0% found this document useful (0 votes)
42 views

Maria DB Server Knowledge Base

MariaDB Server es un sistema de gestión de bases de datos relacionales, de código abierto y de uso general, optimizado para rendimiento y facilidad de uso; tiene sus raíces en MySQL Server y es una alternativa a Postgres, Oracle Database y otras bases de datos relacionales y NoSQL.

Uploaded by

diezv17
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views

Maria DB Server Knowledge Base

MariaDB Server es un sistema de gestión de bases de datos relacionales, de código abierto y de uso general, optimizado para rendimiento y facilidad de uso; tiene sus raíces en MySQL Server y es una alternativa a Postgres, Oracle Database y otras bases de datos relacionales y NoSQL.

Uploaded by

diezv17
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3812

20

From the MariaDB Knowledge Base

22
-1
0
MariaDB
Server
Documentation
Ian Gilfillan (Editor)
Dedicated to bazaar builders everywhere.

Licence
The Knowledge Base content from which this pdf is generated is either licensed under the terms of the GPL, version 2,
originally generated from the server fill_help_tables.sql file, or both of the following two licenses:
The Creative Commons Attribution/ShareAlike 3.0 Unported license (CC-BY-SA).
The Gnu FDL license (GFDL or FDL).
Please see the source page on the Knowledge Base for the definitive licence, and seek proper legal advice if you are in any
doubt about what you are and are not allowed to do with material released under these licenses.
If you find any errors, please see Reporting Documentation Bugs
Generated from the MariaDB Knowledge Base on 2022-10-19

2/3812
Preface
If you’re contemplating whether to devote some time to this book, read this:
MariaDB Server is a general-purpose, open source, relational database management system, optimised for
performance and easy usabiility; it has its roots in MySQL Server, and is an alternative to Postgres, Oracle Database
and other relational and NoSQL databases
This book is the full documentation on MariaDB Server, a “Reference Manual Plus” which includes aspects of a User’s
Guide; it is based on the contents of the MariaDB Knowledge base (https://mariadb.com/kb/ ), an open, community-
edited site contributed to since the inception of MariaDB in 2009
This edition is not specific to any version of MariaDB Server, but includes functionality up to the latest version of
MariaDB at the time of generation
This preface describes the goals, structure and contents of the documentation. Reading it is intended as a helpful step in
understanding how to best use the manual to improve productivity in using MariaDB Server.

This Book’s “Prehistory”


As noted, MariaDB Server has its roots in MySQL Server. It started as a fork of MySQL Server, using the same GPLv2
license. However, although the MySQL Server documentation was always publicly available, it was never released using a
free documentation license. This means that the documentation of MariaDB Server was created from scratch. Or rather, from
the online help texts, which had a compatible open licence that made them usable as a starting point.
The place to which documentation was written was labelled the “Knowledge Base”, by MySQL and MariaDB creator Michael
“Monty” Widenius. The Knowledge Base was – and remains – a community effort. As with many community efforts, there are
core contributors around whom the work is centered. This is where Daniel Bartholomew loaded the online help text, as a first
seed. For roughly the last ten years, the core editor of the MariaDB Knowledge Base has been Ian Gilfillan, working for
MariaDB Foundation and based in South Africa. Hence, his name is on the cover of the book. However, there are a large
number of other contributors, many of whom come from MariaDB Corporation – both as developers of code and as
documentation writers. They are listed on https://mariadb.com/kb/stats/users/ .
With now some 3000 pages in this book, most of the initial holes in the documentation have been filled. There should now be
no reason to do as in the very early days of MariaDB Server – namely look up MariaDB features in the MySQL
documentation. On the contrary, the functionality of the two databases have diverged considerably, so you would be ill
advised not to use this MariaDB Server specific documentation.

The First Edition


The first edition of the MariaDB Server Documentation as a PDF file was released in April 2022. Prior to this, the contents
were accessible as individual Knowledge Base (KB) articles. But already in 2014 – over seven years before – the user base
requested a PDF version, as seen by MariaDB’s Jira entry https://jira.mariadb.org/browse/MDEV-6881 MariaDB
Documentation improvements. There, user Stoykov pointed out that MariaDB documentation already had search capabilities
and a way to mirror the KB in an offline version – but lacked downloadable PDF and EPUB versions,
Fast forward some seven years and a number of upvotes and watchers, we decided to devote resources to it. Creating a
PDF from an HTML file is something Python is good at, and Dorje Gilfillan did all the tweaking necessary to merge the
individual KB pages into one huge HTML file for PDF conversion.

This Book’s Structure


We had to impose a chapter structure on the book which is only indirectly visible from a collection of KB articles on the web.
This means that the work in compiling the PDF isn’t just about merging many KB pages in an order that could be derived from
the hierarchical pointers between the articles. It also involves cleaning up that structure.
As a result, you will see two tables of contents. One is a one-pager overview with just the two top levels of hierarchy. The
other is over 30 pages long. True to the Open Source mantra of “release early, release often”, we believe that the structure
can still be improved upon – but it is a good starting point. We have seven overall chapters, and the structures below them all
make sense at some level.
To get the most out of the book, we recommend you to spend time making yourself familiar with the table of contents. It will
give you an idea of existing functionality. Just browsing it through may give you ideas of commands you didn't know existed.

This Book’s Format


There is currently just one version of the book. It’s delivered in the PDF format, and in the Golden Ratio aspect ratio –
meaning, A4. As we envision it to be read mostly on-screen anyway, we wanted to avoid the additional complexity of also
providing a US Letter format. If we meet demand for further versions, doing US Letter is of course an option; however, given
there are many ways to improve the documentation, we would also like to understand how adding another aspect ratio of the
PDF would benefit the users in practice.
We don’t yet provide the ePub format. Again, if you desire ePub, please educate us as to what added benefits you expect of
ePub on top of PDF.

3/3812
Use Cases For This Book
We expect the main use case for the PDF version of the book to be offline access. Offline may be imposed by a flaky or non-
existent internet, but also by self-imposed abstinence from the many distractions of being online.
We expect that browsing the PDF will enable concentrated time to be spent on learning about MariaDB Server. The search
functionality of PDF browsers helps in finding out about commands and syntax you already know of; browsing through a PDF
– in particular the clickable Table of Contents – will hopefully provide you with an educational overview better than the online
KB does.
We expect downloading the manual into laptops, tablets and phones will make sense. If you have the MariaDB Server
Documentation on your phone, you can turn waiting time into something productive, perhaps even fun.

What we should work on


We have lots of room for improvement. That said, our foremost goal now is to get the book out, to get it used. User feedback
will help us determine the right priority for our already existing ideas for improvements. We will likely get other requests
beyond what we currently have in mind.
In the area of basic usability, an index has been spoken about. Looking up commands through searches or through browsing
the table of contents is ok, but an index also has use cases. Our plan here starts from automatic indexing based on keywords
of the headers of individual articles.
In the area of layout, we are looking at finding icons that make the PDF look more like a book, and less like a web page. We
already solved the first issue, which was to find a clearer visual distinction between links within the PDF and links to the web.
In the area of structure, the length of individual chapters varies a lot. It may make sense to move around chapters in the TOC
tree, to be more balanced. It may be that the reader expects another ordering based on experiences from other databases. It
may even be that we lack entire topics. For instance, we eliminated the Release Notes for unsupported versions of MariaDB,
even though these are still accessible on the KB.
In the area of accessibility, there may be places we should publish the PDF to make it easier to find, download, and use.
The common denominator for all of the above is that we need your feedback on what makes sense for you as a user of
MariaDB Server.

Give Us Feedback
We would like to pick the brains of individual users. At conferences, asking open-ended questions is easy and feels
productive for both parties, when meeting in the corridors between talks. Replicating the same productive discussion on-line
is much harder. It takes effort from both parties. It feels like work.
We are still looking for the best way for you to give us meaningful feedback. Feel free to approach us over Zulip
(https://mariadb.zulipchat.com/ – the Documentation topic). Also email to [email protected] will find its way to us.
When you find individual bugs, please enter them into Jira using the guidelines mentioned in the KB article
https://mariadb.com/kb/en/reporting-documentation-bugs/.

Acknowledgements
Compiling any book requires more effort than expected by the authors, and more than visible to the readers. This book is no
exception. It has been over ten years in the making.
The primary thanks go to Ian Gilfillan, as the overall editor of the book and as the individually most productive author.
Close to Ian, we have Daniel Bartholomew. Daniel even beats Ian when it comes to articles created, and comes second on
articles edited.
Among the community contributors, we want to highlight Federico Razzoli. He has two accounts, totalling 4488, at the time of
writing – making him rank third amongst personal contributors.
When it comes to organisational contributors, the largest one is MariaDB Corporation. With them coding most of the features,
they also stand for the lion’s share of their documentation. As writers, besides Daniel Bartholomew whom we already
mentioned several times, we want to highlight Russell Dyer, Kenneth Dyer, Geoff Montee, and Jacob Moorman.
As the developer of the KB software itself, Bryan Alsdorf deserves special acknowledgement.
A special thanks goes to Michael “Monty” Widenius, the creator of MariaDB. Monty has always understood the importance of
documentation. He is leading by example, with a large number of personal edits. In fact, Monty has the second highest
number of edits amongst developers, after Sergei Golubchik and followed by Sergey Petrunia – all of which have over a
thousand edits.
Amongst the prolific contributors within the MariaDB Corporation Engineering team, the Connectors team stands out, with
Diego Dupin, Georg Richter, and Lawrin Novitzky ranking near the top. However, we have decided not to include Connectors
documentation in this first edition; we are contemplating whether it should be a separate PDF manual.
Other past and present Engineering team members, in decreasing order of number of edits, are David Hill, Dipti Joshi, David
Thompson, Massimiliano Pinto, Kolbe Kegel, Vladislav Vaintroub, Ralf Gebhardt, Markus Mäkelä, Sunanda Menon, the late
Rasmus Johansson, Todd Stoffel, Elena Stepanova, Julien Fritsch, and Alexander Barkov. They all have more than one
hundred edits, which is a lot.
As a true Open Source project, MariaDB Server documentation attracts attention and plentiful contributions also from outside
4/3812
the MariaDB Corporation Documentation and Engineering teams. We want to highlight those with over a hundred edits: Colin
Charles and Stephane Varoqui, both of MariaDB Corporation, and Daniel Black, of MariaDB Foundation.
Amongst community contributors in the over-a-hundred-edits category, we want to mention especially Alena Subotina, with
edits related to the dbforge documentation tool, and Juan Telleria, with edits often related to R Statistical Programming.
Prolific contributors whose contributions are not visible in this English manual are Esper Ecyan (Japanese) and Hector
Stredel (French); Federico Razzoli (Italian) has many edits also in English.
We also want to extend a thank you to the code developers who make work easy for the documentation team through
thoroughly prepared, reusable texts in Jira; in this category, Marko Mäkelä and Oleksandr Byelkin come to mind.
As for the PDF manual, it has been teamwork between Ian and his son Dorje Gilfillan. Ian has done what editors do, Dorje
has coded the Python code that compiles the KB pages into one.
All in all, thank you to everyone who has contributed to this book! We hope compiling it into one volume is of use for you, and
we would love to hear what you think about the end result.
Munich, Germany, October 2022
Kaj Arnö, CEO, MariaDB Foundation

5/3812
Chapter Contents
Chapter 1 Using MariaDB Server 45
1.1 SQL Statements & Structure 45
1.2 Built-in Functions 878
1.3 Clients & Utilities 1236
Chapter 2 MariaDB Administration 1375
2.1 Getting, Installing, and Upgrading MariaDB 1376
2.2 User & Server Security 1833
2.3 Backing Up and Restoring Databases 1893
2.4 Server Monitoring & Logs 1954
2.5 Partitioning Tables 1980
2.6 MariaDB Audit Plugin 1991
2.7 Variables and Modes 1991
2.8 Copying Tables Between Different MariaDB Databases and MariaDB Servers 2115
Chapter 3 High Availability & Performance Tuning 2117
3.1 MariaDB Replication 2117
3.2 MariaDB Galera Cluster 2223
3.3 Optimization and Tuning 2299
Chapter 4 Programming & Customizing MariaDB 2574
4.1 Programmatic & Compound Statements 2574
4.2 Stored Routines 2574
4.3 Triggers & Events 2595
4.4 Views 2604
4.5 User-Defined Functions 2608
Chapter 5 Columns, Storage Engines, and Plugins 2612
5.1 Data Types 2612
5.2 Character Sets and Collations 2692
5.3 Storage Engines 2703
5.4 Plugins 3303
Chapter 6 Training & Tutorials 3445
6.1 Beginner MariaDB Articles 3446
6.2 Basic MariaDB Articles 3488
6.3 Intermediate MariaDB Articles 3503
6.4 Advanced MariaDB Articles 3537
Chapter 7 MariaDB Server Releases 3557
7.1 Release Notes 3558
Chapter 8 The Community 3785
8.1 Bug Tracking 3786
8.2 Contributing & Participating 3799
8.3 Legal Matters 3809

6/3812
Table of Contents
Chapter 1 Using MariaDB Server 45
1.1 SQL Statements & Structure 45
1.1.1 SQL Statements 45
1.1.1.1 Account Management SQL Commands 46
1.1.1.1.1 CREATE USER 47
1.1.1.1.2 ALTER USER 54
1.1.1.1.3 DROP USER 58
1.1.1.1.4 GRANT 60
1.1.1.1.5 RENAME USER 74
1.1.1.1.6 REVOKE 74
1.1.1.1.7 SET PASSWORD 75
1.1.1.1.8 CREATE ROLE 77
1.1.1.1.9 DROP ROLE 78
1.1.1.1.10 SET ROLE 79
1.1.1.1.11 SET DEFAULT ROLE 80
1.1.1.1.12 SHOW GRANTS 81
1.1.1.1.13 SHOW CREATE USER 82
1.1.1.2 Administrative SQL Statements 83
1.1.1.2.1 Table Statements 84
1.1.1.2.1.1 ALTER 85
1.1.1.2.1.1.1 ALTER TABLE 86
1.1.1.2.1.1.2 ALTER DATABASE 99
1.1.1.2.1.1.3 ALTER EVENT 100
1.1.1.2.1.1.4 ALTER FUNCTION 101
1.1.1.2.1.1.5 ALTER LOGFILE GROUP 101
1.1.1.2.1.1.6 ALTER PROCEDURE 101
1.1.1.2.1.1.7 ALTER SEQUENCE 102
1.1.1.2.1.1.8 ALTER SERVER 102
1.1.1.2.1.1.9 ALTER TABLESPACE 103
1.1.1.2.1.1.10 ALTER USER 103
1.1.1.2.1.1.11 ALTER VIEW 103
1.1.1.2.1.2 ANALYZE TABLE 103
1.1.1.2.1.3 CHECK TABLE 104
1.1.1.2.1.4 CHECK VIEW 105
1.1.1.2.1.5 CHECKSUM TABLE 105
1.1.1.2.1.6 CREATE TABLE 107
1.1.1.2.1.7 DELETE 121
1.1.1.2.1.8 DROP TABLE 124
1.1.1.2.1.9 Installing System Tables (mysql_install_db) 126
1.1.1.2.1.10 mysqlcheck 126
1.1.1.2.1.11 OPTIMIZE TABLE 130
1.1.1.2.1.12 RENAME TABLE 132
1.1.1.2.1.13 REPAIR TABLE 133
1.1.1.2.1.14 REPAIR VIEW 134
1.1.1.2.1.15 REPLACE 134
1.1.1.2.1.16 SHOW COLUMNS 137
1.1.1.2.1.17 SHOW CREATE TABLE 139
1.1.1.2.1.18 SHOW INDEX 141
1.1.1.2.1.19 TRUNCATE TABLE 143
1.1.1.2.1.20 UPDATE 145
1.1.1.2.1.21 IGNORE 146
1.1.1.2.1.22 System-Versioned Tables 147
1.1.1.2.2 ANALYZE and EXPLAIN Statements 147
1.1.1.2.2.1 ANALYZE FORMAT=JSON 148
1.1.1.2.2.2 ANALYZE FORMAT=JSON Examples 149
1.1.1.2.2.3 ANALYZE Statement 150
1.1.1.2.2.4 EXPLAIN 152
1.1.1.2.2.5 EXPLAIN ANALYZE 157
1.1.1.2.2.6 EXPLAIN FORMAT=JSON 157
1.1.1.2.2.7 SHOW EXPLAIN 158
1.1.1.2.2.8 Using Buffer UPDATE Algorithm 160
1.1.1.2.3 BACKUP Commands 160
1.1.1.2.3.1 BACKUP STAGE 160
1.1.1.2.3.2 BACKUP LOCK 163
1.1.1.2.3.3 Mariabackup and BACKUP STAGE Commands 164

7/3812
1.1.1.2.3.4 Storage Snapshots and BACKUP STAGE Commands 164
1.1.1.2.4 FLUSH Commands 164
1.1.1.2.4.1 FLUSH 164
1.1.1.2.4.2 FLUSH QUERY CACHE 169
1.1.1.2.4.3 FLUSH TABLES FOR EXPORT 169
1.1.1.2.5 Replication Commands 170
1.1.1.2.5.1 CHANGE MASTER TO 172
1.1.1.2.5.2 START SLAVE 184
1.1.1.2.5.3 STOP SLAVE 185
1.1.1.2.5.4 RESET REPLICA/SLAVE 186
1.1.1.2.5.5 SET GLOBAL SQL_SLAVE_SKIP_COUNTER 187
1.1.1.2.5.6 SHOW RELAYLOG EVENTS 188
1.1.1.2.5.7 SHOW SLAVE STATUS 188
1.1.1.2.5.8 SHOW MASTER STATUS 194
1.1.1.2.5.9 SHOW SLAVE HOSTS 194
1.1.1.2.5.10 RESET MASTER 195
1.1.1.2.6 Plugin SQL Statements 195
1.1.1.2.6.1 SHOW PLUGINS 196
1.1.1.2.6.2 SHOW PLUGINS SONAME 197
1.1.1.2.6.3 INSTALL PLUGIN 197
1.1.1.2.6.4 UNINSTALL PLUGIN 198
1.1.1.2.6.5 INSTALL SONAME 199
1.1.1.2.6.6 UNINSTALL SONAME 200
1.1.1.2.6.7 mysql_plugin 201
1.1.1.2.7 SET Commands 201
1.1.1.2.7.1 SET 202
1.1.1.2.7.2 SET CHARACTER SET 204
1.1.1.2.7.3 SET GLOBAL SQL_SLAVE_SKIP_COUNTER 205
1.1.1.2.7.4 SET NAMES 205
1.1.1.2.7.5 SET PASSWORD 207
1.1.1.2.7.6 SET ROLE 207
1.1.1.2.7.7 SET SQL_LOG_BIN 207
1.1.1.2.7.8 SET STATEMENT 207
1.1.1.2.7.9 SET TRANSACTION 208
1.1.1.2.7.10 SET Variable 210
1.1.1.2.8 SHOW 211
1.1.1.2.8.1 About SHOW 214
1.1.1.2.8.2 Extended Show 215
1.1.1.2.8.3 SHOW AUTHORS 216
1.1.1.2.8.4 SHOW BINARY LOGS 218
1.1.1.2.8.5 SHOW BINLOG EVENTS 219
1.1.1.2.8.6 SHOW CHARACTER SET 219
1.1.1.2.8.7 SHOW CLIENT_STATISTICS 220
1.1.1.2.8.8 SHOW COLLATION 221
1.1.1.2.8.9 SHOW COLUMNS 221
1.1.1.2.8.10 SHOW CONTRIBUTORS 221
1.1.1.2.8.11 SHOW CREATE DATABASE 222
1.1.1.2.8.12 SHOW CREATE EVENT 223
1.1.1.2.8.13 SHOW CREATE FUNCTION 224
1.1.1.2.8.14 SHOW CREATE PACKAGE 224
1.1.1.2.8.15 SHOW CREATE PACKAGE BODY 225
1.1.1.2.8.16 SHOW CREATE PROCEDURE 227
1.1.1.2.8.17 SHOW CREATE SEQUENCE 228
1.1.1.2.8.18 SHOW CREATE TABLE 229
1.1.1.2.8.19 SHOW CREATE TRIGGER 229
1.1.1.2.8.20 SHOW CREATE USER 230
1.1.1.2.8.21 SHOW CREATE VIEW 230
1.1.1.2.8.22 SHOW DATABASES 231
1.1.1.2.8.23 SHOW ENGINE 232
1.1.1.2.8.24 SHOW ENGINE INNODB STATUS 233
1.1.1.2.8.25 SHOW ENGINES 235
1.1.1.2.8.26 SHOW ERRORS 236
1.1.1.2.8.27 SHOW EVENTS 237
1.1.1.2.8.28 SHOW FUNCTION CODE 238
1.1.1.2.8.29 SHOW FUNCTION STATUS 238
1.1.1.2.8.30 SHOW GRANTS 239
1.1.1.2.8.31 SHOW INDEX 239
1.1.1.2.8.32 SHOW INDEX_STATISTICS 239
1.1.1.2.8.34 SHOW LOCALES 240
1.1.1.2.8.35 SHOW BINLOG STATUS 240
1.1.1.2.8.36 SHOW OPEN TABLES 240

8/3812
1.1.1.2.8.37 SHOW PACKAGE BODY STATUS 241
1.1.1.2.8.38 SHOW PACKAGE STATUS 242
1.1.1.2.8.39 SHOW PLUGINS 242
1.1.1.2.8.40 SHOW PLUGINS SONAME 242
1.1.1.2.8.41 SHOW PRIVILEGES 242
1.1.1.2.8.42 SHOW PROCEDURE CODE 244
1.1.1.2.8.43 SHOW PROCEDURE STATUS 245
1.1.1.2.8.44 SHOW PROCESSLIST 246
1.1.1.2.8.45 SHOW PROFILE 247
1.1.1.2.8.46 SHOW PROFILES 249
1.1.1.2.8.47 SHOW QUERY_RESPONSE_TIME 250
1.1.1.2.8.48 SHOW RELAYLOG EVENTS 250
1.1.1.2.8.49 SHOW REPLICA HOSTS 250
1.1.1.2.8.50 SHOW REPLICA STATUS 250
1.1.1.2.8.51 SHOW STATUS 250
1.1.1.2.8.52 SHOW TABLE STATUS 263
1.1.1.2.8.53 SHOW TABLES 265
1.1.1.2.8.54 SHOW TABLE_STATISTICS 266
1.1.1.2.8.55 SHOW TRIGGERS 267
1.1.1.2.8.56 SHOW USER_STATISTICS 269
1.1.1.2.8.57 SHOW VARIABLES 269
1.1.1.2.8.58 SHOW WARNINGS 271
1.1.1.2.8.59 SHOW WSREP_MEMBERSHIP 273
1.1.1.2.8.60 SHOW WSREP_STATUS 273
1.1.1.2.9 System Tables 274
1.1.1.2.9.1 Information Schema 274
1.1.1.2.9.1.1 Information Schema Tables 274
1.1.1.2.9.1.1.1 Information Schema InnoDB Tables 277
1.1.1.2.9.1.1.1.1 Information Schema INNODB_BUFFER_PAGE Table 279
1.1.1.2.9.1.1.1.2 Information Schema INNODB_BUFFER_PAGE_LRU Table 280
1.1.1.2.9.1.1.1.3 Information Schema INNODB_BUFFER_POOL_PAGES Table 282
1.1.1.2.9.1.1.1.4 Information Schema INNODB_BUFFER_POOL_PAGES_BLOB Table 283
1.1.1.2.9.1.1.1.5 Information Schema INNODB_BUFFER_POOL_PAGES_INDEX Table 283
1.1.1.2.9.1.1.1.6 Information Schema INNODB_BUFFER_POOL_STATS Table 283
1.1.1.2.9.1.1.1.7 Information Schema INNODB_CHANGED_PAGES Table 285
1.1.1.2.9.1.1.1.8 Information Schema INNODB_CMP and INNODB_CMP_RESET Tables 285
1.1.1.2.9.1.1.1.9 Information Schema INNODB_CMPMEM and INNODB_CMPMEM_RESET Tables 286
1.1.1.2.9.1.1.1.10 Information Schema INNODB_CMP_PER_INDEX and INNODB_CMP_PER_INDEX_RESET Tables 287
1.1.1.2.9.1.1.1.11 Information Schema INNODB_FT_BEING_DELETED Table 288
1.1.1.2.9.1.1.1.12 Information Schema INNODB_FT_CONFIG Table 288
1.1.1.2.9.1.1.1.13 Information Schema INNODB_FT_DEFAULT_STOPWORD Table 289
1.1.1.2.9.1.1.1.14 Information Schema INNODB_FT_DELETED Table 289
1.1.1.2.9.1.1.1.15 Information Schema INNODB_FT_INDEX_CACHE Table 290
1.1.1.2.9.1.1.1.16 Information Schema INNODB_FT_INDEX_TABLE Table 292
1.1.1.2.9.1.1.1.17 Information Schema INNODB_LOCK_WAITS Table 293
1.1.1.2.9.1.1.1.18 Information Schema INNODB_LOCKS Table 293
1.1.1.2.9.1.1.1.19 Information Schema INNODB_METRICS Table 294
1.1.1.2.9.1.1.1.20 Information Schema INNODB_MUTEXES Table 297
1.1.1.2.9.1.1.1.21 Information Schema INNODB_SYS_COLUMNS Table 298
1.1.1.2.9.1.1.1.22 Information Schema INNODB_SYS_DATAFILES Table 299
1.1.1.2.9.1.1.1.23 Information Schema INNODB_SYS_FIELDS Table 300
1.1.1.2.9.1.1.1.24 Information Schema INNODB_SYS_FOREIGN Table 300
1.1.1.2.9.1.1.1.25 Information Schema INNODB_SYS_FOREIGN_COLS Table 301
1.1.1.2.9.1.1.1.26 Information Schema INNODB_SYS_INDEXES Table 301
1.1.1.2.9.1.1.1.27 Information Schema INNODB_SYS_SEMAPHORE_WAITS Table 302
1.1.1.2.9.1.1.1.28 Information Schema INNODB_SYS_TABLES Table 303
1.1.1.2.9.1.1.1.29 Information Schema INNODB_SYS_TABLESPACES Table 304
1.1.1.2.9.1.1.1.30 Information Schema INNODB_SYS_TABLESTATS Table 305
1.1.1.2.9.1.1.1.31 Information Schema INNODB_SYS_VIRTUAL Table 306
1.1.1.2.9.1.1.1.32 Information Schema INNODB_TABLESPACES_ENCRYPTION Table 306
1.1.1.2.9.1.1.1.33 Information Schema INNODB_TABLESPACES_SCRUBBING Table 307
1.1.1.2.9.1.1.1.34 Information Schema INNODB_TRX Table 308
1.1.1.2.9.1.1.1.35 Information Schema TEMP_TABLES_INFO Table 310
1.1.1.2.9.1.1.2 Information Schema MyRocks Tables 310
1.1.1.2.9.1.1.2.1 Information Schema ROCKSDB_CFSTATS Table 311
1.1.1.2.9.1.1.2.2 Information Schema ROCKSDB_CF_OPTIONS Table 311
1.1.1.2.9.1.1.2.3 Information Schema ROCKSDB_COMPACTION_STATS Table 312
1.1.1.2.9.1.1.2.4 Information Schema ROCKSDB_DBSTATS Table 312
1.1.1.2.9.1.1.2.5 Information Schema ROCKSDB_DDL Table 312
1.1.1.2.9.1.1.2.6 Information Schema ROCKSDB_DEADLOCK Table 312
1.1.1.2.9.1.1.2.7 Information Schema ROCKSDB_GLOBAL_INFO Table 313

9/3812
1.1.1.2.9.1.1.2.8 Information Schema ROCKSDB_INDEX_FILE_MAP Table 313
1.1.1.2.9.1.1.2.9 Information Schema ROCKSDB_LOCKS Table 313
1.1.1.2.9.1.1.2.10 Information Schema ROCKSDB_PERF_CONTEXT Table 314
1.1.1.2.9.1.1.2.11 Information Schema ROCKSDB_PERF_CONTEXT_GLOBAL Table 314
1.1.1.2.9.1.1.2.12 Information Schema ROCKSDB_SST_PROPS Table 314
1.1.1.2.9.1.1.2.13 Information Schema ROCKSDB_TRX Table 315
1.1.1.2.9.1.1.3 ColumnStore Information Schema Tables 315
1.1.1.2.9.1.1.4 Information Schema ALL_PLUGINS Table 318
1.1.1.2.9.1.1.5 Information Schema APPLICABLE_ROLES Table 319
1.1.1.2.9.1.1.6 Information Schema CHARACTER_SETS Table 320
1.1.1.2.9.1.1.7 Information Schema CHECK_CONSTRAINTS Table 320
1.1.1.2.9.1.1.8 Information Schema CLIENT_STATISTICS Table 323
1.1.1.2.9.1.1.9 Information Schema COLLATION_CHARACTER_SET_APPLICABILITY Table 325
1.1.1.2.9.1.1.10 Information Schema COLLATIONS Table 325
1.1.1.2.9.1.1.11 Information Schema COLUMN_PRIVILEGES Table 326
1.1.1.2.9.1.1.12 Information Schema COLUMNS Table 327
1.1.1.2.9.1.1.13 Information Schema DISKS Table 329
1.1.1.2.9.1.1.14 Information Schema ENABLED_ROLES Table 330
1.1.1.2.9.1.1.15 Information Schema ENGINES Table 330
1.1.1.2.9.1.1.16 Information Schema EVENTS Table 333
1.1.1.2.9.1.1.17 Information Schema FEEDBACK Table 333
1.1.1.2.9.1.1.18 Information Schema FILES Table 334
1.1.1.2.9.1.1.19 Information Schema GEOMETRY_COLUMNS Table 334
1.1.1.2.9.1.1.20 Information Schema GLOBAL_STATUS and SESSION_STATUS Tables 336
1.1.1.2.9.1.1.21 Information Schema GLOBAL_VARIABLES and SESSION_VARIABLES Tables 336
1.1.1.2.9.1.1.22 Information Schema INDEX_STATISTICS Table 337
1.1.1.2.9.1.1.23 Information Schema KEY_CACHES Table 337
1.1.1.2.9.1.1.24 Information Schema KEY_COLUMN_USAGE Table 338
1.1.1.2.9.1.1.25 Information Schema KEYWORDS Table 339
1.1.1.2.9.1.1.26 Information Schema LOCALES Table 348
1.1.1.2.9.1.1.27 Information Schema METADATA_LOCK_INFO Table 349
1.1.1.2.9.1.1.28 Information Schema MROONGA_STATS Table 351
1.1.1.2.9.1.1.29 Information Schema OPTIMIZER_TRACE Table 351
1.1.1.2.9.1.1.30 Information Schema PARAMETERS Table 352
1.1.1.2.9.1.1.31 Information Schema PARTITIONS Table 353
1.1.1.2.9.1.1.32 Information Schema PLUGINS Table 354
1.1.1.2.9.1.1.33 Information Schema PROCESSLIST Table 357
1.1.1.2.9.1.1.34 Information Schema PROFILING Table 358
1.1.1.2.9.1.1.35 Information Schema QUERY_CACHE_INFO Table 359
1.1.1.2.9.1.1.36 Information Schema QUERY_RESPONSE_TIME Table 360
1.1.1.2.9.1.1.37 Information Schema REFERENTIAL_CONSTRAINTS Table 361
1.1.1.2.9.1.1.38 Information Schema ROUTINES Table 361
1.1.1.2.9.1.1.39 Information Schema SCHEMA_PRIVILEGES Table 362
1.1.1.2.9.1.1.40 Information Schema SCHEMATA Table 363
1.1.1.2.9.1.1.41 Information Schema SPATIAL_REF_SYS Table 364
1.1.1.2.9.1.1.42 Information Schema SPIDER_ALLOC_MEM Table 364
1.1.1.2.9.1.1.43 Information Schema SPIDER_WRAPPER_PROTOCOLS Table 364
1.1.1.2.9.1.1.44 Information Schema SQL_FUNCTIONS Table 365
1.1.1.2.9.1.1.45 Information Schema STATISTICS Table 368
1.1.1.2.9.1.1.46 Information Schema SYSTEM_VARIABLES Table 369
1.1.1.2.9.1.1.47 Information Schema TABLE_CONSTRAINTS Table 370
1.1.1.2.9.1.1.48 Information Schema TABLE_PRIVILEGES Table 370
1.1.1.2.9.1.1.49 Information Schema TABLE_STATISTICS Table 370
1.1.1.2.9.1.1.50 Information Schema TABLES Table 371
1.1.1.2.9.1.1.51 Information Schema TABLESPACES Table 373
1.1.1.2.9.1.1.52 Information Schema THREAD_POOL_GROUPS Table 374
1.1.1.2.9.1.1.53 Information Schema THREAD_POOL_QUEUES Table 374
1.1.1.2.9.1.1.54 Information Schema THREAD_POOL_STATS Table 374
1.1.1.2.9.1.1.55 Information Schema THREAD_POOL_WAITS Table 375
1.1.1.2.9.1.1.56 Information Schema TRIGGERS Table 375
1.1.1.2.9.1.1.57 Information Schema USER_PRIVILEGES Table 376
1.1.1.2.9.1.1.58 Information Schema USER_STATISTICS Table 376
1.1.1.2.9.1.1.59 Information Schema USER_VARIABLES Table 378
1.1.1.2.9.1.1.60 Information Schema VIEWS Table 378
1.1.1.2.9.1.1.61 Information Schema WSREP_MEMBERSHIP Table 379
1.1.1.2.9.1.1.62 Information Schema WSREP_STATUS Table 380
1.1.1.2.9.1.2 Extended SHOW 380
1.1.1.2.9.1.3 TIME_MS column in INFORMATION_SCHEMA.PROCESSLIST 380
1.1.1.2.9.2 Performance Schema 380
1.1.1.2.9.2.1 Performance Schema Tables 381
1.1.1.2.9.2.1.1 List of Performance Schema Tables 385

10/3812
1.1.1.2.9.2.1.2 Performance Schema accounts Table 387
1.1.1.2.9.2.1.3 Performance Schema cond_instances Table 387
1.1.1.2.9.2.1.4 Performance Schema events_stages_current Table 388
1.1.1.2.9.2.1.5 Performance Schema events_stages_history Table 388
1.1.1.2.9.2.1.6 Performance Schema events_stages_history_long Table 389
1.1.1.2.9.2.1.7 Performance Schema events_stages_summary_by_account_by_event_name Table 389
1.1.1.2.9.2.1.8 Performance Schema events_stages_summary_by_host_by_event_name Table 390
1.1.1.2.9.2.1.9 Performance Schema events_stages_summary_by_thread_by_event_name Table 391
1.1.1.2.9.2.1.10 Performance Schema events_stages_summary_by_user_by_event_name Table 392
1.1.1.2.9.2.1.11 Performance Schema events_stages_summary_global_by_event_name Table 393
1.1.1.2.9.2.1.12 Performance Schema events_statements_current Table 394
1.1.1.2.9.2.1.13 Performance Schema events_statements_history Table 395
1.1.1.2.9.2.1.14 Performance Schema events_statements_history_long Table 396
1.1.1.2.9.2.1.15 Performance Schema events_statements_summary_by_account_by_event_name Table 398
1.1.1.2.9.2.1.16 Performance Schema events_statements_summary_by_digest Table 399
1.1.1.2.9.2.1.17 Performance Schema events_statements_summary_by_host_by_event_name Table 400
1.1.1.2.9.2.1.18 Performance Schema events_statements_summary_by_program Table 402
1.1.1.2.9.2.1.19 Performance Schema events_statements_summary_by_thread_by_event_name Table 404
1.1.1.2.9.2.1.20 Performance Schema events_statements_summary_by_user_by_event_name Table 405
1.1.1.2.9.2.1.21 Performance Schema events_statements_summary_global_by_event_name Table 407
1.1.1.2.9.2.1.22 Performance Schema events_transactions_current Table 409
1.1.1.2.9.2.1.23 Performance Schema events_transactions_history Table 410
1.1.1.2.9.2.1.24 Performance Schema events_transactions_history_long Table 412
1.1.1.2.9.2.1.25 Performance Schema events_transactions_summary_by_account_by_event_name Table 413
1.1.1.2.9.2.1.26 Performance Schema events_transactions_summary_by_host_by_event_name Table 414
1.1.1.2.9.2.1.27 Performance Schema events_transactions_summary_by_thread_by_event_name Table 415
1.1.1.2.9.2.1.28 Performance Schema events_transactions_summary_by_user_by_event_name Table 415
1.1.1.2.9.2.1.29 Performance Schema events_transactions_summary_global_by_event_name Table 416
1.1.1.2.9.2.1.30 Performance Schema events_waits_current Table 416
1.1.1.2.9.2.1.31 Performance Schema events_waits_history Table 417
1.1.1.2.9.2.1.32 Performance Schema events_waits_history_long Table 418
1.1.1.2.9.2.1.33 Performance Schema events_waits_summary_by_account_by_event_name Table 419
1.1.1.2.9.2.1.34 Performance Schema events_waits_summary_by_host_by_event_name Table 420
1.1.1.2.9.2.1.35 Performance Schema events_waits_summary_by_instance Table 421
1.1.1.2.9.2.1.36 Performance Schema events_waits_summary_by_thread_by_event_name Table 422
1.1.1.2.9.2.1.37 Performance Schema events_waits_summary_by_user_by_event_name Table 423
1.1.1.2.9.2.1.38 Performance Schema events_waits_summary_global_by_event_name Table 424
1.1.1.2.9.2.1.39 Performance Schema file_instances Table 425
1.1.1.2.9.2.1.40 Performance Schema file_summary_by_event_name Table 426
1.1.1.2.9.2.1.41 Performance Schema file_summary_by_instance Table 427
1.1.1.2.9.2.1.42 Performance Schema global_status Table 429
1.1.1.2.9.2.1.43 Performance Schema hosts Table 430
1.1.1.2.9.2.1.44 Performance Schema host_cache Table 430
1.1.1.2.9.2.1.45 Performance Schema memory_summary_by_account_by_event_name Table 431
1.1.1.2.9.2.1.46 Performance Schema memory_summary_by_host_by_event_name Table 432
1.1.1.2.9.2.1.47 Performance Schema memory_summary_by_thread_by_event_name Table 433
1.1.1.2.9.2.1.48 Performance Schema memory_summary_by_user_by_event_name Table 434
1.1.1.2.9.2.1.49 Performance Schema memory_summary_global_by_event_name Table 434
1.1.1.2.9.2.1.50 Performance Schema metadata_locks Table 435
1.1.1.2.9.2.1.51 Performance Schema mutex_instances Table 436
1.1.1.2.9.2.1.52 Performance Schema objects_summary_global_by_type Table 437
1.1.1.2.9.2.1.53 Performance Schema performance_timers Table 437
1.1.1.2.9.2.1.54 Performance Schema prepared_statements_instances Table 438
1.1.1.2.9.2.1.55 Performance Schema replication_applier_configuration Table 440
1.1.1.2.9.2.1.56 Performance Schema replication_applier_status Table 440
1.1.1.2.9.2.1.57 Performance Schema replication_applier_status_by_coordinator Table 440
1.1.1.2.9.2.1.58 Performance Schema replication_applier_status_by_worker Table 441
1.1.1.2.9.2.1.59 Performance Schema replication_connection_configuration Table 441
1.1.1.2.9.2.1.60 Performance Schema rwlock_instances Table 442
1.1.1.2.9.2.1.61 Performance Schema session_account_connect_attrs Table 442
1.1.1.2.9.2.1.62 Performance Schema session_connect_attrs Table 443
1.1.1.2.9.2.1.63 Performance Schema session_status Table 444
1.1.1.2.9.2.1.64 Performance Schema setup_actors Table 444
1.1.1.2.9.2.1.65 Performance Schema setup_consumers Table 444
1.1.1.2.9.2.1.66 Performance Schema setup_instruments Table 445
1.1.1.2.9.2.1.67 Performance Schema setup_objects Table 457
1.1.1.2.9.2.1.68 Performance Schema setup_timers Table 458
1.1.1.2.9.2.1.69 Performance Schema socket_instances Table 458
1.1.1.2.9.2.1.70 Performance Schema socket_summary_by_event_name Table 459
1.1.1.2.9.2.1.71 Performance Schema socket_summary_by_instance Table 460
1.1.1.2.9.2.1.72 Performance Schema status_by_account Table 461

11/3812
1.1.1.2.9.2.1.73 Performance Schema status_by_host Table 461
1.1.1.2.9.2.1.74 Performance Schema status_by_thread Table 462
1.1.1.2.9.2.1.75 Performance Schema status_by_user Table 462
1.1.1.2.9.2.1.76 Performance Schema table_handles Table 462
1.1.1.2.9.2.1.77 Performance Schema table_io_waits_summary_by_index_usage Table 463
1.1.1.2.9.2.1.78 Performance Schema table_io_waits_summary_by_table Table 464
1.1.1.2.9.2.1.79 Performance Schema table_lock_waits_summary_by_table Table 465
1.1.1.2.9.2.1.80 Performance Schema threads Table 467
1.1.1.2.9.2.1.81 Performance Schema user_variables_by_thread Table 468
1.1.1.2.9.2.1.82 Performance Schema users Table 469
1.1.1.2.9.2.2 Performance Schema Overview 469
1.1.1.2.9.2.3 Performance Schema Status Variables 471
1.1.1.2.9.2.4 Performance Schema System Variables 475
1.1.1.2.9.2.5 Performance Schema Digests 483
1.1.1.2.9.2.6 PERFORMANCE_SCHEMA Storage Engine 484
1.1.1.2.9.3 The mysql Database Tables 484
1.1.1.2.9.3.1 mysql.column_stats Table 485
1.1.1.2.9.3.2 mysql.columns_priv Table 486
1.1.1.2.9.3.3 mysql.db Table 487
1.1.1.2.9.3.4 mysql.event Table 488
1.1.1.2.9.3.5 mysql.func Table 490
1.1.1.2.9.3.6 mysql.general_log Table 490
1.1.1.2.9.3.7 mysql.global_priv Table 491
1.1.1.2.9.3.8 mysql.gtid_slave_pos Table 493
1.1.1.2.9.3.9 mysql.help_category Table 494
1.1.1.2.9.3.10 mysql.help_keyword Table 495
1.1.1.2.9.3.11 mysql.help_relation Table 496
1.1.1.2.9.3.12 mysql.help_topic Table 496
1.1.1.2.9.3.13 mysql.index_stats Table 497
1.1.1.2.9.3.14 mysql.innodb_index_stats 498
1.1.1.2.9.3.15 mysql.innodb_table_stats 499
1.1.1.2.9.3.16 mysql.password_reuse_check_history Table 500
1.1.1.2.9.3.17 mysql.plugin Table 500
1.1.1.2.9.3.18 mysql.proc Table 501
1.1.1.2.9.3.19 mysql.procs_priv Table 503
1.1.1.2.9.3.20 mysql.roles_mapping Table 503
1.1.1.2.9.3.21 mysql.servers Table 504
1.1.1.2.9.3.22 mysql.slow_log Table 504
1.1.1.2.9.3.23 mysql.tables_priv Table 505
1.1.1.2.9.3.24 mysql.table_stats Table 506
1.1.1.2.9.3.25 mysql.time_zone Table 506
1.1.1.2.9.3.26 mysql.time_zone_leap_second Table 507
1.1.1.2.9.3.27 mysql.time_zone_name Table 508
1.1.1.2.9.3.28 mysql.time_zone_transition Table 508
1.1.1.2.9.3.29 mysql.time_zone_transition_type Table 509
1.1.1.2.9.3.30 mysql.transaction_registry Table 510
1.1.1.2.9.3.31 mysql.user Table 510
1.1.1.2.9.3.32 Spider mysql Database Tables 514
1.1.1.2.9.3.32.1 mysql.spider_link_failed_log Table 514
1.1.1.2.9.3.32.2 mysql.spider_link_mon_servers Table 515
1.1.1.2.9.3.32.3 mysql.spider_tables Table 515
1.1.1.2.9.3.32.4 mysql.spider_table_crd Table 516
1.1.1.2.9.3.32.5 mysql.spider_table_position_for_recovery Table 517
1.1.1.2.9.3.32.6 mysql.spider_table_sts Table 517
1.1.1.2.9.3.32.7 mysql.spider_xa Table 517
1.1.1.2.9.3.32.8 mysql.spider_xa_failed_log Table 518
1.1.1.2.9.3.32.9 mysql.spider_xa_member Table 519
1.1.1.2.9.4 Sys Schema 519
1.1.1.2.9.4.1 Sys Schema sys_config Table 520
1.1.1.2.9.4.2 Sys Schema Stored Functions 520
1.1.1.2.9.4.2.1 extract_schema_from_file_name 521
1.1.1.2.9.4.2.2 extract_table_from_file_name 522
1.1.1.2.9.4.2.3 format_bytes 522
1.1.1.2.9.4.2.4 format_path 523
1.1.1.2.9.4.2.5 format_statement 524
1.1.1.2.9.4.2.6 format_time 524
1.1.1.2.9.4.2.7 list_add 525
1.1.1.2.9.4.2.8 list_drop 526
1.1.1.2.9.4.2.9 ps_is_account_enabled 526
1.1.1.2.9.4.2.10 ps_is_consumer_enabled 526
1.1.1.2.9.4.2.11 ps_is_instrument_default_enabled 527

12/3812
1.1.1.2.9.4.2.12 ps_is_instrument_default_timed 528
1.1.1.2.9.4.2.13 ps_is_thread_instrumented 529
1.1.1.2.9.4.2.14 ps_thread_account 529
1.1.1.2.9.4.2.15 ps_thread_id 530
1.1.1.2.9.4.2.16 ps_thread_stack 531
1.1.1.2.9.4.2.17 ps_thread_trx_info 531
1.1.1.2.9.4.2.18 quote_identifier 532
1.1.1.2.9.4.2.19 sys_get_config 532
1.1.1.2.9.4.2.20 version_major 533
1.1.1.2.9.4.2.21 version_minor 533
1.1.1.2.9.4.2.22 version_patch 534
1.1.1.2.9.4.3 Sys Schema Stored Procedures 534
1.1.1.2.9.4.3.1 create_synonym_db 535
1.1.1.2.9.4.3.2 statement_performance_analyzer 536
1.1.1.2.9.4.3.3 table_exists 536
1.1.1.2.9.5 mariadb_schema 537
1.1.1.2.9.6 Writing Logs Into Tables 538
1.1.1.2.10 BINLOG 539
1.1.1.2.11 PURGE BINARY LOGS 539
1.1.1.2.12 CACHE INDEX 540
1.1.1.2.13 DESCRIBE 541
1.1.1.2.14 EXECUTE Statement 541
1.1.1.2.15 HELP Command 542
1.1.1.2.16 KILL [CONNECTION | QUERY] 543
1.1.1.2.17 LOAD INDEX 544
1.1.1.2.18 RESET 544
1.1.1.2.19 SHUTDOWN 545
1.1.1.2.20 USE 546
1.1.1.3 Data Definition 546
1.1.1.3.1 CREATE 547
1.1.1.3.1.1 CREATE DATABASE 548
1.1.1.3.1.2 CREATE EVENT 550
1.1.1.3.1.3 CREATE FUNCTION 553
1.1.1.3.1.4 CREATE FUNCTION UDF 557
1.1.1.3.1.5 CREATE INDEX 560
1.1.1.3.1.6 CREATE LOGFILE GROUP 562
1.1.1.3.1.7 CREATE PACKAGE 563
1.1.1.3.1.8 CREATE PACKAGE BODY 565
1.1.1.3.1.9 CREATE PROCEDURE 568
1.1.1.3.1.10 CREATE ROLE 571
1.1.1.3.1.11 CREATE SEQUENCE 571
1.1.1.3.1.12 CREATE SERVER 571
1.1.1.3.1.13 CREATE TABLE 573
1.1.1.3.1.14 CREATE TABLESPACE 573
1.1.1.3.1.15 CREATE TRIGGER 573
1.1.1.3.1.16 CREATE USER 575
1.1.1.3.1.17 CREATE VIEW 575
1.1.1.3.1.18 Silent Column Changes 579
1.1.1.3.1.19 Generated (Virtual and Persistent/Stored) Columns 580
1.1.1.3.1.20 Invisible Columns 587
1.1.1.3.2 ALTER 589
1.1.1.3.2.1 ALTER TABLE 589
1.1.1.3.2.2 ALTER DATABASE 589
1.1.1.3.2.3 ALTER EVENT 589
1.1.1.3.2.4 ALTER FUNCTION 589
1.1.1.3.2.5 ALTER LOGFILE GROUP 589
1.1.1.3.2.6 ALTER PROCEDURE 589
1.1.1.3.2.7 ALTER SEQUENCE 589
1.1.1.3.2.8 ALTER SERVER 589
1.1.1.3.2.9 ALTER TABLESPACE 589
1.1.1.3.2.10 ALTER USER 589
1.1.1.3.2.11 ALTER VIEW 589
1.1.1.3.3 DROP 589
1.1.1.3.3.1 DROP DATABASE 590
1.1.1.3.3.2 DROP EVENT 591
1.1.1.3.3.3 DROP FUNCTION 592
1.1.1.3.3.4 DROP FUNCTION UDF 593
1.1.1.3.3.5 DROP INDEX 594
1.1.1.3.3.6 DROP LOGFILE GROUP 595
1.1.1.3.3.7 DROP PACKAGE 595
1.1.1.3.3.8 DROP PACKAGE BODY 595

13/3812
1.1.1.3.3.9 DROP PROCEDURE 596
1.1.1.3.3.10 DROP ROLE 597
1.1.1.3.3.11 DROP SEQUENCE 597
1.1.1.3.3.12 DROP SERVER 597
1.1.1.3.3.13 DROP TABLE 598
1.1.1.3.3.14 DROP TABLESPACE 598
1.1.1.3.3.15 DROP TRIGGER 598
1.1.1.3.3.16 DROP USER 599
1.1.1.3.3.17 DROP VIEW 599
1.1.1.3.4 Atomic DDL 600
1.1.1.3.5 CONSTRAINT 602
1.1.1.3.6 MERGE 604
1.1.1.3.7 RENAME TABLE 604
1.1.1.3.8 TRUNCATE TABLE 604
1.1.1.4 Data Manipulation 605
1.1.1.4.1 Selecting Data 605
1.1.1.4.1.1 SELECT 607
1.1.1.4.1.2 Joins & Subqueries 609
1.1.1.4.1.2.1 Joins 610
1.1.1.4.1.2.1.1 Joining Tables with JOIN Clauses 610
1.1.1.4.1.2.1.2 More Advanced Joins 610
1.1.1.4.1.2.1.3 JOIN Syntax 613
1.1.1.4.1.2.1.4 Comma vs JOIN 615
1.1.1.4.1.2.2 Subqueries 615
1.1.1.4.1.2.2.1 Scalar Subqueries 616
1.1.1.4.1.2.2.2 Row Subqueries 617
1.1.1.4.1.2.2.3 Subqueries and ALL 617
1.1.1.4.1.2.2.4 Subqueries and ANY 618
1.1.1.4.1.2.2.5 Subqueries and EXISTS 619
1.1.1.4.1.2.2.6 Subqueries in a FROM Clause 620
1.1.1.4.1.2.2.7 Subquery Optimizations 621
1.1.1.4.1.2.2.7.1 Subquery Optimizations Map 621
1.1.1.4.1.2.2.7.2 Semi-join Subquery Optimizations 621
1.1.1.4.1.2.2.7.3 Table Pullout Optimization 621
1.1.1.4.1.2.2.7.4 Non-semi-join Subquery Optimizations 621
1.1.1.4.1.2.2.7.5 Subquery Cache 621
1.1.1.4.1.2.2.7.6 Condition Pushdown Into IN subqueries 621
1.1.1.4.1.2.2.7.7 Conversion of Big IN Predicates Into Subqueries 621
1.1.1.4.1.2.2.7.8 EXISTS-to-IN Optimization 621
1.1.1.4.1.2.2.7.9 Optimizing GROUP BY and DISTINCE Clauses in Subqueries 621
1.1.1.4.1.2.2.8 Subqueries and JOINs 621
1.1.1.4.1.2.2.9 Subquery Limitations 623
1.1.1.4.1.2.3 UNION 624
1.1.1.4.1.2.4 EXCEPT 628
1.1.1.4.1.2.5 INTERSECT 631
1.1.1.4.1.2.6 Precedence Control in Table Operations 634
1.1.1.4.1.2.7 MINUS 635
1.1.1.4.1.3 LIMIT 635
1.1.1.4.1.4 ORDER BY 638
1.1.1.4.1.5 GROUP BY 640
1.1.1.4.1.6 Common Table Expressions 642
1.1.1.4.1.6.1 WITH 642
1.1.1.4.1.6.2 Non-Recursive Common Table Expressions Overview 644
1.1.1.4.1.6.3 Recursive Common Table Expressions Overview 646
1.1.1.4.1.7 SELECT WITH ROLLUP 652
1.1.1.4.1.8 SELECT INTO OUTFILE 654
1.1.1.4.1.9 SELECT INTO DUMPFILE 655
1.1.1.4.1.10 FOR UPDATE 655
1.1.1.4.1.11 LOCK IN SHARE MODE 656
1.1.1.4.1.12 Optimizer Hints 656
1.1.1.4.1.13 PROCEDURE 657
1.1.1.4.1.14 HANDLER 657
1.1.1.4.1.15 DUAL 657
1.1.1.4.1.16 SELECT ... OFFSET ... FETCH 657
1.1.1.4.2 Inserting & Loading Data 659
1.1.1.4.2.1 INSERT 659
1.1.1.4.2.2 INSERT DELAYED 662
1.1.1.4.2.3 INSERT SELECT 663
1.1.1.4.2.4 LOAD Data into Tables or Index 664
1.1.1.4.2.4.1 LOAD DATA INFILE 665
1.1.1.4.2.4.2 LOAD INDEX 667

14/3812
1.1.1.4.2.4.3 LOAD XML 668
1.1.1.4.2.4.4 LOAD_FILE 669
1.1.1.4.2.5 Concurrent Inserts 669
1.1.1.4.2.6 HIGH_PRIORITY and LOW_PRIORITY 670
1.1.1.4.2.7 IGNORE 670
1.1.1.4.2.8 INSERT - Default & Duplicate Values 670
1.1.1.4.2.9 INSERT IGNORE 671
1.1.1.4.2.10 INSERT ON DUPLICATE KEY UPDATE 672
1.1.1.4.2.11 INSERT...RETURNING 675
1.1.1.4.3 Changing & Deleting Data 677
1.1.1.4.3.1 DELETE 677
1.1.1.4.3.2 HIGH_PRIORITY and LOW_PRIORITY 677
1.1.1.4.3.3 IGNORE 677
1.1.1.4.3.4 REPLACE 677
1.1.1.4.3.5 REPLACE...RETURNING 677
1.1.1.4.3.6 TRUNCATE TABLE 679
1.1.1.4.3.7 UPDATE 679
1.1.1.5 Prepared Statements 679
1.1.1.5.1 PREPARE Statement 680
1.1.1.5.2 Out Parameters in PREPARE 683
1.1.1.5.3 EXECUTE STATEMENT 683
1.1.1.5.4 DEALLOCATE / DROP PREPARE 683
1.1.1.5.5 EXECUTE IMMEDIATE 683
1.1.1.6 Programmatic & Compound Statements 686
1.1.1.6.1 Using Compound Statements Outside of Stored Programs 687
1.1.1.6.2 BEGIN END 688
1.1.1.6.3 CASE Statement 689
1.1.1.6.4 DECLARE CONDITION 690
1.1.1.6.5 DECLARE HANDLER 690
1.1.1.6.6 DECLARE Variable 692
1.1.1.6.7 FOR 693
1.1.1.6.8 GOTO 695
1.1.1.6.9 IF 696
1.1.1.6.10 ITERATE 696
1.1.1.6.11 Labels 697
1.1.1.6.12 LEAVE 697
1.1.1.6.13 LOOP 698
1.1.1.6.14 REPEAT LOOP 699
1.1.1.6.15 RESIGNAL 700
1.1.1.6.16 RETURN 701
1.1.1.6.17 SELECT INTO 702
1.1.1.6.18 SET Variable 702
1.1.1.6.19 SIGNAL 703
1.1.1.6.20 WHILE 705
1.1.1.6.21 Cursors 705
1.1.1.6.21.1 Cursor Overview 705
1.1.1.6.21.2 DECLARE CURSOR 708
1.1.1.6.21.3 OPEN 709
1.1.1.6.21.4 FETCH 710
1.1.1.6.21.5 CLOSE 710
1.1.1.7 Stored Routine Statements 711
1.1.1.7.1 CALL 711
1.1.1.7.2 DO 711
1.1.1.8 Table Statements 712
1.1.1.9 Transactions 712
1.1.1.9.1 START TRANSACTION 712
1.1.1.9.2 COMMIT 714
1.1.1.9.3 ROLLBACK 715
1.1.1.9.4 SET TRANSACTION 715
1.1.1.9.5 LOCK TABLES 715
1.1.1.9.6 SAVEPOINT 717
1.1.1.9.7 Metadata Locking 717
1.1.1.9.8 SQL statements That Cause an Implicit Commit 718
1.1.1.9.9 Transaction Timeouts 720
1.1.1.9.10 UNLOCK TABLES 720
1.1.1.9.11 WAIT and NOWAIT 722
1.1.1.9.12 XA Transactions 722
1.1.1.10 HELP Command 725
1.1.1.11 Comment Syntax 725
1.1.1.12 Built-in Functions 726
1.1.2 SQL Language Structure 726

15/3812
1.1.2.1 Identifier Names 727
1.1.2.2 Identifier Case-sensitivity 730
1.1.2.3 Binary Literals 730
1.1.2.4 Boolean Literals 731
1.1.2.5 Date and Time Literals 731
1.1.2.6 Hexadecimal Literals 733
1.1.2.7 Identifier Qualifiers 735
1.1.2.8 Identifier to File Name Mapping 735
1.1.2.9 MariaDB Error Codes 736
1.1.2.10 Numeric Literals 780
1.1.2.11 Reserved Words 780
1.1.2.12 SQLSTATE 787
1.1.2.13 String Literals 787
1.1.2.14 Table Value Constructors 788
1.1.2.15 User-Defined Variables 789
1.1.3 Geographic & Geometric Features 791
1.1.3.1 GIS Resources 792
1.1.3.2 GIS features in 5.3.3 792
1.1.3.3 Geometry Types 793
1.1.3.4 Geometry Hierarchy 795
1.1.3.5 Geometry Constructors 795
1.1.3.6 Geometry Properties 795
1.1.3.7 Geometry Relations 795
1.1.3.8 LineString Properties 795
1.1.3.9 MBR (Minimum Bounding Rectangle) 795
1.1.3.10 Point Properties 795
1.1.3.11 Polygon Properties 795
1.1.3.12 WKB 795
1.1.3.13 WKT 795
1.1.3.14 MySQL/MariaDB Spatial Support Matrix 795
1.1.3.15 SPATIAL INDEX 799
1.1.3.16 GeoJSON 800
1.1.3.16.1 ST_AsGeoJSON 800
1.1.3.16.2 ST_GeomFromGeoJSON 801
1.1.4 NoSQL 801
1.1.4.1 CONNECT 802
1.1.4.2 HANDLER 802
1.1.4.2.1 HANDLER Commands 803
1.1.4.2.2 HANDLER for MEMORY Tables 804
1.1.4.3 HandlerSocket 805
1.1.4.3.1 HandlerSocket Installation 805
1.1.4.3.2 HandlerSocket Configuration Options 806
1.1.4.3.3 HandlerSocket Client Libraries 809
1.1.4.3.4 Testing HandlerSocket in a Source Distribution 809
1.1.4.3.5 HandlerSocket External Resources 810
1.1.4.4 Dynamic Columns 810
1.1.4.5 Dynamic Columns from MariaDB 10 815
1.1.4.6 Dynamic Column API 817
1.1.4.7 Dynamic Columns from MariaDB 10 822
1.1.4.8 JSON Functions 824
1.1.4.9 LOAD_FILE 824
1.1.5 Operators 824
1.1.5.1 Arithmetic Operators 827
1.1.5.1.1 Addition Operator (+) 827
1.1.5.1.2 DIV 827
1.1.5.1.3 Division Operator (/) 828
1.1.5.1.4 MOD 829
1.1.5.1.5 Modulo Operator (%) 829
1.1.5.1.6 Multiplication Operator (*) 829
1.1.5.1.7 Subtraction Operator (-) 830
1.1.5.2 Assignment Operators 831
1.1.5.2.1 Assignment Operator (:=) 831
1.1.5.2.2 Assignment Operator (=) 832
1.1.5.3 Bit Functions and Operators 832
1.1.5.4 Comparison Operators 832
1.1.5.4.1 Not Equal Operator: != 833
1.1.5.4.2 < 834
1.1.5.4.3 <= 835
1.1.5.4.4 <=> 835
1.1.5.4.5 = 836
1.1.5.4.6 > 837

16/3812
1.1.5.4.7 >= 838
1.1.5.4.8 BETWEEN AND 839
1.1.5.4.9 COALESCE 840
1.1.5.4.10 GREATEST 841
1.1.5.4.11 IN 842
1.1.5.4.12 INTERVAL 843
1.1.5.4.13 IS 844
1.1.5.4.14 IS NOT 844
1.1.5.4.15 IS NOT NULL 845
1.1.5.4.16 IS NULL 845
1.1.5.4.17 ISNULL 846
1.1.5.4.18 LEAST 846
1.1.5.4.19 NOT BETWEEN 847
1.1.5.4.20 NOT IN 847
1.1.5.5 Logical Operators 848
1.1.5.5.1 ! 849
1.1.5.5.2 && 849
1.1.5.5.3 XOR 850
1.1.5.5.4 || 851
1.1.5.6 Operator Precedence 852
1.1.6 Sequences 853
1.1.6.1 Sequence Overview 853
1.1.6.2 CREATE SEQUENCE 857
1.1.6.3 SHOW CREATE SEQUENCE 859
1.1.6.4 ALTER SEQUENCE 859
1.1.6.5 DROP SEQUENCE 861
1.1.6.6 SEQUENCE Functions 862
1.1.6.6.1 LASTVAL 862
1.1.6.6.2 NEXT VALUE for sequence_name 862
1.1.6.6.3 NEXTVAL 863
1.1.6.6.4 PREVIOUS VALUE FOR sequence_name 863
1.1.6.6.5 SETVAL 865
1.1.6.7 SHOW TABLES 867
1.1.7 Temporal Tables 867
1.1.7.1 System-Versioned Tables 867
1.1.7.2 Application-Time Periods 874
1.1.7.3 Bitemporal Tables 878
1.2 Built-in Functions 878
1.2.1 Function and Operator Reference 879
1.2.2 String Functions 889
1.2.2.1 Regular Expressions Functions 892
1.2.2.1.1 Regular Expressions Overview 893
1.2.2.1.2 Perl Compatible Regular Expressions (PCRE) Documentation 902
1.2.2.1.3 NOT REGEXP 914
1.2.2.1.4 REGEXP 914
1.2.2.1.5 REGEXP_INSTR 915
1.2.2.1.6 REGEXP_REPLACE 916
1.2.2.1.7 REGEXP_SUBSTR 917
1.2.2.1.8 RLIKE 918
1.2.2.2 Dynamic Columns Functions 918
1.2.2.2.1 COLUMN_ADD 918
1.2.2.2.2 COLUMN_CHECK 919
1.2.2.2.3 COLUMN_CREATE 919
1.2.2.2.4 COLUMN_DELETE 919
1.2.2.2.5 COLUMN_EXISTS 920
1.2.2.2.6 COLUMN_GET 920
1.2.2.2.7 COLUMN_JSON 920
1.2.2.2.8 COLUMN_LIST 921
1.2.2.3 ASCII 921
1.2.2.4 BIN 922
1.2.2.5 BINARY Operator 922
1.2.2.6 BIT_LENGTH 923
1.2.2.7 CAST 924
1.2.2.8 CHAR Function 925
1.2.2.9 CHAR_LENGTH 926
1.2.2.10 CHARACTER_LENGTH 927
1.2.2.11 CHR 927
1.2.2.12 CONCAT 928
1.2.2.13 CONCAT_WS 929
1.2.2.14 CONVERT 930
1.2.2.15 ELT 931

17/3812
1.2.2.16 EXPORT_SET 932
1.2.2.17 EXTRACTVALUE 932
1.2.2.18 FIELD 934
1.2.2.19 FIND_IN_SET 935
1.2.2.20 FORMAT 936
1.2.2.21 FROM_BASE64 936
1.2.2.22 HEX 937
1.2.2.23 INSTR 938
1.2.2.24 LCASE 938
1.2.2.25 LEFT 938
1.2.2.26 INSERT Function 939
1.2.2.27 LENGTH 939
1.2.2.28 LENGTHB 940
1.2.2.29 LIKE 941
1.2.2.30 LOAD_FILE 943
1.2.2.31 LOCATE 943
1.2.2.32 LOWER 944
1.2.2.33 LPAD 944
1.2.2.34 LTRIM 945
1.2.2.35 MAKE_SET 946
1.2.2.36 MATCH AGAINST 947
1.2.2.37 Full-Text Index Stopwords 947
1.2.2.38 MID 948
1.2.2.39 NATURAL_SORT_KEY 948
1.2.2.40 NOT LIKE 952
1.2.2.41 NOT REGEXP 952
1.2.2.42 OCTET_LENGTH 952
1.2.2.43 ORD 952
1.2.2.44 POSITION 953
1.2.2.45 QUOTE 953
1.2.2.46 REPEAT Function 954
1.2.2.47 REPLACE Function 954
1.2.2.48 REVERSE 954
1.2.2.49 RIGHT 955
1.2.2.50 RPAD 955
1.2.2.51 RTRIM 956
1.2.2.52 SFORMAT 957
1.2.2.53 SOUNDEX 958
1.2.2.54 SOUNDS LIKE 958
1.2.2.55 SPACE 959
1.2.2.56 STRCMP 959
1.2.2.57 SUBSTR 960
1.2.2.58 SUBSTRING 960
1.2.2.59 SUBSTRING_INDEX 962
1.2.2.60 TO_BASE64 962
1.2.2.61 TO_CHAR 963
1.2.2.62 TRIM 964
1.2.2.63 TRIM_ORACLE 965
1.2.2.64 UCASE 965
1.2.2.65 UNCOMPRESS 965
1.2.2.66 UNCOMPRESSED_LENGTH 966
1.2.2.67 UNHEX 966
1.2.2.68 UPDATEXML 967
1.2.2.69 UPPER 968
1.2.2.70 WEIGHT_STRING 968
1.2.2.71 Type Conversion 969
1.2.3 Date & Time Functions 972
1.2.3.1 Microseconds in MariaDB 975
1.2.3.2 Date and Time Units 976
1.2.3.3 ADD_MONTHS 977
1.2.3.4 ADDDATE 978
1.2.3.5 ADDTIME 979
1.2.3.6 CONVERT_TZ 980
1.2.3.7 CURDATE 981
1.2.3.8 CURRENT_DATE 981
1.2.3.9 CURRENT_TIME 981
1.2.3.10 CURRENT_TIMESTAMP 982
1.2.3.11 CURTIME 982
1.2.3.12 DATE FUNCTION 983
1.2.3.13 DATEDIFF 983
1.2.3.14 DATE_ADD 984

18/3812
1.2.3.15 DATE_FORMAT 985
1.2.3.16 DATE_SUB 987
1.2.3.17 DAY 988
1.2.3.18 DAYNAME 988
1.2.3.19 DAYOFMONTH 989
1.2.3.20 DAYOFWEEK 989
1.2.3.21 DAYOFYEAR 990
1.2.3.22 EXTRACT 990
1.2.3.23 FROM_DAYS 991
1.2.3.24 FROM_UNIXTIME 992
1.2.3.25 GET_FORMAT 994
1.2.3.26 HOUR 995
1.2.3.27 LAST_DAY 996
1.2.3.28 LOCALTIME 996
1.2.3.29 LOCALTIMESTAMP 996
1.2.3.30 MAKEDATE 997
1.2.3.31 MAKETIME 997
1.2.3.32 MICROSECOND 998
1.2.3.33 MINUTE 999
1.2.3.34 MONTH 999
1.2.3.35 MONTHNAME 1000
1.2.3.36 NOW 1000
1.2.3.37 PERIOD_ADD 1002
1.2.3.38 PERIOD_DIFF 1002
1.2.3.39 QUARTER 1003
1.2.3.40 SECOND 1003
1.2.3.41 SEC_TO_TIME 1004
1.2.3.42 STR_TO_DATE 1004
1.2.3.43 SUBDATE 1006
1.2.3.44 SUBTIME 1007
1.2.3.45 SYSDATE 1008
1.2.3.46 TIME Function 1009
1.2.3.47 TIMEDIFF 1009
1.2.3.48 TIMESTAMP FUNCTION 1010
1.2.3.49 TIMESTAMPADD 1010
1.2.3.50 TIMESTAMPDIFF 1011
1.2.3.51 TIME_FORMAT 1012
1.2.3.52 TIME_TO_SEC 1012
1.2.3.53 TO_DAYS 1013
1.2.3.54 TO_SECONDS 1013
1.2.3.55 UNIX_TIMESTAMP 1014
1.2.3.56 UTC_DATE 1015
1.2.3.57 UTC_TIME 1016
1.2.3.58 UTC_TIMESTAMP 1016
1.2.3.59 WEEK 1017
1.2.3.60 WEEKDAY 1018
1.2.3.61 WEEKOFYEAR 1019
1.2.3.62 YEAR 1020
1.2.3.63 YEARWEEK 1021
1.2.4 Aggregate Functions 1021
1.2.4.1 Stored Aggregate Functions 1022
1.2.4.2 AVG 1025
1.2.4.3 BIT_AND 1026
1.2.4.4 BIT_OR 1027
1.2.4.5 BIT_XOR 1028
1.2.4.6 COUNT 1029
1.2.4.7 COUNT DISTINCT 1030
1.2.4.8 GROUP_CONCAT 1031
1.2.4.9 JSON_ARRAYAGG 1032
1.2.4.10 JSON_OBJECTAGG 1033
1.2.4.11 MAX 1034
1.2.4.12 MIN 1035
1.2.4.13 STD 1037
1.2.4.14 STDDEV 1038
1.2.4.15 STDDEV_POP 1039
1.2.4.16 STDDEV_SAMP 1040
1.2.4.17 SUM 1040
1.2.4.18 VARIANCE 1042
1.2.4.19 VAR_POP 1043
1.2.4.20 VAR_SAMP 1045
1.2.5 Numeric Functions 1046

19/3812
1.2.5.1 Addition Operator (+) 1048
1.2.5.2 Subtraction Operator (-) 1048
1.2.5.3 Division Operator (/) 1048
1.2.5.4 Multiplication Operator (*) 1048
1.2.5.5 Modulo Operator (%) 1048
1.2.5.6 DIV 1048
1.2.5.7 ABS 1048
1.2.5.8 ACOS 1049
1.2.5.9 ASIN 1050
1.2.5.10 ATAN 1050
1.2.5.11 ATAN2 1051
1.2.5.12 CEIL 1051
1.2.5.13 CEILING 1052
1.2.5.14 CONV 1052
1.2.5.15 COS 1053
1.2.5.16 COT 1053
1.2.5.17 CRC32 1054
1.2.5.18 CRC32C 1055
1.2.5.19 DEGREES 1055
1.2.5.20 EXP 1056
1.2.5.21 FLOOR 1056
1.2.5.22 GREATEST 1057
1.2.5.23 LEAST 1057
1.2.5.24 LN 1057
1.2.5.25 LOG 1057
1.2.5.26 LOG10 1058
1.2.5.27 LOG2 1059
1.2.5.28 MOD 1059
1.2.5.29 OCT 1060
1.2.5.30 PI 1061
1.2.5.31 POW 1061
1.2.5.32 POWER 1062
1.2.5.33 RADIANS 1062
1.2.5.34 RAND 1063
1.2.5.35 ROUND 1064
1.2.5.36 SIGN 1065
1.2.5.37 SIN 1066
1.2.5.38 SQRT 1066
1.2.5.39 TAN 1067
1.2.5.40 TRUNCATE 1068
1.2.6 Control Flow Functions 1069
1.2.6.1 CASE OPERATOR 1070
1.2.6.2 DECODE 1070
1.2.6.3 DECODE_ORACLE 1071
1.2.6.4 IF Function 1071
1.2.6.5 IFNULL 1072
1.2.6.6 NULLIF 1073
1.2.6.7 NVL 1074
1.2.6.8 NVL2 1074
1.2.7 Pseudo Columns 1074
1.2.7.1 _rowid 1075
1.2.8 Secondary Functions 1075
1.2.8.1 Bit Functions and Operators 1075
1.2.8.1.1 Operator Precedence 1076
1.2.8.1.2 & 1076
1.2.8.1.3 << 1076
1.2.8.1.4 >> 1077
1.2.8.1.5 BIT_COUNT 1077
1.2.8.1.6 ^ 1077
1.2.8.1.7 | 1078
1.2.8.1.8 ~ 1078
1.2.8.1.9 Parentheses 1079
1.2.8.1.10 TRUE FALSE 1080
1.2.8.2 Encryption, Hashing and Compression Functions 1080
1.2.8.2.1 AES_DECRYPT 1081
1.2.8.2.2 AES_ENCRYPT 1081
1.2.8.2.3 COMPRESS 1081
1.2.8.2.4 DECODE 1082
1.2.8.2.5 DES_DECRYPT 1082
1.2.8.2.6 DES_ENCRYPT 1083
1.2.8.2.7 ENCODE 1083

20/3812
1.2.8.2.8 ENCRYPT 1084
1.2.8.2.9 MD5 1084
1.2.8.2.10 OLD_PASSWORD 1085
1.2.8.2.11 PASSWORD 1085
1.2.8.2.12 RANDOM_BYTES 1086
1.2.8.2.13 SHA1 1087
1.2.8.2.14 SHA2 1087
1.2.8.2.15 UNCOMPRESS 1088
1.2.8.2.16 UNCOMPRESSED_LENGTH 1088
1.2.8.3 Information Functions 1088
1.2.8.3.1 BENCHMARK 1089
1.2.8.3.2 BINLOG_GTID_POS 1089
1.2.8.3.3 CHARSET 1089
1.2.8.3.4 COERCIBILITY 1090
1.2.8.3.5 COLLATION 1091
1.2.8.3.6 CONNECTION_ID 1091
1.2.8.3.7 CURRENT_ROLE 1092
1.2.8.3.8 CURRENT_USER 1092
1.2.8.3.9 DATABASE 1093
1.2.8.3.10 DECODE_HISTOGRAM 1094
1.2.8.3.11 DEFAULT 1095
1.2.8.3.12 FOUND_ROWS 1098
1.2.8.3.13 LAST_INSERT_ID 1099
1.2.8.3.14 LAST_VALUE 1101
1.2.8.3.15 PROCEDURE ANALYSE 1103
1.2.8.3.16 ROWNUM 1103
1.2.8.3.17 ROW_COUNT 1105
1.2.8.3.18 SCHEMA 1106
1.2.8.3.19 SESSION_USER 1106
1.2.8.3.20 SYSTEM_USER 1106
1.2.8.3.21 USER 1107
1.2.8.3.22 VERSION 1107
1.2.8.4 Miscellaneous Functions 1108
1.2.8.4.1 GET_LOCK 1109
1.2.8.4.2 INET6_ATON 1112
1.2.8.4.3 INET6_NTOA 1113
1.2.8.4.4 INET_ATON 1113
1.2.8.4.5 INET_NTOA 1114
1.2.8.4.6 IS_FREE_LOCK 1114
1.2.8.4.7 IS_IPV4 1115
1.2.8.4.8 IS_IPV4_COMPAT 1115
1.2.8.4.9 IS_IPV4_MAPPED 1116
1.2.8.4.10 IS_IPV6 1116
1.2.8.4.11 IS_USED_LOCK 1117
1.2.8.4.12 MASTER_GTID_WAIT 1117
1.2.8.4.13 MASTER_POS_WAIT 1118
1.2.8.4.14 NAME_CONST 1119
1.2.8.4.15 RELEASE_ALL_LOCKS 1119
1.2.8.4.16 RELEASE_LOCK 1120
1.2.8.4.17 SLEEP 1121
1.2.8.4.18 SYS_GUID 1122
1.2.8.4.19 UUID 1122
1.2.8.4.20 UUID_SHORT 1123
1.2.8.4.21 VALUES / VALUE 1124
1.2.9 Special Functions 1125
1.2.9.1 Dynamic Columns Functions 1125
1.2.9.2 Galera Functions 1125
1.2.9.2.1 WSREP_LAST_SEEN_GTID 1125
1.2.9.2.2 WSREP_LAST_WRITTEN_GTID 1126
1.2.9.2.3 WSREP_SYNC_WAIT_UPTO_GTID 1126
1.2.9.3 Geographic Functions 1126
1.2.9.3.1 Geometry Constructors 1127
1.2.9.3.1.1 BUFFER 1127
1.2.9.3.1.2 CONVEXHULL 1128
1.2.9.3.1.3 GEOMETRYCOLLECTION 1128
1.2.9.3.1.4 LINESTRING 1128
1.2.9.3.1.5 MULTILINESTRING 1128
1.2.9.3.1.6 MULTIPOINT 1129
1.2.9.3.1.7 MULTIPOLYGON 1129
1.2.9.3.1.8 POINT 1129
1.2.9.3.1.9 PointOnSurface 1130

21/3812
1.2.9.3.1.10 POLYGON 1130
1.2.9.3.1.11 ST_BUFFER 1130
1.2.9.3.1.12 ST_CONVEXHULL 1131
1.2.9.3.1.13 ST_INTERSECTION 1132
1.2.9.3.1.14 ST_POINTONSURFACE 1132
1.2.9.3.1.15 ST_SYMDIFFERENCE 1132
1.2.9.3.1.16 ST_UNION 1133
1.2.9.3.2 Geometry Properties 1134
1.2.9.3.2.1 BOUNDARY 1135
1.2.9.3.2.2 DIMENSION 1135
1.2.9.3.2.3 ENVELOPE 1135
1.2.9.3.2.4 GeometryN 1135
1.2.9.3.2.5 GeometryType 1135
1.2.9.3.2.6 IsClosed 1135
1.2.9.3.2.7 IsEmpty 1135
1.2.9.3.2.8 IsRing 1135
1.2.9.3.2.9 IsSimple 1135
1.2.9.3.2.10 NumGeometries 1135
1.2.9.3.2.11 SRID 1135
1.2.9.3.2.12 ST_BOUNDARY 1135
1.2.9.3.2.13 ST_DIMENSION 1136
1.2.9.3.2.14 ST_ENVELOPE 1136
1.2.9.3.2.15 ST_GEOMETRYN 1137
1.2.9.3.2.16 ST_GEOMETRYTYPE 1137
1.2.9.3.2.17 ST_ISCLOSED 1138
1.2.9.3.2.18 ST_ISEMPTY 1138
1.2.9.3.2.19 ST_IsRing 1138
1.2.9.3.2.20 ST_IsSimple 1139
1.2.9.3.2.21 ST_NUMGEOMETRIES 1139
1.2.9.3.2.22 ST_RELATE 1139
1.2.9.3.2.23 ST_SRID 1140
1.2.9.3.3 Geometry Relations 1140
1.2.9.3.3.1 CONTAINS 1141
1.2.9.3.3.2 CROSSES 1141
1.2.9.3.3.3 DISJOINT 1142
1.2.9.3.3.4 EQUALS 1142
1.2.9.3.3.5 INTERSECTS 1142
1.2.9.3.3.6 OVERLAPS 1142
1.2.9.3.3.7 ST_CONTAINS 1143
1.2.9.3.3.8 ST_CROSSES 1143
1.2.9.3.3.9 ST_DIFFERENCE 1144
1.2.9.3.3.10 ST_DISJOINT 1144
1.2.9.3.3.11 ST_DISTANCE 1145
1.2.9.3.3.12 ST_DISTANCE_SPHERE 1145
1.2.9.3.3.13 ST_EQUALS 1146
1.2.9.3.3.14 ST_INTERSECTS 1146
1.2.9.3.3.15 ST_LENGTH 1147
1.2.9.3.3.16 ST_OVERLAPS 1147
1.2.9.3.3.17 ST_TOUCHES 1147
1.2.9.3.3.18 ST_WITHIN 1148
1.2.9.3.3.19 TOUCHES 1148
1.2.9.3.3.20 WITHIN 1149
1.2.9.3.4 LineString Properties 1149
1.2.9.3.4.1 ENDPOINT 1150
1.2.9.3.4.2 GLENGTH 1150
1.2.9.3.4.3 NumPoints 1150
1.2.9.3.4.4 PointN 1150
1.2.9.3.4.5 STARTPOINT 1150
1.2.9.3.4.6 ST_ENDPOINT 1150
1.2.9.3.4.7 ST_NUMPOINTS 1151
1.2.9.3.4.8 ST_POINTN 1151
1.2.9.3.4.9 ST_STARTPOINT 1151
1.2.9.3.5 MBR (Minimum Bounding Rectangle) 1152
1.2.9.3.5.1 MBR Definition 1152
1.2.9.3.5.2 MBRContains 1153
1.2.9.3.5.3 MBRDisjoint 1153
1.2.9.3.5.4 MBREqual 1153
1.2.9.3.5.5 MBRIntersects 1154
1.2.9.3.5.6 MBROverlaps 1154
1.2.9.3.5.7 MBRTouches 1155
1.2.9.3.5.8 MBRWithin 1156

22/3812
1.2.9.3.6 Point Properties 1156
1.2.9.3.6.1 ST_X 1157
1.2.9.3.6.2 ST_Y 1157
1.2.9.3.6.3 X 1157
1.2.9.3.6.4 Y 1157
1.2.9.3.7 Polygon Properties 1157
1.2.9.3.7.1 AREA 1158
1.2.9.3.7.2 CENTROID 1158
1.2.9.3.7.3 ExteriorRing 1158
1.2.9.3.7.4 InteriorRingN 1158
1.2.9.3.7.5 NumInteriorRings 1158
1.2.9.3.7.6 ST_AREA 1158
1.2.9.3.7.7 ST_CENTROID 1159
1.2.9.3.7.8 ST_ExteriorRing 1159
1.2.9.3.7.9 ST_InteriorRingN 1160
1.2.9.3.7.10 ST_NumInteriorRings 1160
1.2.9.3.8 WKB 1161
1.2.9.3.8.1 Well-Known Binary (WKB) Format 1162
1.2.9.3.8.2 AsBinary 1162
1.2.9.3.8.3 AsWKB 1162
1.2.9.3.8.4 MLineFromWKB 1162
1.2.9.3.8.5 MPointFromWKB 1163
1.2.9.3.8.6 MPolyFromWKB 1163
1.2.9.3.8.7 GeomCollFromWKB 1164
1.2.9.3.8.8 GeometryCollectionFromWKB 1164
1.2.9.3.8.9 GeometryFromWKB 1164
1.2.9.3.8.10 GeomFromWKB 1164
1.2.9.3.8.11 LineFromWKB 1164
1.2.9.3.8.12 LineStringFromWKB 1164
1.2.9.3.8.13 MultiLineStringFromWKB 1164
1.2.9.3.8.14 MultiPointFromWKB 1164
1.2.9.3.8.15 MultiPolygonFromWKB 1164
1.2.9.3.8.16 PointFromWKB 1164
1.2.9.3.8.17 PolyFromWKB 1164
1.2.9.3.8.18 PolygonFromWKB 1164
1.2.9.3.8.19 ST_AsBinary 1164
1.2.9.3.8.20 ST_AsWKB 1165
1.2.9.3.8.21 ST_GeomCollFromWKB 1165
1.2.9.3.8.22 ST_GeometryCollectionFromWKB 1165
1.2.9.3.8.23 ST_GeometryFromWKB 1165
1.2.9.3.8.24 ST_GeomFromWKB 1165
1.2.9.3.8.25 ST_LineFromWKB 1166
1.2.9.3.8.26 ST_LineStringFromWKB 1166
1.2.9.3.8.27 ST_PointFromWKB 1166
1.2.9.3.8.28 ST_PolyFromWKB 1167
1.2.9.3.8.29 ST_PolygonFromWKB 1167
1.2.9.3.9 WKT 1167
1.2.9.3.9.1 WKT Definition 1169
1.2.9.3.9.2 AsText 1169
1.2.9.3.9.3 AsWKT 1169
1.2.9.3.9.4 GeomCollFromText 1169
1.2.9.3.9.5 GeometryCollectionFromText 1169
1.2.9.3.9.6 GeometryFromText 1169
1.2.9.3.9.7 GeomFromText 1169
1.2.9.3.9.8 LineFromText 1169
1.2.9.3.9.9 LineStringFromText 1170
1.2.9.3.9.10 MLineFromText 1170
1.2.9.3.9.11 MPointFromText 1170
1.2.9.3.9.12 MPolyFromText 1170
1.2.9.3.9.13 MultiLineStringFromText 1171
1.2.9.3.9.14 MultiPointFromText 1171
1.2.9.3.9.15 MultiPolygonFromText 1171
1.2.9.3.9.16 PointFromText 1171
1.2.9.3.9.17 PolyFromText 1171
1.2.9.3.9.18 PolygonFromText 1171
1.2.9.3.9.19 ST_AsText 1171
1.2.9.3.9.20 ST_ASWKT 1172
1.2.9.3.9.21 ST_GeomCollFromText 1172
1.2.9.3.9.22 ST_GeometryCollectionFromText 1172
1.2.9.3.9.23 ST_GeometryFromText 1172
1.2.9.3.9.24 ST_GeomFromText 1172

23/3812
1.2.9.3.9.25 ST_LineFromText 1173
1.2.9.3.9.26 ST_LineStringFromText 1173
1.2.9.3.9.27 ST_PointFromText 1173
1.2.9.3.9.28 ST_PolyFromText 1173
1.2.9.3.9.29 ST_PolygonFromText 1174
1.2.9.4 JSON Functions 1174
1.2.9.4.1 Differences between JSON_QUERY and JSON_VALUE 1176
1.2.9.4.2 JSONPath Expressions 1176
1.2.9.4.3 JSON_ARRAY 1179
1.2.9.4.4 JSON_ARRAYAGG 1179
1.2.9.4.5 JSON_ARRAY_APPEND 1179
1.2.9.4.6 JSON_ARRAY_INSERT 1180
1.2.9.4.7 JSON_COMPACT 1181
1.2.9.4.8 JSON_CONTAINS 1181
1.2.9.4.9 JSON_CONTAINS_PATH 1182
1.2.9.4.10 JSON_DEPTH 1183
1.2.9.4.11 JSON_DETAILED 1183
1.2.9.4.12 JSON_EQUALS 1184
1.2.9.4.13 JSON_EXISTS 1185
1.2.9.4.14 JSON_EXTRACT 1185
1.2.9.4.15 JSON_INSERT 1186
1.2.9.4.16 JSON_KEYS 1186
1.2.9.4.17 JSON_LENGTH 1187
1.2.9.4.18 JSON_LOOSE 1187
1.2.9.4.19 JSON_MERGE 1188
1.2.9.4.20 JSON_MERGE_PATCH 1188
1.2.9.4.21 JSON_MERGE_PRESERVE 1189
1.2.9.4.22 JSON_NORMALIZE 1189
1.2.9.4.23 JSON_OBJECT 1190
1.2.9.4.24 JSON_OBJECTAGG 1190
1.2.9.4.25 JSON_OVERLAPS 1190
1.2.9.4.26 JSON_QUERY 1191
1.2.9.4.27 JSON_QUOTE 1192
1.2.9.4.28 JSON_REMOVE 1192
1.2.9.4.29 JSON_REPLACE 1193
1.2.9.4.30 JSON_SEARCH 1193
1.2.9.4.31 JSON_SET 1194
1.2.9.4.32 JSON_TABLE 1194
1.2.9.4.33 JSON_TYPE 1198
1.2.9.4.34 JSON_UNQUOTE 1199
1.2.9.4.35 JSON_VALID 1200
1.2.9.4.36 JSON_VALUE 1201
1.2.9.5 SEQUENCE Functions 1201
1.2.9.6 Spider Functions 1201
1.2.9.6.1 SPIDER_BG_DIRECT_SQL 1201
1.2.9.6.2 SPIDER_COPY_TABLES 1202
1.2.9.6.3 SPIDER_DIRECT_SQL 1202
1.2.9.6.4 SPIDER_FLUSH_TABLE_MON_CACHE 1203
1.2.9.7 Window Functions 1203
1.2.9.7.1 Window Functions Overview 1205
1.2.9.7.2 AVG 1210
1.2.9.7.3 BIT_AND 1210
1.2.9.7.4 BIT_OR 1210
1.2.9.7.5 BIT_XOR 1210
1.2.9.7.6 COUNT 1210
1.2.9.7.7 CUME_DIST 1210
1.2.9.7.8 DENSE_RANK 1212
1.2.9.7.9 FIRST_VALUE 1212
1.2.9.7.10 JSON_ARRAYAGG 1214
1.2.9.7.11 JSON_OBJECTAGG 1214
1.2.9.7.12 LAG 1214
1.2.9.7.13 LAST_VALUE 1215
1.2.9.7.14 LEAD 1215
1.2.9.7.15 MAX 1216
1.2.9.7.16 MEDIAN 1216
1.2.9.7.17 MIN 1217
1.2.9.7.18 NTH_VALUE 1217
1.2.9.7.19 NTILE 1217
1.2.9.7.20 PERCENT_RANK 1218
1.2.9.7.21 PERCENTILE_CONT 1222
1.2.9.7.22 PERCENTILE_DISC 1224

24/3812
1.2.9.7.23 RANK 1225
1.2.9.7.24 ROW_NUMBER 1226
1.2.9.7.25 STD 1227
1.2.9.7.26 STDDEV 1227
1.2.9.7.27 STDDEV_POP 1227
1.2.9.7.28 STDDEV_SAMP 1227
1.2.9.7.29 SUM 1227
1.2.9.7.30 VARIANCE 1227
1.2.9.7.31 VAR_POP 1227
1.2.9.7.32 VAR_SAMP 1227
1.2.9.7.33 Aggregate Functions as Window Functions 1227
1.2.9.7.34 ColumnStore Window Functions 1228
1.2.9.7.35 Window Frames 1234
1.3 Clients & Utilities 1236
1.3.1 mysql Client 1239
1.3.2 mysql Command-line Client 1239
1.3.3 Delimiters 1248
1.3.4 mariadb Command-Line Client 1249
1.3.5 Aria Clients and Utilities 1249
1.3.5.1 aria_chk 1249
1.3.5.2 aria_pack 1252
1.3.5.3 aria_read_log 1254
1.3.5.4 aria_s3_copy 1255
1.3.6 Backup, Restore and Import Clients 1255
1.3.6.1 Mariabackup 1255
1.3.6.2 mariadb-dump 1255
1.3.6.3 mariadb-dump/mysqldump 1255
1.3.6.4 mariadb-hotcopy 1266
1.3.6.5 mariadb-import 1266
1.3.6.6 mysqlhotcopy 1266
1.3.6.7 mysqlimport 1268
1.3.7 Graphical and Enhanced Clients 1272
1.3.8 MyISAM Clients and Utilities 1273
1.3.8.1 myisamchk 1274
1.3.8.2 Memory and Disk Use With myisamchk 1277
1.3.8.3 myisamchk Table Information 1278
1.3.8.4 myisamlog 1282
1.3.8.5 myisampack 1283
1.3.8.6 myisam_ftdump 1284
1.3.9 dbdeployer 1285
1.3.10 EXPLAIN Analyzer 1285
1.3.11 EXPLAIN Analyzer API 1285
1.3.12 innochecksum 1286
1.3.13 msql2mysql 1288
1.3.14 my_print_defaults 1288
1.3.15 mysqladmin 1289
1.3.16 mysqlaccess 1296
1.3.17 mysqlbinlog 1297
1.3.17.1 Using mysqlbinlog 1298
1.3.17.2 mysqlbinlog Options 1298
1.3.17.3 Annotate_rows_log_event 1303
1.3.17.4 mariadb-binlog 1308
1.3.18 mysqlcheck 1308
1.3.19 mysql_convert_table_format 1308
1.3.20 mysqldumpslow 1309
1.3.21 mysql_embedded 1310
1.3.22 mysql_find_rows 1311
1.3.23 mysql_fix_extensions 1311
1.3.24 mysql_install_db 1312
1.3.25 mysql_plugin 1319
1.3.26 mysqlreport 1320
1.3.27 mysql_secure_installation 1322
1.3.28 mysql_setpermission 1324
1.3.29 mysqlshow 1325
1.3.30 mysqlslap 1328
1.3.31 mysql-stress-test 1332
1.3.32 mysql-test 1334
1.3.32.1 mysql-test Overview 1334
1.3.32.2 mysql-test Auxiliary Files 1337
1.3.32.3 mysql-test-run.pl Options 1342
1.3.32.4 Pausing mysql-test-run.pl 1347

25/3812
1.3.32.5 mysqltest and mysqltest-embedded 1348
1.3.32.6 New Features for mysqltest in MariaDB 1350
1.3.32.7 Debugging MariaDB With a Debugger 1351
1.3.32.8 The Debug Sync Facility 1353
1.3.32.9 Code Coverage with dgcov 1357
1.3.32.10 Installing MinIO for Usage With mysql-test-run 1358
1.3.33 mysql_tzinfo_to_sql 1359
1.3.34 mysql_upgrade 1360
1.3.35 mysql_waitpid 1364
1.3.36 perror 1365
1.3.37 replace Utility 1366
1.3.38 resolveip 1366
1.3.39 resolve_stack_dump 1367
1.3.40 xtstat 1367
1.3.41 mariadb-access 1370
1.3.42 mariadb-admin 1370
1.3.43 mariadb-check 1371
1.3.44 mariadb-conv 1371
1.3.45 mariadb-convert-table-format 1372
1.3.46 mariadb-dumpslow 1372
1.3.47 mariadb-embedded 1373
1.3.48 mariadb-find-rows 1373
1.3.49 mariadb-fix-extensions 1373
1.3.50 mariadb-install-db 1373
1.3.51 mariadb-plugin 1374
1.3.52 mariadb-report 1374
1.3.53 mariadb-secure-installation 1374
1.3.54 mariadb-setpermission 1374
1.3.55 mariadb-show 1374
1.3.56 mariadb-slap 1375
1.3.57 mariadb-tzinfo-to-sql 1375
1.3.58 mariadb-upgrade 1375
1.3.59 mariadb-waitpid 1375
Chapter 2 MariaDB Administration 1375
2.1 Getting, Installing, and Upgrading MariaDB 1376
2.1.1 Where to Download MariaDB 1377
2.1.2 MariaDB Binary Packages 1377
2.1.2.1 Installing MariaDB RPM Files 1378
2.1.2.1.1 About the MariaDB RPM Files 1379
2.1.2.1.2 Installing MariaDB with yum/dnf 1382
2.1.2.1.3 Installing MariaDB with zypper 1387
2.1.2.1.4 Installing MariaDB With the rpm Tool 1392
2.1.2.1.5 Checking MariaDB RPM Package Signatures 1393
2.1.2.1.6 Troubleshooting MariaDB Installs on Red Hat/CentOS 1394
2.1.2.1.7 MariaDB for DirectAdmin Using RPMs 1394
2.1.2.1.8 MariaDB Installation (Version 10.1.21) via RPMs on CentOS 7 1395
2.1.2.1.9 Why Source RPMs (SRPMs) Aren't Packaged For Some Platforms 1396
2.1.2.1.10 Building MariaDB from a Source RPM 1396
2.1.2.2 Installing MariaDB .deb Files 1397
2.1.2.3 Installing MariaDB MSI Packages on Windows 1407
2.1.2.4 Installing MariaDB Server PKG packages on macOS 1414
2.1.2.5 Installing MariaDB Binary Tarballs 1414
2.1.2.6 Installing MariaDB Server on macOS Using Homebrew 1416
2.1.2.7 Installing MariaDB Windows ZIP Packages 1417
2.1.2.8 Compiling MariaDB From Source 1417
2.1.2.8.1 Get, Build and Test Latest MariaDB the Lazy Way 1419
2.1.2.8.2 MariaDB Source Code 1420
2.1.2.8.3 Build Environment Setup for Linux 1420
2.1.2.8.4 Generic Build Instructions 1421
2.1.2.8.5 Compiling MariaDB with Extra Modules/Options 1424
2.1.2.8.5.1 Compiling MariaDB with TCMalloc 1424
2.1.2.8.5.2 Specifying Which Plugins to Build 1424
2.1.2.8.6 Creating the MariaDB Source Tarball 1425
2.1.2.8.7 Creating the MariaDB Binary Tarball 1425
2.1.2.8.8 Build Environment Setup for Mac 1426
2.1.2.8.9 Building MariaDB From a Source RPM 1426
2.1.2.8.10 Building MariaDB on CentOS 1426
2.1.2.8.11 Building MariaDB on Fedora 1427
2.1.2.8.12 Building MariaDB on Debian 1428
2.1.2.8.13 Building MariaDB on FreeBSD 1429
2.1.2.8.14 Building MariaDB on Gentoo 1431

26/3812
2.1.2.8.15 Building MariaDB on Solaris and OpenSolaris 1431
2.1.2.8.16 Building MariaDB on Ubuntu 1431
2.1.2.8.17 Building MariaDB on Windows 1432
2.1.2.8.19 Creating a Debian Repository 1435
2.1.2.8.20 Building MariaDB From Source Using musl-based GNU/Linux 1436
2.1.2.8.21 Compiling MariaDB for Debugging 1436
2.1.2.8.22 Cross-compiling MariaDB 1439
2.1.2.8.23 MariaDB Source Configuration Options 1440
2.1.2.8.24 Building RPM Packages From Source 1440
2.1.2.8.25 Compile and Using MariaDB with Sanitizers (ASAN, UBSAN, TSAN, MSAN) 1440
2.1.2.9 Distributions Which Include MariaDB 1442
2.1.2.10 Running Multiple MariaDB Server Processes 1443
2.1.2.11 Installing MariaDB Alongside MySQL 1445
2.1.2.12 GPG 1447
2.1.2.13 MariaDB Deprecation Policy 1447
2.1.2.14 Automated MariaDB Deployment and Administration 1451
2.1.2.14.1 Why to Automate MariaDB Deployments and Management 1451
2.1.2.14.2 A Comparison Between Automation Systems 1452
2.1.2.14.3 Ansible and MariaDB 1455
2.1.2.14.3.1 Ansible Overview for MariaDB Users 1455
2.1.2.14.3.2 Deploying to Remote Servers with Ansible 1457
2.1.2.14.3.3 Deploying Docker Containers with Ansible 1459
2.1.2.14.3.4 Existing Ansible Modules and Roles for MariaDB 1459
2.1.2.14.3.5 Installing MariaDB .deb Files with Ansible 1461
2.1.2.14.3.6 Running mariadb-tzinfo-to-sql with Ansible 1463
2.1.2.14.3.7 Managing Secrets in Ansible 1464
2.1.2.14.4 Puppet and MariaDB 1465
2.1.2.14.4.1 Puppet Overview for MariaDB Users 1465
2.1.2.14.4.2 Bolt Examples 1468
2.1.2.14.4.3 Puppet hiera Configuration System 1470
2.1.2.14.4.4 Deploying Docker Containers with Puppet 1471
2.1.2.14.4.5 Existing Puppet Modules for MariaDB 1472
2.1.2.14.5 Vagrant and MariaDB 1473
2.1.2.14.5.1 Vagrant Overview for MariaDB Users 1473
2.1.2.14.5.2 Creating a Vagrantfile 1476
2.1.2.14.5.3 Vagrant Security Concerns 1480
2.1.2.14.5.4 Running MariaDB ColumnStore Docker containers on Linux, Windows and MacOS 1481
2.1.2.14.6 Docker and MariaDB 1481
2.1.2.14.6.1 Benefits of Managing Docker Containers with Orchestration Software 1482
2.1.2.14.6.2 Installing and Using MariaDB via Docker 1484
2.1.2.14.6.3 Running MariaDB ColumnStore Docker containers on Linux, Windows and MacOS 1489
2.1.2.14.6.4 Creating a Custom Docker Image 1489
2.1.2.14.6.5 Setting Up a LAMP Stack with Docker Compose 1492
2.1.2.14.6.6 Docker Security Concerns 1494
2.1.2.14.6.7 MariaDB Container Cheat Sheet 1495
2.1.2.14.6.8 MariaDB Docker Environment Variables 1497
2.1.2.14.7 Kubernetes and MariaDB 1498
2.1.2.14.8 Kubernetes Overview for MariaDB Users 1498
2.1.2.14.9 Kubernetes Operators for MariaDB 1501
2.1.2.14.10 Automating Upgrades with MariaDB.Org Downloads REST API 1501
2.1.2.14.11 HashiCorp Vault and MariaDB 1503
2.1.2.14.12 Orchestrator Overview 1504
2.1.2.14.13 Rotating Logs on Unix and Linux 1505
2.1.2.14.14 Automating MariaDB Tasks with Events 1505
2.1.2.15 MariaDB Package Repository Setup and Usage 1506
2.1.3 Upgrading MariaDB 1511
2.1.3.1 Upgrading Between Major MariaDB Versions 1512
2.1.3.2 Upgrading Between Minor Versions on Linux 1514
2.1.3.3 Upgrading from MariaDB 10.6 to MariaDB 10.7 1515
2.1.3.4 Upgrading from MariaDB 10.5 to MariaDB 10.6 1516
2.1.3.5 Upgrading from MariaDB 10.4 to MariaDB 10.5 1519
2.1.3.6 Upgrading from MariaDB 10.3 to MariaDB 10.4 1521
2.1.3.7 Upgrading from MariaDB 10.2 to MariaDB 10.3 1523
2.1.3.8 Upgrading from MariaDB 10.1 to MariaDB 10.2 1525
2.1.3.9 Upgrading MariaDB on Windows 1529
2.1.3.10 Upgrading Galera Cluster 1530
2.1.3.10.1 Upgrading Between Minor Versions with Galera Cluster 1531
2.1.3.10.2 Upgrading from MariaDB 10.3 to MariaDB 10.4 with Galera Cluster 1531
2.1.3.10.3 Upgrading from MariaDB 10.2 to MariaDB 10.3 with Galera Cluster 1532
2.1.3.10.4 Upgrading from MariaDB 10.1 to MariaDB 10.2 with Galera Cluster 1534
2.1.3.11 Upgrading from MySQL to MariaDB 1536

27/3812
2.1.3.11.1 Upgrading from MySQL to MariaDB 1536
2.1.3.11.2 Moving from MySQL to MariaDB in Debian 9 1537
2.1.3.11.3 Screencast for Upgrading MySQL to MariaDB 1542
2.1.4 Downgrading between Major Versions of MariaDB 1542
2.1.5 Compiling MariaDB From Source 1542
2.1.6 Starting and Stopping MariaDB 1542
2.1.6.1 Starting and Stopping MariaDB Server 1543
2.1.6.2 Configuring MariaDB with Option Files 1544
2.1.6.3 mysqld Configuration Files and Groups 1552
2.1.6.4 mysqld Options 1552
2.1.6.5 What to Do if MariaDB Doesn't Start 1596
2.1.6.6 Running MariaDB from the Build Directory 1599
2.1.6.7 mysql.server 1601
2.1.6.8 mysqld_safe 1603
2.1.6.9 mysqladmin 1608
2.1.6.10 Switching Between Different Installed MariaDB Versions 1608
2.1.6.11 Specifying Permissions for Schema (Data) Directories and Tables 1610
2.1.6.12 mysqld_multi 1610
2.1.6.13 launchd 1614
2.1.6.14 systemd 1615
2.1.6.15 sysVinit 1626
2.1.6.16 Mariadb-admin 1628
2.1.6.17 mariadbd 1628
2.1.6.18 mariadbd-multi 1628
2.1.6.19 mariadbd-safe 1628
2.1.7 MariaDB Performance & Advanced Configurations 1628
2.1.7.1 Fusion-io 1629
2.1.7.1.1 Fusion-io Introduction 1629
2.1.7.1.2 Atomic Write Support 1631
2.1.7.1.3 InnoDB Page Flushing 1632
2.1.7.3 Configuring Linux for MariaDB 1632
2.1.7.4 Configuring MariaDB for Optimal Performance 1634
2.1.7.5 Configuring Swappiness 1635
2.1.8 Troubleshooting Installation Issues 1636
2.1.8.1 Troubleshooting Connection Issues 1637
2.1.8.2 Installation issues on Windows 1637
2.1.8.3 Troubleshooting MariaDB Installs on Red Hat/CentOS 1637
2.1.8.4 Installation issues on Debian and Ubuntu 1638
2.1.8.4.1 Differences in MariaDB in Debian (and Ubuntu) 1638
2.1.8.4.2 Upgrading from MySQL to MariaDB 1639
2.1.8.4.3 Creating a Debian Repository 1639
2.1.8.4.4 apt-upgrade Fails, But the Database is Running 1639
2.1.8.5 What to Do if MariaDB Doesn't Start 1640
2.1.8.6 Installing on an Old Linux Version 1640
2.1.8.7 Error: symbol mysql_get_server_name, version libmysqlclient_16 not defined 1641
2.1.9 Installing System Tables (mysql_install_db) 1641
2.1.10 mysql_install_db.exe 1641
2.1.11 Configuring MariaDB with Option Files 1642
2.1.12 MariaDB Environment Variables 1642
2.1.13 MariaDB on Amazon AWS 1643
2.1.14 Migrating to MariaDB 1644
2.1.14.1 Migrating to MariaDB from MySQL 1644
2.1.14.1.1 MySQL vs MariaDB: Performance 1645
2.1.14.1.2 MariaDB versus MySQL: Compatibility 1648
2.1.14.1.3 Upgrading from MySQL to MariaDB 1653
2.1.14.1.4 Incompatibilities and Feature Differences Between MariaDB 10.8 and MySQL 8.0 1653
2.1.14.1.5 Incompatibilities and Feature Differences Between MariaDB 10.7 and MySQL 8.0 1657
2.1.14.1.6 Incompatibilities and Feature Differences Between MariaDB 10.6 and MySQL 8.0 1660
2.1.14.1.7 Incompatibilities and Feature Differences Between MariaDB 10.5 and MySQL 8.0 1663
2.1.14.1.8 Incompatibilities and Feature Differences Between MariaDB 10.4 and MySQL 8.0 1666
2.1.14.1.9 Incompatibilities and Feature Differences Between MariaDB 10.3 and MySQL 5.7 1669
2.1.14.1.10 Function Differences Between MariaDB and MySQL 1671
2.1.14.1.10.1 Function Differences Between MariaDB 10.8 and MySQL 8.0 1672
2.1.14.1.10.2 Function Differences Between MariaDB 10.7 and MySQL 8.0 1675
2.1.14.1.10.3 Function Differences Between MariaDB 10.6 and MySQL 8.0 1678
2.1.14.1.10.4 Function Differences Between MariaDB 10.5 and MySQL 8.0 1682
2.1.14.1.10.5 Function Differences Between MariaDB 10.4 and MySQL 8.0 1684
2.1.14.1.10.6 Function Differences Between MariaDB 10.3 and MySQL 8.0 1687
2.1.14.1.10.7 Function Differences Between MariaDB 10.3 and MySQL 5.7 1690
2.1.14.1.11 System Variable Differences between MariaDB and MySQL 1692
2.1.14.1.11.1 System Variable Differences Between MariaDB 10.9 and MySQL 8.0 1693

28/3812
2.1.14.1.11.2 System Variable Differences Between MariaDB 10.8 and MySQL 8.0 1703
2.1.14.1.11.3 System Variable Differences Between MariaDB 10.7 and MySQL 8.0 1714
2.1.14.1.11.4 System Variable Differences Between MariaDB 10.6 and MySQL 8.0 1725
2.1.14.1.11.5 System Variable Differences Between MariaDB 10.5 and MySQL 8.0 1735
2.1.14.1.11.6 System Variable Differences Between MariaDB 10.4 and MySQL 8.0 1746
2.1.14.1.11.7 System Variable Differences Between MariaDB 10.3 and MySQL 8.0 1756
2.1.14.1.11.8 System Variable Differences Between MariaDB 10.3 and MySQL 5.7 1766
2.1.14.1.12 Upgrading from MySQL 5.7 to MariaDB 10.2 1773
2.1.14.1.13 Installing MariaDB Alongside MySQL 1773
2.1.14.1.14 Moving from MySQL to MariaDB in Debian 9 1774
2.1.14.2 Migrating to MariaDB from SQL Server 1774
2.1.14.2.1 Understanding MariaDB Architecture 1774
2.1.14.2.2 SQL Server Features Not Available in MariaDB 1781
2.1.14.2.3 SQL Server Features Implemented Differently in MariaDB 1782
2.1.14.2.4 MariaDB Features Not Available in SQL Server 1784
2.1.14.2.5 Setting Up MariaDB for Testing for SQL Server Users 1785
2.1.14.2.6 Syntax Differences between MariaDB and SQL Server 1786
2.1.14.2.7 SQL Server and MariaDB Types Comparison 1791
2.1.14.2.8 MariaDB Transactions and Isolation Levels for SQL Server Users 1795
2.1.14.2.9 MariaDB Authorization and Permissions for SQL Server Users 1801
2.1.14.2.10 Repairing MariaDB Tables for SQL Server Users 1804
2.1.14.2.11 MariaDB Backups Overview for SQL Server Users 1805
2.1.14.2.12 MariaDB Replication Overview for SQL Server Users 1808
2.1.14.2.13 Moving Data Between SQL Server and MariaDB 1814
2.1.14.2.14 SQL_MODE=MSSQL 1816
2.1.14.3 Migrating to MariaDB from PostgreSQL 1817
2.1.14.4.2 SQL_MODE=ORACLE 1819
2.1.14.5 Installing MariaDB on IBM Cloud 1823
2.1.14.6 mysqld Configuration Files and Groups 1833
2.2 User & Server Security 1833
2.2.1 Securing MariaDB 1833
2.2.1.1 Encryption 1833
2.2.1.1.1 Data-in-Transit Encryption 1834
2.2.1.1.1.1 Secure Connections Overview 1834
2.2.1.1.1.2 Certificate Creation with OpenSSL 1839
2.2.1.1.1.3 Securing Connections for Client and Server 1841
2.2.1.1.1.4 Replication with Secure Connections 1844
2.2.1.1.1.5 Securing Communications in Galera Cluster 1847
2.2.1.1.1.6 SSL/TLS System Variables 1848
2.2.1.1.1.7 SSL/TLS Status Variables 1851
2.2.1.1.1.8 Using TLSv1.3 1855
2.2.1.1.2 Data-at-Rest Encryption 1855
2.2.1.1.2.1 Data-at-Rest Encryption Overview 1856
2.2.1.1.2.2 Why Encrypt MariaDB Data? 1857
2.2.1.1.2.3 Key Management and Encryption Plugins 1858
2.2.1.1.2.4 Encrypting Binary Logs 1858
2.2.1.1.2.5 Aria Encryption 1860
2.2.1.1.2.5.1 Aria Encryption Overview 1860
2.2.1.1.2.5.2 Aria Enabling Encryption 1860
2.2.1.1.2.5.3 Aria Disabling Encryption 1861
2.2.1.1.2.5.4 Aria Encryption Keys 1862
2.2.1.1.2.6 InnoDB Encryption 1862
2.2.1.1.2.6.1 InnoDB Encryption Overview 1863
2.2.1.1.2.6.2 Enabling InnoDB Encryption 1863
2.2.1.1.2.6.3 Disabling InnoDB Encryption 1867
2.2.1.1.2.6.4 InnoDB Background Encryption Threads 1869
2.2.1.1.2.6.5 InnoDB Encryption Keys 1870
2.2.1.1.2.6.6 InnoDB Encryption Troubleshooting 1872
2.2.1.1.3 TLS and Cryptography Libraries Used by MariaDB 1875
2.2.1.2 Running mysqld as root 1879
2.2.1.3 mysql_secure_installation 1879
2.2.1.4 Security-Enhanced Linux with MariaDB 1879
2.2.2 User Account Management 1883
2.2.2.1 Account Management SQL Commands 1883
2.2.2.2 Data-in-Transit Encryption 1883
2.2.2.3 Roles 1883
2.2.2.3.1 Roles Overview 1884
2.2.2.3.2 CREATE ROLE 1887
2.2.2.3.3 DROP ROLE 1887
2.2.2.3.4 CURRENT_ROLE 1887
2.2.2.3.5 SET ROLE 1887

29/3812
2.2.2.3.6 SET DEFAULT ROLE 1887
2.2.2.3.7 GRANT 1887
2.2.2.3.8 REVOKE 1887
2.2.2.3.9 mysqlroles_mapping Table 1887
2.2.2.3.10 Information Schema APPLICABLE_ROLES Table 1888
2.2.2.3.11 Information Schema ENABLED_ROLES Table 1888
2.2.2.4 Account Locking 1888
2.2.2.5 Authentication from MariaDB 10.4 1889
2.2.2.6 User Password Expiry 1891
2.3 Backing Up and Restoring Databases 1893
2.3.1 Backup and Restore Overview 1893
2.3.2 Replication as a Backup Solution 1895
2.3.3 mariadb-dump/mysqldump 1895
2.3.4 Mariabackup 1895
2.3.4.1 Mariabackup Overview 1896
2.3.4.2 Mariabackup Options 1905
2.3.4.3 Full Backup and Restore with Mariabackup 1930
2.3.4.4 Incremental Backup and Restore with Mariabackup 1932
2.3.4.5 Partial Backup and Restore with Mariabackup 1934
2.3.4.6 Restoring Individual Tables and Partitions with Mariabackup 1936
2.3.4.7 Setting up a Replica with Mariabackup 1936
2.3.4.8 Files Backed Up By Mariabackup 1939
2.3.4.9 Files Created by Mariabackup 1939
2.3.4.10 Using Encryption and Compression Tools With Mariabackup 1944
2.3.4.11 How Mariabackup Works 1945
2.3.4.12 Mariabackup and BACKUP STAGE Commands 1947
2.3.4.13 mariabackup SST Method 1950
2.3.4.14 Manual SST of Galera Cluster Node with Mariabackup 1954
2.3.5 mysqlhotcopy 1954
2.4 Server Monitoring & Logs 1954
2.4.1 Overview of MariaDB Logs 1955
2.4.2 Error Log 1956
2.4.3 Setting the Language for Error Messages 1961
2.4.4 General Query Log 1963
2.4.5 Slow Query Log 1965
2.4.5.1 Slow Query Log Overview 1966
2.4.5.2 Slow Query Log Extended Statistics 1971
2.4.5.3 mysqldumpslow 1971
2.4.5.4 EXPLAIN in the Slow Query Log 1971
2.4.5.5 mysqlslow_log Table 1971
2.4.6 Rotating Logs on Unix and Linux 1971
2.4.7 Binary Log 1976
2.4.8 InnoDB Redo Log 1976
2.4.9 InnoDB Undo Log 1976
2.4.10 MyISAM Log 1976
2.4.11 Transaction Coordinator Log 1976
2.4.11.1 Transaction Coordinator Log Overview 1976
2.4.11.2 Heuristic Recovery with the Transaction Coordinator Log 1978
2.4.12 SQL Error Log Plugin 1980
2.4.13 Writing Logs Into Tables 1980
2.4.14 Performance Schema 1980
2.4.15 MariaDB Audit Plugin 1980
2.5 Partitioning Tables 1980
2.5.1 Partitioning Overview 1980
2.5.2 Partitioning Types 1981
2.5.2.1 Partitioning Types Overview 1982
2.5.2.2 LIST Partitioning Type 1982
2.5.2.3 RANGE Partitioning Type 1983
2.5.2.4 HASH Partitioning Type 1985
2.5.2.5 RANGE COLUMNS and LIST COLUMNS Partitioning Types 1985
2.5.3 Partition Pruning and Selection 1986
2.5.4 Partition Maintenance 1987
2.5.5 Partitioning Limitations with MariaDB 1990
2.5.6 Partitions Files 1990
2.5.7 Partitions Metadata 1991
2.6 MariaDB Audit Plugin 1991
2.7 Variables and Modes 1991
2.7.1 Full List of MariaDB Options, System and Status Variables 1992
2.7.2 Server System Variables 2039
2.7.3 OLD_MODE 2108
2.7.4 SQL_MODE 2109

30/3812
2.7.5 SQL_MODE-MSSQL 2115
2.8 Copying Tables Between Different MariaDB Databases and MariaDB Servers 2115
Chapter 3 High Availability & Performance Tuning 2117
3.1 MariaDB Replication 2117
3.1.1 Replication Overview 2119
3.1.2 Replication Commands 2122
3.1.3 Setting Up Replication 2122
3.1.4 Setting up a Replica with Mariabackup 2125
3.1.5 Read-Only Replicas 2125
3.1.6 Replication as a Backup Solution 2126
3.1.7 Multi-Source Replication 2126
3.1.8 Replication Threads 2130
3.1.9 Global Transaction ID 2132
3.1.10 Parallel Replication 2144
3.1.11 Replication and Binary Log System Variables 2148
3.1.12 Replication and Binary Log Status Variables 2166
3.1.13 Binary Log 2172
3.1.13.1 Overview of the Binary Log 2173
3.1.13.2 Activating the Binary Log 2173
3.1.13.3 Using and Maintaining the Binary Log 2174
3.1.13.4 Binary Log Formats 2176
3.1.13.5 Binary Logging of Stored Routines 2179
3.1.13.6 SHOW BINARY LOGS 2180
3.1.13.7 PURGE BINARY LOGS 2180
3.1.13.8 SHOW BINLOG EVENTS 2180
3.1.13.9 SHOW MASTER STATUS 2180
3.1.13.10 Binlog Event Checksums 2180
3.1.13.11 Binlog Event Checksum Interoperability 2180
3.1.13.12 Group Commit for the Binary Log 2181
3.1.13.13 mysqlbinlog 2183
3.1.13.14 Transaction Coordinator Log 2183
3.1.13.15 Compressing Events to Reduce Size of the Binary Log 2183
3.1.13.16 Encrypting Binary Logs 2184
3.1.13.17 Flashback 2184
3.1.13.18 Relay Log 2185
3.1.13.19 Replication and Binary Log System Variables 2186
3.1.14 Unsafe Statements for Statement-based Replication 2186
3.1.15 Replication and Foreign Keys 2187
3.1.16 Relay Log 2188
3.1.18 Group Commit for the Binary Log 2189
3.1.19 Selectively Skipping Replication of Binlog Events 2189
3.1.20 Binlog Event Checksums 2190
3.1.21 Annotate_rows_log_event 2191
3.1.22 Row-based Replication With No Primary Key 2191
3.1.23 Replication Filters 2191
3.1.24 Running Triggers on the Replica for Row-based Events 2199
3.1.25 Semisynchronous Replication 2200
3.1.26 Using MariaDB Replication with MariaDB Galera Cluster 2207
3.1.26.1 Using MariaDB Replication with MariaDB Galera Cluster 2207
3.1.26.2 Using MariaDB GTIDs with MariaDB Galera Cluster 2208
3.1.26.3 Configuring MariaDB Replication between MariaDB Galera Cluster and MariaDB Server 2210
3.1.26.4 Configuring MariaDB Replication between Two MariaDB Galera Clusters 2213
3.1.27 Delayed Replication 2217
3.1.28 Replication When the Primary and Replica Have Different Table Definitions 2218
3.1.29 Restricting Speed of Reading Binlog from Primary by a Replica 2221
3.1.30 Changing a Replica to Become the Primary 2221
3.1.31 Replication with Secure Connections 2223
3.2 MariaDB Galera Cluster 2223
3.2.1 What is MariaDB Galera Cluster? 2225
3.2.2 About Galera Replication 2227
3.2.3 Galera Use Cases 2229
3.2.4 MariaDB Galera Cluster - Known Limitations 2229
3.2.5 Tips on Converting to Galera 2231
3.2.6 Getting Started with MariaDB Galera Cluster 2235
3.2.7 Configuring MariaDB Galera Cluster 2240
3.2.8 State Snapshot Transfers (SSTs) in Galera Cluster 2242
3.2.8.1 Introduction to State Snapshot Transfers (SSTs) 2242
3.2.8.2 mariabackup SST Method 2246
3.2.8.3 Manual SST of Galera Cluster Node With Mariabackup 2246
3.2.8.4 xtrabackup-v2 SST Method 2248
3.2.8.5 Manual SST of Galera Cluster Node With Percona XtraBackup 2252

31/3812
3.2.9 Galera Cluster Status Variables 2254
3.2.10 Galera Cluster System Variables 2261
3.2.11 Building the Galera wsrep Package on Ubuntu and Debian 2272
3.2.12 Building the Galera wsrep Package on Fedora 2273
3.2.13 Installing Galera from Source 2275
3.2.14 Galera Test Repositories 2277
3.2.15 wsrep_provider_options 2278
3.2.16 Galera Cluster Address 2288
3.2.17 Galera Load Balancer 2289
3.2.18 Upgrading Galera Cluster 2289
3.2.19 Using MariaDB Replication with MariaDB Galera Cluster 2289
3.2.20 Securing Communications in Galera Cluster 2289
3.2.21 Installing MariaDB Galera on IBM Cloud 2289
3.3 Optimization and Tuning 2299
3.3.1 Hardware Optimization 2300
3.3.2 Operating System Optimizations 2301
3.3.2.1 Configuring Linux for MariaDB 2301
3.3.2.2 Configuring Swappiness 2301
3.3.2.3 Filesystem Optimizations 2301
3.3.3 Optimization and Indexes 2301
3.3.3.1 The Essentials of an Index 2302
3.3.3.2 Getting Started with Indexes 2302
3.3.3.3 Full-Text Indexes 2305
3.3.3.3.1 Full-Text Index Overview 2306
3.3.3.3.2 Full-Text Index Stopwords 2309
3.3.3.3.3 MATCH AGAINST 2313
3.3.3.3.4 myisam_ftdump 2313
3.3.3.4 ANALYZE TABLE 2313
3.3.3.5 Building the best INDEX for a given SELECT 2313
3.3.3.6 Compound (Composite) Indexes 2321
3.3.3.7 EXPLAIN 2324
3.3.3.8 Foreign Keys 2324
3.3.3.9 Ignored Indexes 2328
3.3.3.10 Index Statistics 2330
3.3.3.11 Latitude/Longitude Indexing 2332
3.3.3.12 Primary Keys with Nullable Columns 2339
3.3.3.13 SHOW EXPLAIN 2340
3.3.3.14 Spatial Index 2340
3.3.3.15 Storage Engine Index Types 2340
3.3.4 Query Optimizations 2341
3.3.4.1 Index Hints: How to Force Query Plans 2342
3.3.4.2 Subquery Optimizations 2346
3.3.4.2.1 Subquery Optimizations Map 2347
3.3.4.2.2 Semi-join Subquery Optimizations 2348
3.3.4.2.3 Table Pullout Optimization 2349
3.3.4.2.4 Non-semi-join Subquery Optimizations 2351
3.3.4.2.5 Subquery Cache 2355
3.3.4.2.6 Condition Pushdown Into IN subqueries 2358
3.3.4.2.7 Conversion of Big IN Predicates Into Subqueries 2358
3.3.4.2.8 EXISTS-to-IN Optimization 2359
3.3.4.2.9 Optimizing GROUP BY and DISTINCT Clauses in Subqueries 2360
3.3.4.3 Optimization Strategies 2360
3.3.4.3.1 DuplicateWeedout Strategy 2361
3.3.4.3.2 FirstMatch Strategy 2363
3.3.4.3.3 LooseScan Strategy 2365
3.3.4.3.4 Semi-join Materialization Strategy 2366
3.3.4.3.5 Improvements to ORDER BY Optimization 2369
3.3.4.4 Optimizations for Derived Tables 2370
3.3.4.4.1 Condition Pushdown into Derived Table Optimization 2370
3.3.4.4.2 Derived Table Merge Optimization 2371
3.3.4.4.3 Derived Table with Key Optimization 2373
3.3.4.4.4 Lateral Derived Optimization 2374
3.3.4.5 Table Elimination 2375
3.3.4.5.1 What is Table Elimination? 2376
3.3.4.5.2 Table Elimination in MariaDB 2377
3.3.4.5.3 Table Elimination User Interface 2377
3.3.4.5.4 Table Elimination in Other Databases 2378
3.3.4.5.5 Table Elimination External Resources 2379
3.3.4.6 Statistics for Optimizing Queries 2379
3.3.4.6.1 Engine-Independent Table Statistics 2380
3.3.4.6.2 Histogram-Based Statistics 2382

32/3812
3.3.4.6.3 Index Statistics 2383
3.3.4.6.4 InnoDB Persistent Statistics 2383
3.3.4.6.5 Slow Query Log Extended Statistics 2383
3.3.4.6.6 User Statistics 2384
3.3.4.7 MIN/MAX optimization 2387
3.3.4.8 Filesort with Small LIMIT Optimization 2388
3.3.4.9 LIMIT ROWS EXAMINED 2389
3.3.4.10 Block-Based Join Algorithms 2390
3.3.4.11 index_merge sort_intersection 2393
3.3.4.13 optimizer_switch 2394
3.3.4.14 Extended Keys 2397
3.3.4.15 How to Quickly Insert Data Into MariaDB 2399
3.3.4.16 Index Condition Pushdown 2401
3.3.4.17 Query Limits and Timeouts 2404
3.3.4.18 Aborting Statements that Exceed a Certain Time to Execute 2405
3.3.4.19 Partition Pruning and Selection 2406
3.3.4.20 Big DELETEs 2406
3.3.4.21 Data Sampling: Techniques for Efficiently Finding a Random Row 2410
3.3.4.22 Data Warehousing High Speed Ingestion 2413
3.3.4.23 Data Warehousing Summary Tables 2417
3.3.4.24 Data Warehousing Techniques 2422
3.3.4.25 Equality propagation optimization 2426
3.3.4.26 FORCE INDEX 2428
3.3.4.27 Groupwise Max in MariaDB 2429
3.3.4.28 GUID/UUID Performance 2434
3.3.4.29 IGNORE INDEX 2436
3.3.4.30 not_null_range_scan Optimization 2437
3.3.4.31 Optimizing for "Latest News"-style Queries 2438
3.3.4.32 Pagination Optimization 2440
3.3.4.33 Pivoting in MariaDB 2443
3.3.4.34 Rollup Unique User Counts 2448
3.3.4.35 Rowid Filtering Optimization 2449
3.3.4.36 USE INDEX 2451
3.3.5 Optimizing Tables 2451
3.3.5.1 OPTIMIZE TABLE 2452
3.3.5.2 ANALYZE TABLE 2452
3.3.5.3 Choosing the Right Storage Engine 2452
3.3.5.4 Converting Tables from MyISAM to InnoDB 2452
3.3.5.5 Histogram-Based Statistics 2452
3.3.5.6 Defragmenting InnoDB Tablespaces 2452
3.3.5.7 Entity-Attribute-Value Implementation 2455
3.3.5.8 IP Range Table Performance 2457
3.3.6 MariaDB Memory Allocation 2459
3.3.7 System Variables 2466
3.3.7.1 System and Status Variables Added By Major Release 2468
3.3.7.1.1 System Variables Added in MariaDB 10.11 2469
3.3.7.1.2 System Variables Added in MariaDB 10.9 2469
3.3.7.1.3 System Variables Added in MariaDB 10.6 2469
3.3.7.1.4 Status Variables Added in MariaDB 10.6 2470
3.3.7.1.5 System Variables Added in MariaDB 10.5 2470
3.3.7.1.6 Status Variables Added in MariaDB 10.5 2471
3.3.7.1.7 System Variables Added in MariaDB 10.4 2472
3.3.7.1.8 Status Variables Added in MariaDB 10.4 2473
3.3.7.1.9 System Variables Added in MariaDB 10.3 2473
3.3.7.1.10 Status Variables Added in MariaDB 10.3 2474
3.3.7.1.11 System Variables Added in MariaDB 10.2 2475
3.3.7.1.12 Status Variables Added in MariaDB 10.2 2476
3.3.7.2 Full List of MariaDB Options, System and Status Variables 2476
3.3.7.3 Server Status Variables 2476
3.3.7.4 Server System Variables 2526
3.3.7.5 Aria Status Variables 2526
3.3.7.6 Aria System Variables 2526
3.3.7.7 CONNECT System Variables 2526
3.3.7.8 Galera Cluster Status Variables 2526
3.3.7.9 Galera Cluster System Variables 2526
3.3.7.10 InnoDB Server Status Variables 2526
3.3.7.11 InnoDB System Variables 2526
3.3.7.12 MariaDB Audit Plugin � Status Variables 2526
3.3.7.13 Mroonga Status Variables 2526
3.3.7.14 Mroonga System Variables 2526
3.3.7.15 MyISAM System Variables 2526

33/3812
3.3.7.16 MyRocks System Variables 2526
3.3.7.17 MyRocks Status Variables 2526
3.3.7.18 OQGRAPH System and Status Variables 2526
3.3.7.19 Performance Schema Status Variables 2526
3.3.7.20 Performance Schema System Variables 2526
3.3.7.21 Replication and Binary Log Status Variables 2527
3.3.7.22 Replication and Binary Log System Variables 2527
3.3.7.23 Semisynchronous Replication Plugin Status Variables 2527
3.3.7.24 Semisynchronous Replication 2528
3.3.7.25 Sphinx Status Variables 2529
3.3.7.26 Spider Status Variables 2529
3.3.7.27 Spider Server System Variables 2529
3.3.7.28 SQL_ERROR_LOG Plugin System Variables 2529
3.3.7.29 SSL/TLS Status Variables 2530
3.3.7.30 SSL/TLS System Variables 2531
3.3.7.31 Thread Pool System and Status Variables 2531
3.3.7.34 MariaDB Optimization for MySQL Users 2534
3.3.7.35 InnoDB Buffer Pool 2535
3.3.7.36 InnoDB Change Buffering 2535
3.3.7.37 Optimizing table_open_cache 2535
3.3.7.38 Optimizing key_buffer_size 2536
3.3.7.39 Segmented Key Cache 2536
3.3.7.40 Big Query Settings 2536
3.3.7.41 Sample my.cnf Files 2537
3.3.7.42 Handling Too Many Connections 2537
3.3.7.43 System Variable Differences between MariaDB and MySQL 2537
3.3.7.44 MariaDB Memory Allocation 2537
3.3.7.45 Setting Innodb Buffer Pool Size Dynamically 2537
3.3.8 Buffers, Caches and Threads 2538
3.3.8.1 Thread Pool 2538
3.3.8.2 Thread Pool in MariaDB 2539
3.3.8.3 Thread Groups in the Unix Implementation of the Thread Pool 2543
3.3.8.4 Thread Pool System and Status Variables 2548
3.3.8.5 Thread Pool in MariaDB 5.1 - 5.3 2548
3.3.9 Thread States 2549
3.3.9.1 Delayed Insert Connection Thread States 2549
3.3.9.2 Delayed Insert Handler Thread States 2550
3.3.9.3 Event Scheduler Thread States 2550
3.3.9.4 General Thread States 2550
3.3.9.5 Master Thread States 2553
3.3.9.6 Query Cache Thread States 2553
3.3.9.7 Slave Connection Thread States 2553
3.3.9.8 Slave I/O Thread States 2554
3.3.9.9 Slave SQL Thread States 2554
3.3.9.10 InnoDB Buffer Pool 2555
3.3.9.11 InnoDB Change Buffering 2555
3.3.9.12 Query Cache 2555
3.3.9.13 Segmented Key Cache 2561
3.3.9.14 Subquery Cache 2561
3.3.9.15 Thread Command Values 2562
3.3.10 Optimizing Data Structure 2562
3.3.10.1 Numeric vs String Fields 2563
3.3.10.2 Optimizing MEMORY Tables 2563
3.3.10.3 Optimizing String and Character Fields 2563
3.3.11 MariaDB Internal Optimizations 2563
3.3.11.1 Binary Log Group Commit and InnoDB Flushing Performance 2563
3.3.11.2 Fair Choice Between Range and Index_merge Optimizations 2563
3.3.11.3 Improvements to ORDER BY Optimization 2565
3.3.11.4 Multi Range Read Optimization 2565
3.3.12 Compression 2571
3.3.12.1 Encryption, Hashing and Compression Functions 2571
3.3.12.2 Storage-Engine Independent Column Compression 2571
3.3.12.3 InnoDB Page Compression 2573
3.3.12.4 Compression Plugins 2573
3.3.12.5 Compressing Events to Reduce Size of the Binary Log 2573
3.3.12.6 InnoDB COMPRESSED Row Format 2573
3.3.12.7 ColumnStore Compression Mode 2573
Chapter 4 Programming & Customizing MariaDB 2574
4.1 Programmatic & Compound Statements 2574
4.2 Stored Routines 2574
4.2.1 Stored Procedures 2574

34/3812
4.2.1.1 Stored Procedure Overview 2575
4.2.1.2 Stored Routine Privileges 2577
4.2.1.3 CREATE PROCEDURE 2578
4.2.1.4 ALTER PROCEDURE 2578
4.2.1.5 DROP PROCEDURE 2578
4.2.1.6 SHOW CREATE PROCEDURE 2578
4.2.1.7 SHOW PROCEDURE CODE 2578
4.2.1.8 SHOW PROCEDURE STATUS 2578
4.2.1.9 Binary Logging of Stored Routines 2578
4.2.1.10 Information Schema ROUTINES Table 2578
4.2.1.11 SQL_MODE=ORACLE 2578
4.2.1.12 Stored Procedure Internals 2578
4.2.2.1 Stored Function Overview 2592
4.2.2.2 Stored Routine Privileges 2594
4.2.2.3 CREATE FUNCTION 2594
4.2.2.4 ALTER FUNCTION 2594
4.2.2.5 DROP FUNCTION 2594
4.2.2.6 SHOW CREATE FUNCTION 2594
4.2.2.7 SHOW FUNCTION STATUS 2594
4.2.2.8 SHOW FUNCTION CODE 2594
4.2.2.9 Stored Aggregate Functions 2594
4.2.2.10 Binary Logging of Stored Routines 2594
4.2.2.11 Stored Function Limitations 2594
4.2.2.12 Information Schema ROUTINES Table 2595
4.2.3 Stored Routine Statements 2595
4.2.4 Binary Logging of Stored Routines 2595
4.2.5 Stored Routine Limitations 2595
4.2.6 Stored Routine Privileges 2595
4.3 Triggers & Events 2595
4.3.1 Triggers 2595
4.3.1.1 Trigger Overview 2596
4.3.1.2 Binary Logging of Stored Routines 2600
4.3.1.3 CREATE TRIGGER 2600
4.3.1.4 DROP TRIGGER 2600
4.3.1.5 Information Schema TRIGGERS Table 2600
4.3.1.6 Running Triggers on the Replica for Row-based Events 2600
4.3.1.7 SHOW CREATE TRIGGER 2600
4.3.1.8 SHOW TRIGGERS 2600
4.3.1.9 Trigger Limitations 2600
4.3.1.10 Triggers and Implicit Locks 2600
4.3.2 Event Scheduler 2601
4.3.2.1 Events Overview 2601
4.3.2.2 Event Limitations 2603
4.3.2.3 CREATE EVENT 2604
4.3.2.4 ALTER EVENT 2604
4.3.2.5 DROP EVENT 2604
4.3.2.6 Information Schema EVENTS Table 2604
4.3.2.7 SHOW EVENTS 2604
4.3.2.8 SHOW CREATE EVENT 2604
4.3.2.9 Automating MariaDB Tasks with Events 2604
4.3.2.10 mysql.event Table 2604
4.4 Views 2604
4.4.1 Creating & Using Views 2605
4.4.2 CREATE VIEW 2605
4.4.3 ALTER VIEW 2605
4.4.4 DROP VIEW 2605
4.4.5 SHOW CREATE VIEW 2605
4.4.6 Inserting and Updating with Views 2605
4.4.7 RENAME TABLE 2606
4.4.8 View Algorithms 2606
4.4.9 Information Schema VIEWS Table 2608
4.4.10 SHOW TABLES 2608
4.5 User-Defined Functions 2608
4.5.1 Creating User-Defined Functions 2608
4.5.2 User-Defined Functions Calling Sequences 2610
4.5.3 User-Defined Functions Security 2612
4.5.4 CREATE FUNCTION UDF 2612
4.5.5 DROP FUNCTION UDF 2612
4.5.6 mysql.func Table 2612
Chapter 5 Columns, Storage Engines, and Plugins 2612
5.1 Data Types 2612

35/3812
5.1.1 Numeric Data Types 2615
5.1.1.1 Numeric Data Type Overview 2616
5.1.1.2 TINYINT 2618
5.1.1.3 BOOLEAN 2620
5.1.1.4 SMALLINT 2621
5.1.1.5 MEDIUMINT 2622
5.1.1.6 INT 2624
5.1.1.7 INTEGER 2625
5.1.1.8 BIGINT 2625
5.1.1.9 DECIMAL 2626
5.1.1.10 DEC, NUMERIC, FIXED 2628
5.1.1.11 NUMBER 2628
5.1.1.12 FLOAT 2628
5.1.1.13 DOUBLE 2629
5.1.1.14 DOUBLE PRECISION 2630
5.1.1.15 BIT 2630
5.1.1.16 Floating-point Accuracy 2631
5.1.1.17 INT1 2631
5.1.1.18 INT2 2631
5.1.1.19 INT3 2632
5.1.1.20 INT4 2632
5.1.1.21 INT8 2632
5.1.2 String Data Types 2632
5.1.2.1 String Literals 2633
5.1.2.2 BINARY 2634
5.1.2.3 BLOB 2635
5.1.2.4 BLOB and TEXT Data Types 2636
5.1.2.5 CHAR 2636
5.1.2.6 CHAR BYTE 2637
5.1.2.7 ENUM 2637
5.1.2.8 INET4 2639
5.1.2.9 INET6 2639
5.1.2.10 JSON Data Type 2646
5.1.2.11 MEDIUMBLOB 2647
5.1.2.12 MEDIUMTEXT 2648
5.1.2.13 LONGBLOB 2648
5.1.2.14 LONG and LONG VARCHAR 2648
5.1.2.15 LONGTEXT 2649
5.1.2.16 ROW 2649
5.1.2.17 TEXT 2654
5.1.2.18 TINYBLOB 2655
5.1.2.19 TINYTEXT 2656
5.1.2.20 VARBINARY 2656
5.1.2.21 VARCHAR 2657
5.1.2.22 SET Data Type 2659
5.1.2.23 UUID Data Type 2659
5.1.2.24 Data Type Storage Requirements 2661
5.1.2.25 Supported Character Sets and Collations 2664
5.1.2.26 Character Sets and Collations 2670
5.1.3 Date and Time Data Types 2670
5.1.3.1 DATE 2670
5.1.3.2 TIME 2671
5.1.3.3 DATETIME 2673
5.1.3.4 TIMESTAMP 2675
5.1.3.5 YEAR Data Type 2680
5.1.4 Geometry Types 2681
5.1.5 AUTO_INCREMENT 2681
5.1.6 Data Type Storage Requirements 2685
5.1.7 AUTO_INCREMENT FAQ 2685
5.1.8 NULL Values 2688
5.2 Character Sets and Collations 2692
5.2.1 Character Set and Collation Overview 2693
5.2.2 Supported Character Sets and Collations 2694
5.2.3 Setting Character Sets and Collations 2694
5.2.4 Unicode 2701
5.2.5 SHOW CHARACTER SET 2701
5.2.6 SHOW COLLATION 2701
5.2.7 Information Schema CHARACTER_SETS Table 2702
5.2.8 Information Schema COLLATIONS Table 2702
5.2.9 Internationalization and Localization 2702
5.2.9.3 Setting the Language for Error Messages 2703

36/3812
5.2.9.5 Locales plugin 2703
5.2.9.6 mysql_tzinfo_to_sql 2703
5.2.10 SET CHARACTER SET 2703
5.2.11 SET NAMES 2703
5.3 Storage Engines 2703
5.3.1 Choosing the Right Storage Engine 2704
5.3.2 InnoDB 2706
5.3.2.1 InnoDB Versions 2708
5.3.2.2 InnoDB Limitations 2710
5.3.2.3 InnoDB Troubleshooting 2712
5.3.2.3.1 InnoDB Troubleshooting Overview 2712
5.3.2.3.2 InnoDB Data Dictionary Troubleshooting 2712
5.3.2.3.3 InnoDB Recovery Modes 2713
5.3.2.3.4 Troubleshooting Row Size Too Large Errors with InnoDB 2715
5.3.2.4 InnoDB System Variables 2731
5.3.2.5 InnoDB Server Status Variables 2785
5.3.2.6 AUTO_INCREMENT Handling in InnoDB 2809
5.3.2.7 InnoDB Buffer Pool 2811
5.3.2.8 InnoDB Change Buffering 2812
5.3.2.9 InnoDB Doublewrite Buffer 2813
5.3.2.10 InnoDB Tablespaces 2813
5.3.2.10.1 InnoDB System Tablespaces 2813
5.3.2.10.2 InnoDB File-Per-Table Tablespaces 2815
5.3.2.10.3 InnoDB Temporary Tablespaces 2821
5.3.2.11 InnoDB File Format 2821
5.3.2.12 InnoDB Row Formats 2823
5.3.2.12.1 InnoDB Row Formats Overview 2823
5.3.2.12.2 InnoDB REDUNDANT Row Format 2827
5.3.2.12.3 InnoDB COMPACT Row Format 2828
5.3.2.12.4 InnoDB DYNAMIC Row Format 2829
5.3.2.12.5 InnoDB COMPRESSED Row Format 2831
5.3.2.12.6 Troubleshooting Row Size Too Large Errors with InnoDB 2833
5.3.2.13 InnoDB Strict Mode 2833
5.3.2.14 InnoDB Redo Log 2840
5.3.2.15 InnoDB Undo Log 2842
5.3.2.16 InnoDB Page Flushing 2843
5.3.2.17 InnoDB Purge 2844
5.3.2.18 Information Schema InnoDB Tables 2847
5.3.2.19 InnoDB Online DDL 2847
5.3.2.19.1 InnoDB Online DDL Overview 2847
5.3.2.19.2 InnoDB Online DDL Operations with the INPLACE Alter Algorithm 2853
5.3.2.19.3 InnoDB Online DDL Operations with the NOCOPY Alter Algorithm 2869
5.3.2.19.4 InnoDB Online DDL Operations with the INSTANT Alter Algorithm 2878
5.3.2.19.5 Instant ADD COLUMN for InnoDB 2893
5.3.2.20 Binary Log Group Commit and InnoDB Flushing Performance 2894
5.3.2.21 InnoDB Page Compression 2895
5.3.2.22 InnoDB Data Scrubbing 2903
5.3.2.23 InnoDB Lock Modes 2903
5.3.2.24 InnoDB Monitors 2904
5.3.2.25 InnoDB Encryption Overview 2906
5.3.3 MariaDB ColumnStore 2908
5.3.4 Aria 2909
5.3.4.1 Aria Storage Engine 2909
5.3.4.2 Aria Clients and Utilities 2911
5.3.4.3 Aria FAQ 2911
5.3.4.4 Aria Storage Formats 2916
5.3.4.5 Aria Status Variables 2917
5.3.4.6 Aria System Variables 2918
5.3.4.7 Aria Group Commit 2923
5.3.4.8 Benchmarking Aria 2924
5.3.4.9 Aria Two-step Deadlock Detection 2925
5.3.4.10 Aria Encryption Overview 2925
5.3.4.11 The Aria Name 2926
5.3.5 Archive 2927
5.3.6 BLACKHOLE 2928
5.3.7 CONNECT 2930
5.3.7.1 Introduction to the CONNECT Engine 2933
5.3.7.2 Installing the CONNECT Storage Engine 2933
5.3.7.3 CONNECT Create Table Options 2935
5.3.7.4 CONNECT Data Types 2937
5.3.7.5 Current Status of the CONNECT Handler 2943

37/3812
5.3.7.6 CONNECT Table Types 2943
5.3.7.6.1 CONNECT Table Types Overview 2945
5.3.7.6.2 Inward and Outward Tables 2946
5.3.7.6.3 CONNECT Table Types - Data Files 2947
5.3.7.6.4 CONNECT Zipped File Tables 2949
5.3.7.6.5 CONNECT DOS and FIX Table Types 2951
5.3.7.6.6 CONNECT DBF Table Type 2954
5.3.7.6.7 CONNECT BIN Table Type 2956
5.3.7.6.8 CONNECT VEC Table Type 2958
5.3.7.6.9 CONNECT CSV and FMT Table Types 2959
5.3.7.6.10 CONNECT - NoSQL Table Types 2962
5.3.7.6.11 CONNECT - Files Retrieved Using Rest Queries 2963
5.3.7.6.12 CONNECT JSON Table Type 2964
5.3.7.6.13 CONNECT XML Table Type 3007
5.3.7.6.14 CONNECT INI Table Type 3020
5.3.7.6.15 CONNECT - External Table Types 3022
5.3.7.6.16 CONNECT ODBC Table Type: Accessing Tables From Another DBMS 3023
5.3.7.6.17 CONNECT JDBC Table Type: Accessing Tables from Another DBMS 3035
5.3.7.6.18 CONNECT MONGO Table Type: Accessing Collections from MongoDB 3042
5.3.7.6.19 CONNECT MYSQL Table Type: Accessing MySQL/MariaDB Tables 3049
5.3.7.6.20 CONNECT PROXY Table Type 3054
5.3.7.6.21 CONNECT XCOL Table Type 3055
5.3.7.6.22 CONNECT OCCUR Table Type 3059
5.3.7.6.23 CONNECT PIVOT Table Type 3060
5.3.7.6.24 CONNECT TBL Table Type: Table List 3066
5.3.7.6.25 CONNECT - Using the TBL and MYSQL Table Types Together 3068
5.3.7.6.26 CONNECT Table Types - Special "Virtual" Tables 3070
5.3.7.6.27 CONNECT Table Types - VIR 3074
5.3.7.6.28 CONNECT Table Types - OEM: Implemented in an External LIB 3076
5.3.7.6.29 CONNECT Table Types - Catalog Tables 3077
5.3.7.7 CONNECT - Security 3081
5.3.7.8 CONNECT - OEM Table Example 3082
5.3.7.9 Using CONNECT 3084
5.3.7.9.1 Using CONNECT - General Information 3084
5.3.7.9.2 Using CONNECT - Virtual and Special Columns 3085
5.3.7.9.3 Using CONNECT - Importing File Data Into MariaDB Tables 3086
5.3.7.9.4 Using CONNECT - Exporting Data From MariaDB 3087
5.3.7.9.5 Using CONNECT - Indexing 3087
5.3.7.9.6 Using CONNECT - Condition Pushdown 3090
5.3.7.9.7 USING CONNECT - Offline Documentation 3090
5.3.7.9.8 Using CONNECT - Partitioning and Sharding 3090
5.3.7.10 CONNECT - Making the GetRest Library 3097
5.3.7.11 CONNECT - Adding the REST Feature as a Library Called by an OEM Table 3099
5.3.7.12 CONNECT - Compiling JSON UDFs in a Separate Library 3101
5.3.7.13 CONNECT System Variables 3103
5.3.7.14 JSON Sample Files 3107
5.3.8 CSV 3115
5.3.8.1 CSV Overview 3115
5.3.8.2 Checking and Repairing CSV Tables 3116
5.3.9 FederatedX 3117
5.3.9.1 About FederatedX 3117
5.3.9.2 Differences Between FederatedX and Federated 3123
5.3.10 MEMORY Storage Engine 3123
5.3.11 MERGE 3124
5.3.12 Mroonga 3126
5.3.12.1 About Mroonga 3126
5.3.12.2 Mroonga Overview 3127
5.3.12.3 Mroonga Status Variables 3129
5.3.12.4 Mroonga System Variables 3130
5.3.12.5 Mroonga User-Defined Functions 3134
5.3.12.5.1 Creating Mroonga User-Defined Functions 3134
5.3.12.5.2 last_insert_grn_id 3135
5.3.12.5.3 mroonga_command 3135
5.3.12.5.4 mroonga_escape 3136
5.3.12.5.5 mroonga_highlight_html 3137
5.3.12.5.6 mroonga_normalize 3138
5.3.12.5.7 mroonga_snippet 3139
5.3.12.5.8 mroonga_snippet_html 3139
5.3.12.6 Information Schema MROONGA_STATS Table 3140
5.3.13 MyISAM 3140
5.3.13.1 MyISAM Overview 3140

38/3812
5.3.13.2 MyISAM System Variables 3141
5.3.13.3 MyISAM Storage Formats 3144
5.3.13.4 MyISAM Clients and Utilities 3145
5.3.13.5 MyISAM Index Storage Space 3145
5.3.13.6 MyISAM Log 3145
5.3.13.7 Concurrent Inserts 3146
5.3.13.8 Segmented Key Cache 3146
5.3.14 MyRocks 3147
5.3.14.1 About MyRocks for MariaDB 3148
5.3.14.2 Getting Started with MyRocks 3149
5.3.14.3 Building MyRocks in MariaDB 3151
5.3.14.4 Loading Data Into MyRocks 3152
5.3.14.5 MyRocks Status Variables 3153
5.3.14.6 MyRocks System Variables 3166
5.3.14.7 MyRocks Transactional Isolation 3192
5.3.14.8 MyRocks and Replication 3192
5.3.14.9 MyRocks and Group Commit with Binary log 3193
5.3.14.10 Optimizer Statistics in MyRocks 3194
5.3.14.11 Differences Between MyRocks Variants 3195
5.3.14.12 MyRocks and Bloom Filters 3196
5.3.14.13 MyRocks and CHECK TABLE 3197
5.3.14.14 MyRocks and Data Compression 3198
5.3.14.15 MyRocks and Index-Only Scans 3199
5.3.14.16 MyRocks and START TRANSACTION WITH CONSISTENT SNAPSHOT 3201
5.3.14.17 MyRocks Column Families 3201
5.3.14.18 MyRocks in MariaDB 10.2 vs MariaDB 10.3 3202
5.3.14.19 MyRocks Performance Troubleshooting 3202
5.3.15 OQGRAPH 3203
5.3.15.1 Installing OQGRAPH 3204
5.3.15.2 OQGRAPH Overview 3204
5.3.15.3 OQGRAPH Examples 3207
5.3.15.4 Compiling OQGRAPH 3210
5.3.15.5 Building OQGRAPH Under Windows 3210
5.3.15.6 OQGRAPH System and Status Variables 3211
5.3.16 S3 Storage Engine 3211
5.3.16.1 Using the S3 Storage Engine 3212
5.3.16.2 Testing the Connections to S3 3216
5.3.16.3 S3 Storage Engine Internals 3218
5.3.16.4 aria_s3_copy 3220
5.3.16.5 S3 Storage Engine Status Variables 3221
5.3.16.6 S3 Storage Engine System Variables 3222
5.3.17 Sequence Storage Engine 3225
5.3.18 SphinxSE 3229
5.3.18.1 About SphinxSE 3229
5.3.18.2 Installing Sphinx 3233
5.3.18.3 Configuring Sphinx 3234
5.3.18.4 Installing and Testing SphinxSE with MariaDB 3234
5.3.18.5 Sphinx Status Variables 3235
5.3.19 Spider 3235
5.3.19.1 Spider Storage Engine Overview 3236
5.3.19.2 Spider Installation 3248
5.3.19.3 Spider Storage Engine Core Concepts 3251
5.3.19.4 Spider Use Cases 3253
5.3.19.5 Spider Cluster Management 3256
5.3.19.6 Spider Feature Matrix 3259
5.3.19.7 Spider Server System Variables 3260
5.3.19.8 Spider Table Parameters 3285
5.3.19.9 Spider Status Variables 3289
5.3.19.10 Spider Functions 3290
5.3.19.10.1 SPIDER_BG_DIRECT_SQL 3290
5.3.19.10.2 SPIDER_COPY_TABLES 3290
5.3.19.10.3 SPIDER_DIRECT_SQL 3290
5.3.19.10.4 SPIDER_FLUSH_TABLE_MON_CACHE 3290
5.3.19.11 Spider mysql Database Tables 3290
5.3.19.11.1 mysqlspider_link_failed_log Table 3290
5.3.19.11.2 mysqlspider_link_mon_servers Table 3290
5.3.19.11.3 mysqlspider_tables Table 3290
5.3.19.11.4 mysqlspider_table_crd Table 3291
5.3.19.11.5 mysqlspider_table_position_for_recovery Table 3291
5.3.19.11.6 mysqlspider_table_sts Table 3291
5.3.19.11.7 mysqlspider_xa Table 3291

39/3812
5.3.19.11.8 mysqlspider_xa_failed_log Table 3291
5.3.19.11.9 mysqlspider_xa_member Table 3291
5.3.19.12 Information Schema SPIDER_ALLOC_MEM Table 3291
5.3.19.13 Information Schema SPIDER_WRAPPER_PROTOCOLS Table 3291
5.3.19.14 Spider Differences Between SpiderForMySQL and MariaDB 3291
5.3.19.15 Spider Case Studies 3291
5.3.19.16 Spider Benchmarks 3291
5.3.19.17 Spider FAQ 3293
5.3.20 Information Schema ENGINES Table 3294
5.3.21 PERFORMANCE_SCHEMA Storage Engine 3294
5.3.22 Storage Engine Development 3294
5.3.22.1 Storage Engine FAQ 3294
5.3.22.2 Engine-defined New Table/Field/Index Attributes 3295
5.3.22.3 Table Discovery 3297
5.3.23 Converting Tables from MyISAM to InnoDB 3299
5.3.24 Machine Learning with MindsDB 3302
5.4 Plugins 3303
5.4.1 Plugin Overview 3304
5.4.2 Information on Plugins 3309
5.4.2.1 List of Plugins 3309
5.4.2.2 Information Schema PLUGINS Table 3311
5.4.2.3 Information Schema ALL_PLUGINS Table 3311
5.4.3 Plugin SQL Statements 3311
5.4.4 Creating and Building Plugins 3311
5.4.4.1 Specifying Which Plugins to Build 3311
5.4.4.2 Writing Plugins for MariaDB 3312
5.4.5 MariaDB Audit Plugin 3313
5.4.5.1 MariaDB Audit Plugin - Installation 3314
5.4.5.2 MariaDB Audit Plugin - Configuration 3315
5.4.5.3 MariaDB Audit Plugin - Log Settings 3316
5.4.5.4 MariaDB Audit Plugin - Location and Rotation of Logs 3319
5.4.5.5 MariaDB Audit Plugin - Log Format 3320
5.4.5.6 MariaDB Audit Plugin - Versions 3321
5.4.5.7 MariaDB Audit Plugin Options and System Variables 3321
5.4.5.8 MariaDB Audit Plugin - Status Variables 3326
5.4.6 Authentication Plugins 3326
5.4.6.1 Pluggable Authentication Overview 3327
5.4.6.2 Authentication Plugin - mysql_native_password 3335
5.4.6.3 Authentication Plugin - mysql_old_password 3337
5.4.6.4 Authentication Plugin - ed25519 3339
5.4.6.5 Authentication Plugin - GSSAPI 3342
5.4.6.6 Authentication with Pluggable Authentication Modules (PAM) 3348
5.4.6.6.1 Authentication Plugin - PAM 3348
5.4.6.6.2 User and Group Mapping with PAM 3358
5.4.6.6.3 Configuring PAM Authentication and User Mapping with Unix Authentication 3363
5.4.6.6.4 Configuring PAM Authentication and User Mapping with LDAP Authentication 3366
5.4.6.7 Authentication Plugin - Unix Socket 3375
5.4.6.8 Authentication Plugin - Named Pipe 3378
5.4.6.9 Authentication Plugin - SHA-256 3380
5.4.7 Password Validation Plugins 3381
5.4.7.1 Simple Password Check Plugin 3382
5.4.7.2 Cracklib Password Check Plugin 3384
5.4.7.3 Password Reuse Check Plugin 3387
5.4.7.4 Password Validation Plugin API 3388
5.4.7.5 password_reuse_check_interval 3390
5.4.8 Key Management and Encryption Plugins 3390
5.4.8.1 Encryption Key Management 3390
5.4.8.2 File Key Management Encryption Plugin 3392
5.4.8.3 Hashicorp Key Management Plugin 3397
5.4.8.4 AWS Key Management Encryption Plugin 3400
5.4.8.5 Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Setup Guide 3404
5.4.8.6 Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Advanced Usage 3410
5.4.8.7 Eperi Key Management Encryption Plugin 3417
5.4.8.8 Encryption Plugin API 3420
5.4.9 MariaDB Replication & Cluster Plugins 3423
5.4.9.1 Semisynchronous Replication 3424
5.4.9.2 WSREP_INFO Plugin 3424
5.4.10 Storage Engines 3425
5.4.11 Other Plugins 3425
5.4.11.1 Feedback Plugin 3426
5.4.11.2 Locales Plugin 3429

40/3812
5.4.11.3 METADATA_LOCK_INFO Plugin 3431
5.4.11.4 MYSQL_JSON 3433
5.4.11.5 Query Cache Information Plugin 3434
5.4.11.6 Query Response Time Plugin 3435
5.4.11.7 SQL Error Log Plugin 3439
5.4.11.8 User Statistics 3442
5.4.11.9 User Variables Plugin 3442
5.4.11.10 Disks Plugin 3443
5.4.11.11 Compression Plugins 3445
Chapter 6 Training & Tutorials 3445
6.1 Beginner MariaDB Articles 3446
6.1.1 A MariaDB Primer 3447
6.1.2 MariaDB Basics 3449
6.1.3 Getting Data from MariaDB 3452
6.1.4 Adding and Changing Data in MariaDB 3455
6.1.5 Altering Tables in MariaDB 3458
6.1.6 Changing Times in MariaDB 3462
6.1.7 Doing Time with MariaDB 3465
6.1.8 Importing Data into MariaDB 3470
6.1.9 Making Backups with mysqldump 3474
6.1.10 MariaDB String Functions 3475
6.1.11 Restoring Data from Dump Files 3478
6.1.12 Basic SQL Queries: A Quick SQL Cheat Sheet 3479
6.1.13 Connecting to MariaDB 3480
6.1.14 External Tutorials 3483
6.1.15 Useful MariaDB Queries 3484
6.2 Basic MariaDB Articles 3488
6.2.1 Basic SQL Debugging 3489
6.2.2 Configuring MariaDB for Remote Client Access 3492
6.2.3 Creating & Using Views 3494
6.2.4 Getting Started with Indexes 3499
6.2.5 Joining Tables with JOIN Clauses 3499
6.2.6 The Essentials of an Index 3500
6.2.7 Troubleshooting Connection Issues 3501
6.3 Intermediate MariaDB Articles 3503
6.3.1 Database Theory 3504
6.3.1.1 Introduction to Relational Databases 3504
6.3.1.2 Exploring Early Database Models 3505
6.3.1.3 Understanding the Hierarchical Database Model 3505
6.3.1.4 Understanding the Network Database Model 3506
6.3.1.5 Understanding the Relational Database Model 3506
6.3.1.6 Relational Databases: Basic Terms 3507
6.3.1.7 Relational Databases: Table Keys 3508
6.3.1.8 Relational Databases: Foreign Keys 3508
6.3.1.9 Relational Databases: Views 3509
6.3.1.10 Database Design 3510
6.3.1.10.1 Database Design: Overview 3511
6.3.1.10.2 Database Lifecycle 3511
6.3.1.10.3 Database Design Phase 1: Analysis 3512
6.3.1.10.4 Database Design Phase 2: Conceptual Design 3513
6.3.1.10.5 Database Design Phase 2: Logical and Physical Design 3516
6.3.1.10.6 Database Design Phase 3: Implementation 3517
6.3.1.10.7 Database Design Phase 4: Testing 3518
6.3.1.10.8 Database Design Phase 5: Operation 3518
6.3.1.10.9 Database Design Phase 6: Maintenance 3518
6.3.1.10.10 Database Design Example Phase 1: Analysis 3519
6.3.1.10.11 Database Design Example Phase 2: Design 3519
6.3.1.10.12 Database Design Example Phase 3: Implementation 3522
6.3.1.10.13 Database Design Example Phases 4-6: Testing, Operation and Maintenance 3523
6.3.1.11 Database Normalization 3524
6.3.1.11.1 Database Normalization Overview 3524
6.3.1.11.2 Database Normalization: 1st Normal Form 3528
6.3.1.11.3 Database Normalization: 2nd Normal Form 3529
6.3.1.11.4 Database Normalization: 3rd Normal Form 3530
6.3.1.11.5 Database Normalization: Boyce-Codd Normal Form 3531
6.3.1.11.6 Database Normalization: 4th Normal Form 3533
6.3.1.11.7 Database Normalization: 5th Normal Form and Beyond 3535
6.3.1.11.8 Understanding Denormalization 3536
6.3.1.12 ACID: Concurrency Control with Transactions 3537
6.3.2 Starting and Stopping MariaDB 3537
6.4 Advanced MariaDB Articles 3537

41/3812
6.4.1 Development Articles 3538
6.4.1.2 MariaDB Internals Documentation 3539
6.4.1.2.1 Optimizer Trace 3539
6.4.1.2.1.1 Optimizer Trace Overview 3539
6.4.1.2.1.2 Optimizer Trace Guide 3541
6.4.1.2.1.3 Basic Optimizer Trace Example 3545
6.4.1.2.2 Using MariaDB with Your Programs (API) 3547
6.4.1.2.2.1 Error Codes 3548
6.4.1.2.2.1.1 MariaDB Error Codes 3548
6.4.1.2.2.1.2 Operating System Error Codes 3548
6.4.1.2.2.1.3 SQLSTATE 3552
6.4.1.2.2.2 Progress Reporting 3553
6.4.1.3 EXPLAIN FORMAT=JSON in MySQL 3556
Chapter 7 MariaDB Server Releases 3557
7.1 Release Notes 3558
7.1.1 MariaDB Server 10.11 3561
7.1.1.1 Changes and Improvements in MariaDB 10.11 3561
7.1.1.2 Release Notes - MariaDB 10.11 Series 3562
7.1.1.2.1 MariaDB 10.11.0 Release Notes 3562
7.1.2 MariaDB Server 10.10 3563
7.1.2.1 Changes and Improvements in MariaDB 10.10 3563
7.1.2.2 Release Notes - MariaDB 10.10 Series 3565
7.1.2.2.1 MariaDB 10.10.1 Release Notes 3565
7.1.2.2.2 MariaDB 10.10.0 Release Notes 3567
7.1.3 MariaDB Server 10.9 3568
7.1.3.1 Changes and Improvements in MariaDB 10.9 3568
7.1.3.2 Release Notes - MariaDB 10.9 Series 3569
7.1.3.2.1 MariaDB 10.9.3 Release Notes 3570
7.1.3.2.2 MariaDB 10.9.2 Release Notes 3570
7.1.3.2.3 MariaDB 10.9.1 Release Notes 3572
7.1.3.2.4 MariaDB 10.9.0 Release Notes 3574
7.1.4 MariaDB Server 10.8 3575
7.1.4.1 Changes and Improvements in MariaDB 10.8 3575
7.1.4.2 Release Notes - MariaDB 10.8 Series 3577
7.1.4.2.1 MariaDB 10.8.5 Release Notes 3578
7.1.4.2.2 MariaDB 10.8.4 Release Notes 3578
7.1.4.2.3 MariaDB 10.8.3 Release Notes 3581
7.1.4.2.4 MariaDB 10.8.2 Release notes 3582
7.1.4.2.5 MariaDB 10.8.1 Release Notes 3583
7.1.4.2.6 MariaDB 10.8.0 Release Notes 3585
7.1.5 MariaDB Server 10.7 3587
7.1.5.1 Changes and Improvements in MariaDB 10.7 3587
7.1.5.2 Release Notes - MariaDB 10.7 Series 3589
7.1.5.2.1 MariaDB 10.7.6 Release Notes 3590
7.1.5.2.2 MariaDB 10.7.5 Release Notes 3591
7.1.5.2.3 MariaDB 10.7.4 Release Notes 3593
7.1.5.2.4 MariaDB 10.7.3 Release Notes 3595
7.1.5.2.5 MariaDB 10.7.2 Release Notes 3596
7.1.5.2.6 MariaDB 10.7.1 Release Notes 3598
7.1.5.2.7 MariaDB 10.7.0 Release Notes 3600
7.1.6 MariaDB Server 10.6 3601
7.1.6.1 Changes and Improvements in MariaDB 10.6 3601
7.1.6.2 Release Notes - MariaDB 10.6 Series 3605
7.1.6.2.1 MariaDB 10.6.10 Release Notes 3605
7.1.6.2.2 MariaDB 10.6.9 Release Notes 3606
7.1.6.2.3 MariaDB 10.6.8 Release Notes 3608
7.1.6.2.4 MariaDB 10.6.7 Release Notes 3611
7.1.6.2.5 MariaDB 10.6.6 Release Notes 3611
7.1.6.2.6 MariaDB 10.6.5 Release Notes 3613
7.1.6.2.7 MariaDB 10.6.4 Release Notes 3614
7.1.6.2.8 MariaDB 10.6.3 Release Notes 3616
7.1.6.2.9 MariaDB 10.6.2 Release Notes 3617
7.1.6.2.10 MariaDB 10.6.1 Release Notes 3618
7.1.6.2.11 MariaDB 10.6.0 Release Notes 3619
7.1.7 MariaDB Server 10.5 3621
7.1.7.1 Changes and Improvements in MariaDB 10.5 3621
7.1.7.2 Release Notes - MariaDB 10.5 Series 3627
7.1.7.2.1 MariaDB 10.5.18 Release Notes 3628
7.1.7.2.2 MariaDB 10.5.17 Release Notes 3629
7.1.7.2.3 MariaDB 10.5.16 Release Notes 3631
7.1.7.2.4 MariaDB 10.5.15 Release Notes 3632

42/3812
7.1.7.2.5 MariaDB 10.5.14 Release Notes 3633
7.1.7.2.6 MariaDB 10.5.13 Release Notes 3635
7.1.7.2.7 MariaDB 10.5.12 Release Notes 3636
7.1.7.2.8 MariaDB 10.5.11 Release Notes 3637
7.1.7.2.9 MariaDB 10.5.10 Release Notes 3639
7.1.7.2.10 MariaDB 10.5.9 Release Notes 3640
7.1.7.2.11 MariaDB 10.5.8 Release Notes 3642
7.1.7.2.12 MariaDB 10.5.7 Release Notes 3642
7.1.7.2.13 MariaDB 10.5.6 Release Notes 3644
7.1.7.2.14 MariaDB 10.5.5 Release Notes 3645
7.1.7.2.15 MariaDB 10.5.4 Release Notes 3647
7.1.7.2.16 MariaDB 10.5.3 Release Notes 3648
7.1.7.2.17 MariaDB 10.5.2 Release Notes 3650
7.1.7.2.18 MariaDB 10.5.1 Release Notes 3652
7.1.7.2.19 MariaDB 10.5.0 Release Notes 3653
7.1.8 MariaDB Server 10.4 3655
7.1.8.1 Changes and Improvements in MariaDB 10.4 3655
7.1.8.2 Release Notes - MariaDB 10.4 Series 3661
7.1.8.2.1 MariaDB 10.4.27 Release Notes 3662
7.1.8.2.2 MariaDB 10.4.26 Release Notes 3662
7.1.8.2.3 MariaDB 10.4.25 Release Notes 3664
7.1.8.2.4 MariaDB 10.4.24 Release Notes 3666
7.1.8.2.5 MariaDB 10.4.23 Release Notes 3667
7.1.8.2.6 MariaDB 10.4.22 Release Notes 3668
7.1.8.2.7 MariaDB 10.4.21 Release Notes 3670
7.1.8.2.8 MariaDB 10.4.20 Release Notes 3671
7.1.8.2.9 MariaDB 10.4.19 Release Notes 3672
7.1.8.2.10 MariaDB 10.4.18 Release Notes 3673
7.1.8.2.11 MariaDB 10.4.17 Release Notes 3675
7.1.8.2.12 MariaDB 10.4.16 Release Notes 3675
7.1.8.2.13 MariaDB 10.4.15 Release Notes 3677
7.1.8.2.14 MariaDB 10.4.14 Release Notes 3678
7.1.8.2.15 MariaDB 10.4.13 Release Notes 3679
7.1.8.2.16 MariaDB 10.4.12 Release Notes 3681
7.1.8.2.17 MariaDB 10.4.11 Release Notes 3683
7.1.8.2.18 MariaDB 10.4.10 Release Notes 3684
7.1.8.2.19 MariaDB 10.4.9 Release Notes 3685
7.1.8.2.20 MariaDB 10.4.8 Release Notes 3686
7.1.8.2.21 MariaDB 10.4.7 Release Notes 3687
7.1.8.2.22 MariaDB 10.4.6 Release Notes 3688
7.1.8.2.23 MariaDB 10.4.5 Release Notes 3689
7.1.8.2.24 MariaDB 10.4.4 Release Notes 3690
7.1.8.2.25 MariaDB 10.4.3 Release Notes 3691
7.1.8.2.26 MariaDB 10.4.2 Release Notes 3692
7.1.8.2.27 MariaDB 10.4.1 Release Notes 3694
7.1.8.2.28 MariaDB 10.4.0 Release Notes 3695
7.1.9 MariaDB Server 10.3 3696
7.1.9.1 Changes & Improvements in MariaDB 10.3 3697
7.1.9.2 Release Notes - MariaDB 10.3 Series 3702
7.1.9.2.1 MariaDB 10.3.37 Release Notes 3704
7.1.9.2.2 MariaDB 10.3.36 Release Notes 3705
7.1.9.2.3 MariaDB 10.3.35 Release Notes 3706
7.1.9.2.4 MariaDB 10.3.34 Release Notes 3708
7.1.9.2.5 MariaDB 10.3.33 Release Notes 3709
7.1.9.2.6 MariaDB 10.3.32 Release Notes 3710
7.1.9.2.7 MariaDB 10.3.31 Release Notes 3712
7.1.9.2.8 MariaDB 10.3.30 Release Notes 3713
7.1.9.2.9 MariaDB 10.3.29 Release Notes 3714
7.1.9.2.10 MariaDB 10.3.28 Release Notes 3715
7.1.9.2.11 MariaDB 10.3.27 Release Notes 3717
7.1.9.2.12 MariaDB 10.3.26 Release Notes 3718
7.1.9.2.13 MariaDB 10.3.25 Release Notes 3719
7.1.9.2.14 MariaDB 10.3.24 Release Notes 3720
7.1.9.2.15 MariaDB 10.3.23 Release Notes 3721
7.1.9.2.16 MariaDB 10.3.22 Release Notes 3723
7.1.9.2.17 MariaDB 10.3.21 Release Notes 3724
7.1.9.2.18 MariaDB 10.3.20 Release Notes 3726
7.1.9.2.19 MariaDB 10.3.19 Release Notes 3726
7.1.9.2.20 MariaDB 10.3.18 Release Notes 3728
7.1.9.2.21 MariaDB 10.3.17 Release Notes 3729
7.1.9.2.22 MariaDB 10.3.16 Release Notes 3730

43/3812
7.1.9.2.23 MariaDB 10.3.15 Release Notes 3731
7.1.9.2.24 MariaDB 10.3.14 Release Notes 3732
7.1.9.2.25 MariaDB 10.3.13 Release Notes 3733
7.1.9.2.26 MariaDB 10.3.12 Release Notes 3734
7.1.9.2.27 MariaDB 10.3.11 Release Notes 3735
7.1.9.2.28 MariaDB 10.3.10 Release Notes 3736
7.1.9.2.29 MariaDB 10.3.9 Release Notes 3737
7.1.9.2.30 MariaDB 10.3.8 Release Notes 3738
7.1.9.2.31 MariaDB 10.3.7 Release Notes 3739
7.1.9.2.32 MariaDB 10.3.6 Release Notes 3740
7.1.9.2.33 MariaDB 10.3.5 Release Notes 3741
7.1.9.2.34 MariaDB 10.3.4 Release Notes 3743
7.1.9.2.35 MariaDB 10.3.3 Release Notes 3743
7.1.9.2.36 MariaDB 10.3.2 Release Notes 3745
7.1.9.2.37 MariaDB 10.3.1 Release Notes 3746
7.1.9.2.38 MariaDB 10.3.0 Release Notes 3747
7.1.10 MariaDB Server 10.2 3749
7.1.10.1 Changes & Improvements in MariaDB 10.2 3749
7.1.11 MariaDB Server 10.1 3756
7.1.11.1 Changes & Improvements in MariaDB 10.1 3756
7.1.12 MariaDB Server 10.0 3762
7.1.12.1 Changes & Improvements in MariaDB 10.0 3762
7.1.13 MariaDB Server 5.5 3769
7.1.13.1 Changes & Improvements in MariaDB 5.5 3769
7.1.14 MariaDB Server 5.3 3777
7.1.14.1 Changes & Improvements in MariaDB 5.3 3777
7.1.15 MariaDB Server 5.2 3780
7.1.15.1 Changes & Improvements in MariaDB 5.2 3781
7.1.16 MariaDB Server 5.1 3782
7.1.16.1 Changes & Improvements in MariaDB 5.1 3782
Chapter 8 The Community 3785
8.1 Bug Tracking 3786
8.1.1 MariaDB Community Bug Reporting 3786
8.1.2 Reporting Documentation Bugs 3790
8.1.3 MariaDB Community Bug Processing 3792
8.1.4 MariaDB Security Bug Fixing Policy 3797
8.1.5 Building MariaDB Server for Debugging 3797
8.1.6 Extracting Entries from the Binary Log 3798
8.2 Contributing & Participating 3799
8.2.1 Getting Help With MariaDB 3800
8.2.2 Contributing to the MariaDB Project 3800
8.2.3 Contributing Code 3801
8.2.4 Donate to the Foundation 3804
8.2.5 Sponsoring the MariaDB Project 3804
8.2.6 Using Git with MariaDB 3804
8.2.6.1 MariaDB Source Code 3804
8.2.6.2 Using Git 3804
8.2.6.3 Configuring Git to Send Commit Notices 3808
8.3 Legal Matters 3809
8.3.1 GNU General Public License, Version 2 3809
8.3.2 Legal Notices for the Knowledge Base 3813

44/3812
1 Using MariaDB Server
Documentation on using MariaDB Server.
SQL Statements & Structure
SQL statements, structure, and rules.

Built-in Functions
Functions and procedures in MariaDB.

Clients & Utilities


Client and utility programs for MariaDB.

1.1 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).
SQL Statements
Explanations of all of the MariaDB SQL statements.

SQL Language Structure


Explanation of SQL grammar rules, including reserved words and literals.

Geographic & Geometric Features


Spatial extensions for geographic and geometric features.

NoSQL
NoSQL-related commands and interfaces

Operators
Operators for comparing and assigning values.

Sequences
Sequence objects, an alternative to AUTO_INCREMENT.

Temporal Tables
MariaDB supports system-versioning, application-time periods and bitemporal tables.

There are 11 related questions .

1.1.1 SQL Statements


Complete list of SQL statements for data definition, data manipulation, etc.
Account Management SQL Commands
CREATE/DROP USER, GRANT, REVOKE, SET PASSWORD etc.

Administrative SQL Statements


SQL statements for setting, flushing and displaying server variables and resources.

Data Definition
SQL commands for defining data, such as ALTER, CREATE, DROP, RENAME etc.

Data Manipulation
SQL commands for querying and manipulating data, such as SELECT, UPDATE, DELETE etc.

Prepared Statements
Prepared statements from any client using the text based prepared statement interface.

Programmatic & Compound Statements


Compound SQL statements for stored routines and in general.

Stored Routine Statements


SQL statements related to creating and using stored routines.
45/3812
Table Statements
Documentation on creating, altering, analyzing and maintaining tables.

Transactions
Sequence of statements that are either completely successful, or have no effect on any schemas

HELP Command
The HELP command will retrieve syntax and help within the mysql client.

Comment Syntax
Comment syntax and style.

Built-in Functions
Functions and procedures in MariaDB.

There are 17 related questions .

1.1.1.1 Account Management SQL Commands


CREATE/DROP USER, GRANT, REVOKE, SET PASSWORD etc.
CREATE USER
8 Create new MariaDB accounts.

ALTER USER
1 Modify an existing MariaDB account.

DROP USER
1 Remove one or more MariaDB accounts.

GRANT
2 Create accounts and set privileges or roles.

RENAME USER
Rename user account.

REVOKE
4 Remove privileges or roles.

SET PASSWORD
Assign password to an existing MariaDB user.

CREATE ROLE
Add new roles.

DROP ROLE
Drop a role.

SET ROLE
1 Enable a role.

SET DEFAULT ROLE


5 Sets a default role for a specified (or current) user.

SHOW GRANTS
9 View GRANT statements.

SHOW CREATE USER


Show the CREATE USER statement for a specified user.

There are 2 related questions .

46/3812
1.1.1.1.1 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
}

Contents
1. Syntax
2. Description
3. OR REPLACE
4. IF NOT EXISTS
5. Authentication Options
1. IDENTIFIED BY 'password'
2. IDENTIFIED BY PASSWORD
'password_hash'
3. IDENTIFIED {VIA|WITH}
authentication_plugin
6. TLS Options
7. Resource Limit Options
8. Account Names
1. Host Name Component
2. User Name Component
3. Anonymous Accounts
1. Fixing a Legacy Default Anonymous
Account
9. Password Expiry
10. Account Locking
11. See Also

Description
47/3812
The CREATE USER statement creates new MariaDB accounts. To use it, you must have the global CREATE USER
privilege or the INSERT privilege for the mysql database. For each account, CREATE USER creates a new row in
mysql.user (until MariaDB 10.3 this is a table, from MariaDB 10.4 it's a view) or mysql.global_priv_table (from MariaDB
10.4) 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, CREATE ROLE, and DROP ROLE all produce the same error code when they fail.
See 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 function prior to being stored in the
mysql.user/mysql.global_priv_table 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 that this clause supports are mysql_native_password and mysql_old_password.

IDENTIFIED BY PASSWORD 'password_hash'


48/3812
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 function. It will be
stored in the mysql.user/mysql.global_priv_table 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 that this clause supports are mysql_native_password and mysql_old_password.

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. The plugin name must be an active authentication plugin as per SHOW PLUGINS. If
it doesn't show up in that output, then you will need to install it with INSTALL PLUGIN or INSTALL SONAME.
For example, this could be used with the PAM authentication plugin:

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 accepts a service name:

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


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() function. This is only valid for authentication plugins that have implemented a hook for
the PASSWORD() function. For example, the ed25519 authentication plugin supports this:
CREATE USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret');

MariaDB starting with 10.4.3


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 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
49/3812
variables still use the prefix ssl_, but internally, MariaDB only supports its secure successors.
See Secure Connections Overview 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, ALTER USER, or GRANT statements. The
following options are available:

Option Description
REQUIRE
TLS is not required for this account, but can still be used.
NONE

REQUIRE The account must use TLS, but no valid X509 certificate is required. This option cannot be combined
SSL with other TLS options.
REQUIRE The account must use TLS and must have a valid X509 certificate. This option implies REQUIRE SSL .
X509 This option cannot be combined with other TLS options.
REQUIRE The account must use TLS and must have a valid X509 certificate. Also, the Certificate Authority must be
ISSUER the one specified via the string issuer . This option implies REQUIRE X509 . This option can be combined
'issuer' with the SUBJECT , and CIPHER options in any order.
REQUIRE The account must use TLS and must have a valid X509 certificate. Also, the certificate's Subject must be
SUBJECT the one specified via the string subject . This option implies REQUIRE X509 . This option can be
'subject' combined with the ISSUER , and CIPHER options in any order.
REQUIRE The account must use TLS, but no valid X509 certificate is required. Also, the encryption used for the
CIPHER connection must use a specific cipher method specified in the string cipher . This option implies
'cipher' 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/[email protected]'
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 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
Number of simultaneous connections that can be accepted from the same account; if it
MAX_USER_CONNECTIONS is 0, max_connections will be used instead; if max_connections is 0, there is no limit
for this account's simultaneous connections.
Timeout, in seconds, for statements executed by the user. See also Aborting
MAX_STATEMENT_TIME
Statements that Exceed a Certain Time to Execute.

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.

50/3812
The count can be reset for all users using FLUSH USER_RESOURCES, FLUSH PRIVILEGES or mysqladmin reload.
Per account resource limits are stored in the user table, in the mysql 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 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.
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, the host name component could be up to 60 characters in length. Starting from MariaDB 10.6, 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.
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:

51/3812
+---------+-------------+
| 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 table has some entries for the ''@'%' anonymous account by default. Unfortunately,
there is no matching entry in the mysql.user/mysql.global_priv_table table, which means that this anonymous account
doesn't exactly exist, but it does have privileges--usually on the default test database created by mysql_install_db.
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 the row in the mysql.db table and then execute FLUSH PRIVILEGES:

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 for more information.

Password Expiry
MariaDB starting with 10.4.3
Besides automatic password expiry, as determined by 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 for more details.

52/3812
Account Locking
MariaDB starting with 10.4.2
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 for more details.

From MariaDB 10.4.7 and MariaDB 10.5.8, the lock_option and password_option clauses can occur in either order.

See Also
Troubleshooting Connection Issues
Authentication from MariaDB 10.4
Identifier Names
GRANT
ALTER USER
DROP USER
SET PASSWORD
SHOW CREATE USER
mysql.user table
mysql.global_priv_table
Password Validation Plugins - permits the setting of basic criteria for passwords
Authentication Plugins - allow various authentication methods to be used, and new ones to be developed.

53/3812
1.1.1.1.2 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
}

Contents
1. Syntax
2. Description
3. IF EXISTS
4. Account Names
5. Authentication Options
1. IDENTIFIED BY 'password'
2. IDENTIFIED BY PASSWORD
'password_hash'
3. IDENTIFIED {VIA|WITH}
authentication_plugin
6. TLS Options
7. Resource Limit Options
8. Password Expiry
9. Account Locking
10. See Also

Description
The ALTER USER statement modifies existing MariaDB accounts. To use it, you must have the global CREATE USER
privilege or the UPDATE privilege for the mysql database. The global SUPER privilege is also required if the 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.

54/3812
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 statements. See account names from the CREATE USER page for details on how account names are
specified.
CURRENT_USER 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
From MariaDB 10.4, 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 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, see 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 function prior to being stored to the mysql.user 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 that this clause supports are mysql_native_password and mysql_old_password.

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#function. It will be
55/3812
stored to the mysql.user 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 that this clause supports are mysql_native_password and mysql_old_password.

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. The plugin name must be an active authentication plugin as per SHOW PLUGINS. If
it doesn't show up in that output, then you will need to install it with INSTALL PLUGIN or INSTALL SONAME.
For example, this could be used with the PAM authentication plugin:

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 accepts a service name:

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 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() function. This is only valid for authentication plugins that have
implemented a hook for the PASSWORD() function. For example, the ed25519 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 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, ALTER USER, or GRANT statements. The
following options are available:

Option Description
REQUIRE
TLS is not required for this account, but can still be used.
NONE

REQUIRE The account must use TLS, but no valid X509 certificate is required. This option cannot be combined
SSL with other TLS options.
56/3812
REQUIRE The account must use TLS and must have a valid X509 certificate. This option implies REQUIRE SSL .
X509 This option cannot be combined with other TLS options.
REQUIRE The account must use TLS and must have a valid X509 certificate. Also, the Certificate Authority must be
ISSUER the one specified via the string issuer . This option implies REQUIRE X509 . This option can be combined
'issuer' with the SUBJECT , and CIPHER options in any order.
REQUIRE The account must use TLS and must have a valid X509 certificate. Also, the certificate's Subject must be
SUBJECT the one specified via the string subject . This option implies REQUIRE X509 . This option can be
'subject' combined with the ISSUER , and CIPHER options in any order.
REQUIRE The account must use TLS, but no valid X509 certificate is required. Also, the encryption used for the
CIPHER connection must use a specific cipher method specified in the string cipher . This option implies
'cipher' 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/[email protected]'
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 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
Number of simultaneous connections that can be accepted from the same account; if it
MAX_USER_CONNECTIONS is 0, max_connections will be used instead; if max_connections is 0, there is no limit
for this account's simultaneous connections.
Timeout, in seconds, for statements executed by the user. See also Aborting
MAX_STATEMENT_TIME
Statements that Exceed a Certain Time to Execute.

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 PRIVILEGES or mysqladmin reload.
Per account resource limits are stored in the user table, in the mysql 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
Besides automatic password expiry, as determined by 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;

57/3812
See User Password Expiry for more details.

Account Locking
MariaDB starting with 10.4.2
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 for more details.

From MariaDB 10.4.7 and MariaDB 10.5.8, the lock_option and password_option clauses can occur in either order.

See Also
Authentication from MariaDB 10.4
GRANT
CREATE USER
DROP USER
SET PASSWORD
SHOW CREATE USER
mysql.user table
Password Validation Plugins - permits the setting of basic criteria for passwords
Authentication Plugins - allow various authentication methods to be used, and new ones to be developed.

1.1.1.1.3 DROP USER


Syntax
DROP USER [IF EXISTS] user_name [, user_name] ...

Contents
1. Syntax
2. Description
1. IF EXISTS
3. Examples
4. See Also

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 privilege or the DELETE 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.
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
58/3812
DROP USER bob;

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
ALTER USER
GRANT
SHOW CREATE USER
mysql.user table

59/3812
1.1.1.1.4 GRANT
Contents
1. Syntax
2. Description
1. Account Names
2. Implicit Account Creation
3. Privilege Levels
1. The USAGE Privilege
2. The ALL PRIVILEGES Privilege
3. The GRANT OPTION Privilege
4. Global Privileges
1. BINLOG ADMIN
2. BINLOG MONITOR
3. BINLOG REPLAY
4. CONNECTION ADMIN
5. CREATE USER
6. FEDERATED ADMIN
7. FILE
8. GRANT OPTION
9. PROCESS
10. READ_ONLY ADMIN
11. RELOAD
12. REPLICATION CLIENT
13. REPLICATION MASTER ADMIN
14. REPLICA MONITOR
15. REPLICATION REPLICA
16. REPLICATION SLAVE
17. REPLICATION SLAVE ADMIN
18. SET USER
19. SHOW DATABASES
20. SHUTDOWN
21. SUPER
5. Database Privileges
6. Table Privileges
7. Column Privileges
8. Function Privileges
9. Procedure Privileges
10. Proxy Privileges
4. Authentication Options
1. IDENTIFIED BY 'password'
2. IDENTIFIED BY PASSWORD 'password_hash'
3. IDENTIFIED {VIA|WITH} authentication_plugin
5. Resource Limit Options
6. TLS Options
7. Roles
1. Syntax
8. TO PUBLIC
1. Syntax
3. Grant Examples
1. Granting Root-like Privileges
4. See Also

Syntax

60/3812
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 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 statement to revoke privileges granted with the GRANT statement.
Use the SHOW GRANTS 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
61/3812
CREATE USER statements. See 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 is set, then accounts can only be created if authentication information is
specified, or with a CREATE USER 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 priv_type 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 prior to MariaDB 10.4, and in mysql.global_priv table afterwards.
Database privileges priv_type 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.
Table privileges priv_type 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 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 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 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 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


62/3812
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, 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, including the PURGE BINARY LOGS statement and setting the system
variables:
binlog_annotate_row_events
binlog_cache_size
binlog_commit_wait_count
binlog_commit_wait_usec
binlog_direct_non_transactional_updates
binlog_expire_logs_seconds
binlog_file_cache_size
binlog_format
binlog_row_image
binlog_row_metadata
binlog_stmt_cache_size
expire_logs_days
log_bin_compress
log_bin_compress_min_len
log_bin_trust_function_creators
max_binlog_cache_size
max_binlog_size
max_binlog_stmt_cache_size
sql_log_bin and
sync_binlog.
Added in MariaDB 10.5.2.

BINLOG MONITOR

New name for REPLICATION CLIENT from MariaDB 10.5.2, ( REPLICATION CLIENT still supported as an alias for
compatibility purposes). Permits running SHOW commands related to the binary log, in particular the SHOW BINLOG
STATUS and SHOW BINARY LOGS statements. Unlike REPLICATION CLIENT prior to MariaDB 10.5, SHOW
REPLICA STATUS isn't included in this privilege, and REPLICA MONITOR is required.

BINLOG REPLAY

Enables replaying the binary log with the BINLOG statement (generated by mariadb-binlog), executing SET timestamp
when 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_seq_no
pseudo_thread_id
server_id.
Added in MariaDB 10.5.2

CONNECTION ADMIN

Enables administering connection resource limit options. This includes ignoring the limits specified by:
max_connections
max_user_connections and
max_password_errors.
The statements specified in init_connect are not executed, killing connections and queries owned by other users is
permitted. The following connection-related system variables can be changed:
connect_timeout
63/3812
disconnect_on_expired_password
extra_max_connections
init_connect
max_connections
max_connect_errors
max_password_errors
proxy_protocol_networks
secure_auth
slow_launch_time
thread_pool_exact_stats
thread_pool_dedicated_listener
thread_pool_idle_timeout
thread_pool_max_threads
thread_pool_min_threads
thread_pool_oversubscribe
thread_pool_prio_kickup_timer
thread_pool_priority
thread_pool_size, and
thread_pool_stall_limit.
Added in MariaDB 10.5.2.

CREATE USER

Create a user using the CREATE USER statement, or implicitly create a user with the GRANT statement.

FEDERATED ADMIN

Execute CREATE SERVER, ALTER SERVER, and DROP SERVER statements. Added in MariaDB 10.5.2.

FILE
Read and write files on the server, using statements like LOAD DATA INFILE or functions like LOAD_FILE(). Also
needed to create CONNECT 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 or mysqladmin processlist. 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 system variable and allows the user to perform write operations, even when the read_only
option is active. Added in MariaDB 10.5.2.
From MariaDB 10.11.0, the 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.

RELOAD

Execute FLUSH statements or equivalent mariadb-admin/mysqladmin commands.

REPLICATION CLIENT

Execute SHOW MASTER STATUS and SHOW BINARY LOGS informative statements. Renamed to BINLOG
MONITOR in MariaDB 10.5.2 (but still supported as an alias for compatibility reasons). SHOW SLAVE STATUS was
part of REPLICATION CLIENT prior to MariaDB 10.5.

REPLICATION MASTER ADMIN


Permits administration of primary servers, including the SHOW REPLICA HOSTS statement, and setting the
gtid_binlog_state, gtid_domain_id, master_verify_checksum and server_id system variables. Added in MariaDB 10.5.2.

REPLICA MONITOR

Permit SHOW REPLICA STATUS and SHOW RELAYLOG EVENTS. From MariaDB 10.5.9.

64/3812
When a user would upgrade from an older major release to a MariaDB 10.5 minor release prior to MariaDB 10.5.9,
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, but after upgrading to a MariaDB 10.5 minor
release prior to MariaDB 10.5.9, they could no longer run SHOW REPLICA STATUS, because that statement was
changed to require the REPLICATION REPLICA ADMIN privilege.
This issue is fixed in MariaDB 10.5.9 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. From MariaDB 10.5.1.

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, REPLICATION REPLICA is an alias for REPLICATION SLAVE .

REPLICATION SLAVE ADMIN


Permits administering replica servers, including START REPLICA/SLAVE, STOP REPLICA/SLAVE, CHANGE MASTER,
SHOW REPLICA/SLAVE STATUS, SHOW RELAYLOG EVENTS statements, replaying the binary log with the BINLOG
statement (generated by mariadb-binlog), and setting the system variables:
gtid_cleanup_batch_size
gtid_ignore_duplicates
gtid_pos_auto_engines
gtid_slave_pos
gtid_strict_mode
init_slave
read_binlog_speed_limit
relay_log_purge
relay_log_recovery
replicate_do_db
replicate_do_table
replicate_events_marked_for_skip
replicate_ignore_db
replicate_ignore_table
replicate_wild_do_table
replicate_wild_ignore_table
slave_compressed_protocol
slave_ddl_exec_mode
slave_domain_parallel_threads
slave_exec_mode
slave_max_allowed_packet
slave_net_timeout
slave_parallel_max_queued
slave_parallel_mode
slave_parallel_threads
slave_parallel_workers
slave_run_triggers_for_rbr
slave_sql_verify_checksum
slave_transaction_retry_interval
slave_type_conversions
sync_master_info
sync_relay_log, and
sync_relay_log_info.
Added in MariaDB 10.5.2.

SET USER
Enables setting the DEFINER when creating triggers, views, stored functions and stored procedures. Added in MariaDB
10.5.2.

SHOW DATABASES

List all databases using the SHOW DATABASES statement. Without the SHOW DATABASES privilege, you can still issue
65/3812
the SHOW DATABASES statement, but it will only list databases containing tables on which you have privileges.

SHUTDOWN

Shut down the server using SHUTDOWN or the mysqladmin shutdown command.

SUPER

Execute superuser statements: CHANGE MASTER TO, KILL (users who do not have this privilege can only KILL their
own threads), PURGE LOGS, SET global system variables, or the mysqladmin debug command. Also, this permission
allows the user to write data even if the 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 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 to allow for more fine-grained
privileges, although it remains an alias for these smaller privileges.
From MariaDB 10.11.0, the 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.

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 a database using the CREATE DATABASE statement, when the privilege is granted for a
CREATE 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
Create Stored Programs using the CREATE PROCEDURE and CREATE FUNCTION statements.
ROUTINE

CREATE
Create temporary tables with the CREATE TEMPORARY TABLE statement. This privilege enable writing
TEMPORARY
and dropping those temporary tables
TABLES

Drop a database using the DROP DATABASE statement, when the privilege is granted for a database.
DROP
This also grants the DROP privilege on all tables in the database.
EVENT Create, drop and alter EVENT s.
GRANT
Grant database privileges. You can only grant privileges that you have.
OPTION

LOCK Acquire explicit locks using the LOCK TABLES statement; you also need to have the SELECT privilege on
TABLES a table, in order to lock it.

Table Privileges
Privilege Description
ALTER Change the structure of an existing table using the ALTER TABLE statement.
Create a table using the CREATE TABLE statement. You can grant the CREATE privilege on tables that
CREATE
do not yet exist.
CREATE
Create a view using the CREATE_VIEW statement.
VIEW

DELETE Remove rows from a table using the DELETE statement.


Remove historical rows from a table using the DELETE HISTORY statement. Displays as DELETE
VERSIONING ROWS when running SHOW GRANTS until MariaDB 10.3.15 and until MariaDB 10.4.5
DELETE (MDEV-17655 ), or when running SHOW PRIVILEGES until MariaDB 10.5.2, MariaDB 10.4.13 and
HISTORY MariaDB 10.3.23 (MDEV-20382 ). From MariaDB 10.3.4. From MariaDB 10.3.5, if a user has the
SUPER privilege but not this privilege, running mysql_upgrade will grant this privilege as well.

66/3812
Drop a table using the DROP TABLE statement or a view using the DROP VIEW statement. Also
DROP
required to execute the TRUNCATE TABLE statement.
GRANT
Grant table privileges. You can only grant privileges that you have.
OPTION

Create an index on a table using the CREATE INDEX statement. Without the INDEX privilege, you can
still create indexes when creating a table using the CREATE TABLE statement if the you have the
INDEX
CREATE privilege, and you can create indexes using the ALTER TABLE statement if you have the
ALTER privilege.

Add rows to a table using the INSERT statement. The INSERT privilege can also be set on individual
INSERT
columns; see Column Privileges below for details.
REFERENCES Unused.
Read data from a table using the SELECT statement. The SELECT privilege can also be set on
SELECT
individual columns; see Column Privileges below for details.
SHOW VIEW Show the CREATE VIEW statement to create a view using the SHOW CREATE VIEW statement.
Execute triggers associated to tables you update, execute the CREATE TRIGGER and DROP
TRIGGER
TRIGGER statements. You will still be able to see triggers.
Update existing rows in a table using the UPDATE statement. UPDATE statements usually include a
WHERE clause to update only certain rows. You must have SELECT privileges on the table or the
UPDATE
appropriate columns for the WHERE clause. The UPDATE privilege can also be set on individual
columns; see 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
Add rows specifying values in columns using the INSERT statement. If you only have column-level
INSERT
INSERT privileges, you must specify the columns you are setting in the INSERT statement. All other
(column_list)
columns will be set to their default values, or NULL .
REFERENCES
Unused.
(column_list)

Read values in columns using the SELECT statement. You cannot access or query any columns for
SELECT
which you do not have SELECT privileges, including in WHERE , ON , GROUP BY , and ORDER BY
(column_list)
clauses.
Update values in columns of existing rows using the UPDATE statement. UPDATE statements usually
UPDATE
include a WHERE clause to update only certain rows. You must have SELECT privileges on the table
(column_list)
or the appropriate columns for the WHERE clause.

Function Privileges
Privilege Description
ALTER
Change the characteristics of a stored function using the ALTER FUNCTION statement.
ROUTINE

Use a stored function. You need SELECT privileges for any tables or columns accessed by the
EXECUTE
function.
GRANT OPTION Grant function privileges. You can only grant privileges that you have.

Procedure Privileges
Privilege Description
ALTER
Change the characteristics of a stored procedure using the ALTER PROCEDURE statement.
ROUTINE

Execute a stored procedure using the CALL statement. The privilege to call a procedure may allow you to
EXECUTE
perform actions you wouldn't otherwise be able to do, such as insert rows into a table.

67/3812
GRANT
Grant procedure privileges. You can only grant privileges that you have.
OPTION

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() 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 does not support proxy users.
The pam 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 to enable user and group mapping with PAM.
For example, to grant the PROXY privilege to an anonymous account that authenticates with the pam 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 :

68/3812
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:

69/3812
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 mysql_install_db 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 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 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 statement to change a user's password with
GRANT .
The only authentication plugins that this clause supports are mysql_native_password and mysql_old_password.

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 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:


70/3812
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 statement to change a user's password with
GRANT .
The only authentication plugins that this clause supports are mysql_native_password and mysql_old_password.

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. The plugin name must be an active authentication plugin as per SHOW PLUGINS. If
it doesn't show up in that output, then you will need to install it with INSTALL PLUGIN or INSTALL SONAME.
For example, this could be used with the PAM authentication plugin:

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 accepts a service name:

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


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() function. This is only valid for authentication plugins that have implemented a hook for
the PASSWORD() function. For example, the ed25519 authentication plugin supports this:
CREATE USER safe@'%' IDENTIFIED VIA ed25519
USING PASSWORD('secret');

MariaDB starting with 10.4.3


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 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
Number of simultaneous connections that can be accepted from the same account; if it
MAX_USER_CONNECTIONS is 0, max_connections will be used instead; if max_connections is 0, there is no limit
for this account's simultaneous connections.
Timeout, in seconds, for statements executed by the user. See also Aborting
MAX_STATEMENT_TIME
Statements that Exceed a Certain Time to Execute.

If any of these limits are set to 0 , then there is no limit for that resource for that user.

71/3812
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 PRIVILEGES or mysqladmin reload.
Users with the CONNECTION ADMIN privilege (in MariaDB 10.5.2 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 table, in the mysql 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 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, ALTER USER, or GRANT statements. The
following options are available:

Option Description
REQUIRE
TLS is not required for this account, but can still be used.
NONE

REQUIRE The account must use TLS, but no valid X509 certificate is required. This option cannot be combined
SSL with other TLS options.
REQUIRE The account must use TLS and must have a valid X509 certificate. This option implies REQUIRE SSL .
X509 This option cannot be combined with other TLS options.
REQUIRE The account must use TLS and must have a valid X509 certificate. Also, the Certificate Authority must be
ISSUER the one specified via the string issuer . This option implies REQUIRE X509 . This option can be combined
'issuer' with the SUBJECT , and CIPHER options in any order.
REQUIRE The account must use TLS and must have a valid X509 certificate. Also, the certificate's Subject must be
SUBJECT the one specified via the string subject . This option implies REQUIRE X509 . This option can be
'subject' combined with the ISSUER , and CIPHER options in any order.
REQUIRE The account must use TLS, but no valid X509 certificate is required. Also, the encryption used for the
CIPHER connection must use a specific cipher method specified in the string cipher . This option implies
'cipher' 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/[email protected]'
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
72/3812
have to be configured to connect with TLS.
See Securing Connections for Client and Server 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 a role 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 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 statement.

TO PUBLIC
MariaDB starting with 10.11
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, a user will also see all privileges inherited from PUBLIC. SHOW GRANTS 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
--skip-grant-tables allows you to start MariaDB without GRANT . This is useful if you lost your root password.
CREATE USER
ALTER USER
DROP USER
SET PASSWORD
SHOW CREATE USER
mysql.global_priv table
mysql.user table
Password Validation Plugins - permits the setting of basic criteria for passwords
Authentication Plugins - allow various authentication methods to be used, and new ones to be developed.

73/3812
1.1.1.1.5 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 privilege or the UPDATE 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.
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.

Examples
CREATE USER 'donald', 'mickey';
RENAME USER 'donald' TO 'duck'@'localhost', 'mickey' TO 'mouse'@'localhost';

1.1.1.1.6 REVOKE
Contents
1. Privileges
1. Syntax
2. Description
3. Examples
2. Roles
1. Syntax
2. Description
3. Example

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) 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.
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 privilege or the UPDATE privilege for the mysql
74/3812
database. See GRANT.

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 from a user or another role that it's previously been assigned to. If a role has
previously been set as a default role, REVOKE does not remove the record of the default role from the mysql.user table.
If the role is subsequently granted again, it will again be the user's default. Use SET DEFAULT ROLE NONE to
explicitly remove this.
Before MariaDB 10.1.13 , the REVOKE role statement was not permitted in prepared statements.

Example
REVOKE journalist FROM hulda

1.1.1.1.7 SET PASSWORD


Syntax
SET PASSWORD [FOR user] =
{
PASSWORD('some password')
| OLD_PASSWORD('some password')
| 'encrypted password'
}

Contents
1. Syntax
2. Description
3. Authentication Plugin Support
4. Passwordless User Accounts
5. Example
6. See Also

Description
The SET PASSWORD statement assigns a password to an existing MariaDB user account.
If the password is specified using the PASSWORD() or OLD_PASSWORD() 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() .
OLD_PASSWORD() 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 table (or view in MariaDB-10.4 onwards) entry.

75/3812
The argument to PASSWORD() and the password given to MariaDB clients can be of arbitrary length.

Authentication Plugin Support


MariaDB starting with 10.4
In MariaDB 10.4 and later, SET PASSWORD (with or without PASSWORD() ) works for accounts authenticated via any
authentication plugin that supports passwords stored in the mysql.global_priv table.
The ed25519 , mysql_native_password , and mysql_old_password authentication plugins store passwords in the
mysql.global_priv 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 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 , named_pipe , gssapi , and pam authentication plugins do not store passwords in the
mysql.global_priv 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 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 for an overview of authentication changes in MariaDB 10.4.

MariaDB until 10.3


In MariaDB 10.3 and before, SET PASSWORD (with or without PASSWORD() ) only works for accounts authenticated via
mysql_native_password or mysql_old_password authentication plugins

Passwordless User Accounts


User accounts do not always require passwords to login.
The unix_socket , named_pipe and gssapi authentication plugins do not require a password to authenticate the
user.
The pam authentication plugin may or may not require a password to authenticate the user, depending on the specific
configuration.
The mysql_native_password and mysql_old_password 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


In MariaDB 10.4 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 - permits the setting of basic criteria for passwords
ALTER USER

76/3812
1.1.1.1.8 CREATE ROLE
Syntax
CREATE [OR REPLACE] ROLE [IF NOT EXISTS] role
[WITH ADMIN
{CURRENT_USER | CURRENT_ROLE | user | role}]

Contents
1. Syntax
2. Description
1. WITH ADMIN
2. OR REPLACE
3. IF NOT EXISTS
3. Examples
4. See Also

Description
The CREATE ROLE statement creates one or more MariaDB roles. To use it, you must have the global CREATE USER
privilege or the INSERT privilege for the mysql database. For each account, CREATE ROLE creates a new row in the
mysql.user 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 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 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 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.

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 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:

77/3812
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
Roles Overview
DROP ROLE

1.1.1.1.9 DROP ROLE


Syntax
DROP ROLE [IF EXISTS] role_name [,role_name ...]

Contents
1. Syntax
2. Description
1. IF EXISTS
3. Examples
4. See Also

Description
The DROP ROLE statement removes one or more MariaDB roles. To use this statement, you must have the global
CREATE USER privilege or the DELETE privilege for the mysql database.
DROP ROLE does not disable roles for connections which selected them with SET ROLE. If a role has previously been
set as a default role, DROP ROLE does not remove the record of the default role from the mysql.user table. If the role is
subsequently recreated and granted, it will again be the user's default. Use SET DEFAULT ROLE NONE 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:
78/3812
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
CREATE ROLE

1.1.1.1.10 SET ROLE


Syntax
SET ROLE { role | NONE }

Contents
1. Syntax
2. Description
3. Example

Description
The SET ROLE statement enables a role, 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.

Example

79/3812
SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL |
+--------------+

SET ROLE staff;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| staff |
+--------------+

SET ROLE NONE;

SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| NULL |
+----------------+

1.1.1.1.11 SET DEFAULT ROLE


Contents
1. Syntax
2. Description
3. Examples

Syntax
SET DEFAULT ROLE { role | NONE } [ FOR user@host ]

Description
The SET DEFAULT ROLE statement sets a default role for a specified (or current) user. A default role is automatically
enabled when a user connects (an implicit SET ROLE 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 or revoked, 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 table/view, as well as in the Information
Schema APPLICABLE_ROLES table, 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:

80/3812
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;

1.1.1.1.12 SHOW GRANTS


Contents
1. Syntax
2. Description
1. Users
2. Roles
1. Example
3. FOR PUBLIC
3. See Also

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 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.

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.
81/3812
Note that the DELETE HISTORY privilege, introduced in MariaDB 10.3.4, was displayed as DELETE VERSIONING ROWS
when running SHOW GRANTS until MariaDB 10.3.15 (MDEV-17655 ).

Roles
SHOW GRANTS can also be used to view the privileges granted to a role.

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
GRANT ... TO PUBLIC was introduced in MariaDB 10.11 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
SHOW CREATE USER shows how the user was created.
SHOW PRIVILEGES shows the privileges supported by MariaDB.
Roles

1.1.1.1.13 SHOW CREATE USER


Syntax
SHOW CREATE USER user_name

Description
Shows the CREATE USER statement that created the given user. The statement requires the SELECT privilege for the
mysql 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:

82/3812
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
ALTER USER
SHOW GRANTS shows the GRANTS/PRIVILEGES for a user.
SHOW PRIVILEGES shows the privileges supported by MariaDB.

1.1.1.2 Administrative SQL Statements


SQL statements for administering MariaDB.
Table Statements
Documentation on creating, altering, analyzing and maintaining tables.

ANALYZE and EXPLAIN Statements


Articles on the ANALYZE and EXPLAIN statements

BACKUP Commands
Commands used by backup tools.

FLUSH Commands
Commands to flush or reset various caches in MariaDB.

Replication Commands
List of replication-related commands.

Plugin SQL Statements


List of SQL statements related to plugins.

SET Commands
The SET commands

SHOW
Articles on the various SHOW commands.

System Tables

BINLOG
Generated by mysqlbinlog

PURGE BINARY LOGS


PURGE BINARY LOGS removes all binary logs from the server, prior to the provided date or log file.

CACHE INDEX
Caches MyISAM or Aria indexes

DESCRIBE
Information about columns in a table.

EXECUTE Statement
Executes a previously PREPAREd statement

HELP Command
The HELP command will retrieve syntax and help within the mysql client.

KILL [CONNECTION | QUERY]


Kill connection by query or thread id.

83/3812
LOAD INDEX
Loads one or more indexes from one or more MyISAM/Aria tables into a key buffer.

RESET
1 Overall description of the different RESET commands

SHUTDOWN
Shuts down the server.

USE
1 Set the current default database.

There are 1 related questions .

1.1.1.2.1 Table Statements


Articles about creating, modifying, and maintaining tables in MariaDB.
ALTER
The various ALTER statements in MariaDB.

ANALYZE TABLE
3 Store key distributions for a table.

CHECK TABLE
1 Check table for errors.

CHECK VIEW
Check whether the view algorithm is correct.

CHECKSUM TABLE
1 Report a table checksum.

CREATE TABLE
7 Creates a new table.

DELETE
2 Delete rows from one or more tables.

DROP TABLE
Removes definition and data from one or more tables.

Installing System Tables (mysql_install_db)


Using mysql_install_db to create the system tables in the 'mysql' database directory.

mysqlcheck
Tool for checking, repairing, analyzing and optimizing tables.

mysql_upgrade
2 Update to the latest version.

OPTIMIZE TABLE
4 Reclaim unused space and defragment data.

RENAME TABLE
1 Change a table's name.

REPAIR TABLE
Repairs a table, if the storage engine supports this statement.

REPAIR VIEW
Fix view if the algorithms are swapped.

REPLACE
1 Equivalent to DELETE + INSERT, or just an INSERT if no rows are returned.

84/3812
SHOW COLUMNS
Column information.

SHOW CREATE TABLE


Shows the CREATE TABLE statement that created the table.

SHOW INDEX
Information about table indexes.

TRUNCATE TABLE
DROP and re-CREATE a table.

UPDATE
2 Modify rows in one or more tables.

Obsolete Table Commands


Table commands that have been removed from MariaDB

IGNORE
Suppress errors while trying to violate a UNIQUE constraint.

System-Versioned Tables
26 System-versioned tables record the history of all changes to table data.

There are 1 related questions .

1.1.1.2.1.1 ALTER
This category is for documentation on the various ALTER statements.
ALTER TABLE
5 Modify a table's definition.

ALTER DATABASE
Change the overall characteristics of a database.

ALTER EVENT
Change an existing event.

ALTER FUNCTION
Change the characteristics of a stored function.

ALTER LOGFILE GROUP


Only useful with MySQL Cluster, and has no effect in MariaDB.

ALTER PROCEDURE
1 Change stored procedure characteristics.

ALTER SEQUENCE
Change options for a SEQUENCE.

ALTER SERVER
Updates mysql.servers table.

ALTER TABLESPACE
ALTER TABLESPACE is not available in MariaDB.

ALTER USER
1 Modify an existing MariaDB account.

ALTER VIEW
2 Change a view definition.

There are 1 related questions .

85/3812
1.1.1.2.1.1.1 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
| 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:
86/3812
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] ...

87/3812
Contents
1. Syntax
2. Description
3. Privileges
4. Online DDL
1. ALTER ONLINE TABLE
5. WAIT/NOWAIT
6. IF EXISTS
7. Column Definitions
8. Index Definitions
9. Character Sets and Collations
10. Alter Specifications
1. Table Options
2. ADD COLUMN
3. DROP COLUMN
4. MODIFY COLUMN
5. CHANGE COLUMN
6. ALTER COLUMN
7. RENAME INDEX/KEY
8. RENAME COLUMN
9. ADD PRIMARY KEY
10. DROP PRIMARY KEY
11. ADD FOREIGN KEY
12. DROP FOREIGN KEY
13. ADD INDEX
14. DROP INDEX
15. ADD UNIQUE INDEX
16. DROP UNIQUE INDEX
17. ADD FULLTEXT INDEX
18. DROP FULLTEXT INDEX
19. ADD SPATIAL INDEX
20. DROP SPATIAL INDEX
21. ENABLE/ DISABLE KEYS
22. RENAME TO
23. ADD CONSTRAINT
24. DROP CONSTRAINT
25. ADD SYSTEM VERSIONING
26. DROP SYSTEM VERSIONING
27. ADD PERIOD FOR SYSTEM_TIME
28. FORCE
29. EXCHANGE PARTITION
30. DISCARD TABLESPACE
31. IMPORT TABLESPACE
32. ALGORITHM
1. ALGORITHM=DEFAULT
2. ALGORITHM=COPY
3. ALGORITHM=INPLACE
4. ALGORITHM=NOCOPY
5. ALGORITHM=INSTANT
33. LOCK
11. Progress Reporting
12. Aborting ALTER TABLE Operations
13. Atomic ALTER TABLE
14. Replication
15. Examples
16. See Also

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 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 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
88/3812
statements.
This statement can also be used to rename a table. For details see RENAME TABLE.
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 and MyISAM allocate a buffer whose size is defined by aria_sort_buffer_size or
myisam_sort_buffer_size, also used for REPAIR TABLE. InnoDB allocates three buffers whose size is defined by
innodb_sort_buffer_size.

Privileges
Executing the ALTER TABLE statement generally requires at least the ALTER privilege for the table or the database..
If you are renaming a table, then it also requires the DROP, CREATE and INSERT privileges for the table or the
database as well.

Online DDL
Online DDL is supported with the ALGORITHM and LOCK clauses.
See InnoDB Online DDL Overview for more information on online DDL with InnoDB.

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 alter specification for more information.


This statement is equivalent to the following:

ALTER TABLE ... ALGORITHM=INPLACE;

See the ALGORITHM alter specification for more information.

WAIT/NOWAIT
MariaDB starting with 10.3.0
Set the lock wait timeout. See WAIT and NOWAIT.

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
89/3812
the statement (or end if finished).

MariaDB starting with 10.5.2


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 for information about column definitions.

Index Definitions
See CREATE TABLE: Index Definitions for information about index definitions.
The CREATE INDEX and DROP 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 for details on setting the character sets and collations.

Alter Specifications
Table Options
See CREATE TABLE: 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. 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.

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.

MariaDB starting with 10.2.8


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

90/3812
order to drop the column, an explicit DROP PRIMARY KEY and ADD PRIMARY KEY would be required. Up until MariaDB
10.2.7 , 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


MariaDB 10.4.0 supports instant DROP COLUMN. DROP COLUMN of an indexed column would imply DROP INDEX
(and in the case of a non-UNIQUE multi-column index, possibly ADD INDEX). These will not be allowed with
ALGORITHM=INSTANT, but unlike before, they can be allowed with ALGORITHM=NOCOPY

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
From MariaDB 10.5.2, 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
From MariaDB 10.5.2, 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.

91/3812
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 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 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 for more information.

DROP FOREIGN KEY


Drop a foreign key.
See Foreign Keys 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 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 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.
92/3812
See Getting Started with Indexes: 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 for more information.

ADD FULLTEXT INDEX


Add a FULLTEXT index.
See Full-Text Indexes for more information.

DROP FULLTEXT INDEX


Drop a FULLTEXT index.
See Full-Text Indexes for more information.

ADD SPATIAL INDEX


Add a SPATIAL index.
See SPATIAL INDEX for more information.

DROP SPATIAL INDEX


Drop a SPATIAL index.
See SPATIAL 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 into empty tables.
ENABLE KEYS will enable all disabled keys.

RENAME TO
Renames the table. See also RENAME TABLE.

ADD CONSTRAINT
Modifies the table adding a constraint on a particular column or columns.

MariaDB starting with 10.2.1


MariaDB 10.2.1 introduced new ways to define a constraint.

Note: Before MariaDB 10.2.1 , constraint expressions were accepted in syntax, but ignored.

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.

93/3812
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 clause.
You can disable all constraint expression checks by setting the variable 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:

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
MariaDB starting with 10.2.22
DROP CONSTRAINT for UNIQUE and FOREIGN KEY constraints was introduced in MariaDB 10.2.22 and MariaDB
10.3.13.

MariaDB starting with 10.2.1


DROP CONSTRAINT for CHECK constraints was introduced in MariaDB 10.2.1

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 or ALTER TABLE...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. 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


94/3812
MariaDB starting with 10.3.4
System-versioned tables was added in MariaDB 10.3.4.

Add system versioning.

DROP SYSTEM VERSIONING


MariaDB starting with 10.3.4
System-versioned tables was added in MariaDB 10.3.4.

Drop system versioning.

ADD PERIOD FOR SYSTEM_TIME


MariaDB starting with 10.3.4
System-versioned tables was added in MariaDB 10.3.4.

FORCE
ALTER TABLE ... FORCE can force MariaDB to re-build the table.

In MariaDB 5.5 and before, this could only be done by setting the 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 system variable is set to ON . 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.

EXCHANGE PARTITION
This is used to exchange the tablespace files between a partition and another table.
See copying InnoDB's transportable tablespaces for more information.

DISCARD TABLESPACE
This is used to discard an InnoDB table's tablespace.
See copying InnoDB's 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.
See copying InnoDB's 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

95/3812
ALGORITHM=INPLACE
ALGORITHM=NOCOPY - This was added in MariaDB 10.3.7.
ALGORITHM=INSTANT - This was added in MariaDB 10.3.7.
See InnoDB Online DDL Overview: 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 and before, if the value of the 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 and later, the old_alter_table system variable is deprecated. Instead, the alter_algorithm system
variable defines the default algorithm for ALTER TABLE operations.

ALGORITHM=COPY
ALGORITHM=COPY is the name for the original ALTER TABLE 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 operations are required that each require the table to be rebuilt, then it is
best to specify all operations in a single ALTER TABLE 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 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 for more.

ALGORITHM=NOCOPY
ALGORITHM=NOCOPY was introduced in MariaDB 10.3.7.
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.

96/3812
See InnoDB Online DDL Operations with ALGORITHM=NOCOPY for more.

ALGORITHM=INSTANT
ALGORITHM=INSTANT was introduced in MariaDB 10.3.7.
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 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 is equivalent to LOCK=NONE . Therefore, the ALTER ONLINE TABLE statement can be used to
ensure that your ALTER TABLE operation allows all concurrent DML.
See InnoDB Online DDL Overview: 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 mysql 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 statement and in the contents of the
information_schema.PROCESSLIST table.
See Progress Reporting 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.

MariaDB starting with 10.2.13


Aborting ALTER TABLE ... ALGORITHM=COPY was made faster by removing excessive undo logging (MDEV-11415 ).
This significantly shortens the time it takes to abort a running ALTER TABLE operation.

Atomic ALTER TABLE


MariaDB starting with 10.6.1
From MariaDB 10.6, ALTER TABLE is atomic for most engines, including InnoDB, MyRocks, MyISAM and Aria (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.
97/3812
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 for more information.

Replication
MariaDB starting with 10.8.0
Before MariaDB 10.8.0, ALTER TABLE got fully executed on the primary first, and only then was it replicated and
started executing on replicas. From MariaDB 10.8.0, ALTER TABLE gets replicated and starts executing on replicas
when it 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 ).

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, adding a primary key for an application-time period table with a WITHOUT OVERLAPS
constraint:

ALTER TABLE rooms ADD PRIMARY KEY(room_number, p WITHOUT OVERLAPS);

See Also
CREATE TABLE
DROP TABLE
Character Sets and Collations
SHOW CREATE TABLE
Instant ADD COLUMN for InnoDB
98/3812
1.1.1.2.1.1.2 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'

Contents
1. Syntax
2. Description
1. COMMENT
3. Examples
4. See Also

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 for more.
You can see what character sets and collations are available using, respectively, the SHOW CHARACTER SET and
SHOW COLLATION statements.
Changing the default character set/collation of a database does not change the character set/collation of any stored
procedures or stored functions 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). 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 mysqlcheck (as invoked by mysql_upgrade ).
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


From MariaDB 10.5.0, 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.

99/3812
Examples
ALTER DATABASE test CHARACTER SET='utf8' COLLATE='utf8_bin';

From MariaDB 10.5.0:

ALTER DATABASE p COMMENT='Presentations';

See Also
CREATE DATABASE
DROP DATABASE
SHOW CREATE DATABASE
SHOW DATABASES
Character Sets and Collations
Information Schema SCHEMATA Table

1.1.1.2.1.1.3 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]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The ALTER EVENT statement is used to change one or more of the characteristics of an existing event 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.
This statement requires the EVENT 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 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
CREATE EVENT
100/3812
SHOW CREATE EVENT
DROP EVENT

1.1.1.2.1.1.4 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'

Contents
1. Syntax
2. Description
3. Example
4. See Also

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 and CREATE
FUNCTION.
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.

Example
ALTER FUNCTION hello SQL SECURITY INVOKER;

See Also
CREATE FUNCTION
SHOW CREATE FUNCTION
DROP FUNCTION
SHOW FUNCTION STATUS
Information Schema ROUTINES Table

1.1.1.2.1.1.5 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 for more information.

1.1.1.2.1.1.6 ALTER PROCEDURE


Syntax
101/3812
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. 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 (since MariaDB 10.1.3 ) or DROP PROCEDURE and CREATE PROCEDURE
(MariaDB 10.1.2 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.

Example
ALTER PROCEDURE simpleproc SQL SECURITY INVOKER;

See Also
Stored Procedure Overview
CREATE PROCEDURE
SHOW CREATE PROCEDURE
DROP PROCEDURE
SHOW CREATE PROCEDURE
SHOW PROCEDURE STATUS
Stored Routine Privileges
Information Schema ROUTINES Table

1.1.1.2.1.1.7 ALTER SEQUENCE


1.1.1.2.1.1.8 ALTER SERVER
Syntax
ALTER SERVER server_name
OPTIONS (option [, option] ...)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Alters the server information for server_name, adjusting the specified options as per the CREATE SERVER command.
The corresponding fields in the mysql.servers table are updated accordingly. This statement requires the SUPER
privilege or, from MariaDB 10.5.2, the FEDERATED ADMIN privilege.
ALTER SERVER is not written to the binary log, irrespective of the binary log format being used. From MariaDB 10.1.13
, Galera replicates the CREATE SERVER, ALTER SERVER and DROP SERVER statements.

Examples
ALTER SERVER s OPTIONS (USER 'sally');

102/3812
See Also
CREATE SERVER
DROP SERVER
Spider Storage Engine

1.1.1.2.1.1.9 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 for more information.

1.1.1.2.1.1.10 ALTER USER


1.1.1.2.1.1.11 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]

Contents
1. Syntax
2. Description
3. Example
4. See Also

Description
This statement changes the definition of a view, which must exist. The syntax is similar to that for CREATE VIEW 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 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 privilege.

Example
ALTER VIEW v AS SELECT a, a*3 AS a2 FROM t;

See Also
CREATE VIEW
DROP VIEW
SHOW CREATE VIEW
INFORMATION SCHEMA VIEWS Table

1.1.1.2.1.2 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 ...]])]]

103/3812
Contents
1. Syntax
2. Description
3. Engine-Independent Statistics
4. See Also

Description
ANALYZE TABLE analyzes and stores the key distribution for a table (index statistics). This statement works with
MyISAM, Aria and InnoDB 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.
For more information on how the analysis works within InnoDB, see InnoDB Limitations.
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 for the table.
By default, ANALYZE TABLE statements are written to the binary log and will be replicated. 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, ANALYZE TABLE statements are not logged to the binary log if read_only is set. See also Read-
Only Replicas.
ANALYZE TABLE is also supported for partitioned tables. You can use ALTER TABLE ... ANALYZE PARTITION to analyze
one or more partitions.
The Aria storage engine supports progress reporting for the ANALYZE TABLE statement.

Engine-Independent Statistics
ANALYZE TABLE supports engine-independent statistics. See Engine-Independent Table Statistics: Collecting Statistics
with the ANALYZE TABLE Statement for more information.

See Also
Index Statistics
InnoDB Persistent Statistics
Progress Reporting
Engine-independent Statistics
Histogram-based Statistics
ANALYZE Statement

1.1.1.2.1.3 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, Aria, CSV, InnoDB, and MyISAM
tables. For Aria and MyISAM tables, the key statistics are updated as well. For CSV, see also Checking and Repairing
CSV Tables.
As an alternative, myisamchk is a commandline tool for checking MyISAM tables when the tables are not being
accessed.
For checking dynamic columns integrity, 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 ... 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:
104/3812
Do a very quick check if the storage format for the table has changed so that one needs to do a
FOR
REPAIR. This is only needed when one upgrades between major versions of MariaDB or MySQL. This
UPGRADE
is usually done by running mysql_upgrade .
Only check tables that has not been closed properly or are marked as corrupt. Only supported by the
FAST
MyISAM and Aria engines. For other engines the table is checked normally
Check only tables that has changed since last REPAIR / CHECK. Only supported by the MyISAM and
CHANGED
Aria engines. For other engines the table is checked normally.
Do a fast check. For MyISAM and Aria engine this means we skip checking the delete link chain which
QUICK
may take some time.
Scan also the data files. Checks integrity between data and index files with checksums. In most cases
MEDIUM
this should find all possible errors.
Does a full check to verify every possible error. For MyISAM and Aria we verify for each row that all it
EXTENDED
keys exists and points to the row. This may take a long time on big tables!

For most cases running CHECK TABLE without options or MEDIUM should be good enough.
The Aria storage engine supports progress reporting for this statement.
If you want to know if two tables are identical, take a look at CHECKSUM TABLE.

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.

1.1.1.2.1.4 CHECK VIEW


Syntax
CHECK VIEW view_name

Description
The CHECK VIEW statement was introduced in MariaDB 10.0.18 to assist with fixing MDEV-6916 , an issue
introduced in MariaDB 5.2 where the view algorithms were swapped. It checks whether the view algorithm is correct.
It is run as part of mysql_upgrade, and should not normally be required in regular use.

See Also
REPAIR VIEW

1.1.1.2.1.5 CHECKSUM TABLE


Syntax
CHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ]

Contents
1. Syntax
2. Description
3. Differences Between MariaDB and
MySQL

Description
105/3812
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; currently, this is supported only for
Aria and MyISAM 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 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.

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.

106/3812
1.1.1.2.1.6 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)

Contents
1. Syntax
2. Description
3. Privileges
4. CREATE OR REPLACE
1. Things to be Aware of With CREATE
OR REPLACE
5. CREATE TABLE IF NOT EXISTS
6. CREATE TEMPORARY TABLE
7. CREATE TABLE ... LIKE
8. CREATE TABLE ... SELECT
9. Column Definitions
1. NULL and NOT NULL
2. DEFAULT Column Option
3. AUTO_INCREMENT Column Option
4. ZEROFILL Column Option
5. PRIMARY KEY Column Option
6. UNIQUE KEY Column Option
7. COMMENT Column Option
8. REF_SYSTEM_ID
9. Generated Columns
10. COMPRESSED
11. INVISIBLE
12. WITH SYSTEM VERSIONING Column
Option
13. WITHOUT SYSTEM VERSIONING
Column Option
10. Index Definitions
1. Index Categories
1. Plain Indexes
2. PRIMARY KEY
3. UNIQUE
4. FOREIGN KEY
5. FULLTEXT
6. SPATIAL
2. Index Options
1. KEY_BLOCK_SIZE Index Option
2. Index Types
3. WITH PARSER Index Option
4. COMMENT Index Option
5. CLUSTERING Index Option
6. IGNORED / NOT IGNORED
11. Periods
12. Constraint Expressions
13. Table Options
1. [STORAGE] ENGINE
2. AUTO_INCREMENT
3. AVG_ROW_LENGTH
4. [DEFAULT] CHARACTER
SET/CHARSET
5. CHECKSUM/TABLE_CHECKSUM
6. [DEFAULT] COLLATE
7. COMMENT
8. CONNECTION
107/3812
9. DATA DIRECTORY/INDEX
DIRECTORY
10. DELAY_KEY_WRITE
11. ENCRYPTED
12. ENCRYPTION_KEY_ID
13. IETF_QUOTES
14. INSERT_METHOD
15. KEY_BLOCK_SIZE
16. MIN_ROWS/MAX_ROWS
17. PACK_KEYS
18. PAGE_CHECKSUM
19. PAGE_COMPRESSED
20. PAGE_COMPRESSION_LEVEL
21. PASSWORD
22. RAID_TYPE
23. ROW_FORMAT
1. Supported MyISAM Row Formats
2. Supported Aria Row Formats
3. Supported InnoDB Row Formats
4. Other Storage Engines and
ROW_FORMAT
24. SEQUENCE
25. STATS_AUTO_RECALC
26. STATS_PERSISTENT
27. STATS_SAMPLE_PAGES
28. TRANSACTIONAL
29. UNION
30. WITH SYSTEM VERSIONING
14. Partitions
15. Sequences
16. Atomic DDL
17. Examples
18. See Also

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, because it allows to create a table into a database, which
contains data from other databases. See Identifier Qualifiers.
If a table with the same name exists, error 1050 results. Use IF NOT EXISTS to suppress this error and issue a note
instead. Use SHOW WARNINGS to see notes.
The CREATE TABLE statement automatically commits the current transaction, except when using the TEMPORARY
keyword.
For valid identifiers to use as table names, see Identifier Names.

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 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 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 more robust if it has to rollback and repeat statements such as
CREATE ... SELECT on replicas.

108/3812
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 it will continue to be locked after the statement.
Temporary tables are only dropped if the TEMPORARY keyword was used. (With DROP TABLE, 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 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 privilege on the database to create temporary tables. If no storage
engine is specified, the default_tmp_storage_engine setting will determine the engine.
ROCKSDB temporary tables cannot be created by setting the default_tmp_storage_engine system variable, or using
CREATE TEMPORARY TABLE LIKE . Before MariaDB 10.7, they could be specified, but would silently fail, and a MyISAM
table would be created instead. From MariaDB 10.7 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() 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.

109/3812
If the new table has a primary key or UNIQUE indexes, you can use the IGNORE 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 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 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, 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 this was also true for CHECK constraints. However, only the syntax described below creates
foreign keys.
From MariaDB 10.5, MariaDB will attempt to apply the constraint. See Foreign Keys examples.

Each definition either creates a column in the table or specifies and index or constraint on one or more columns. See
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
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.

DEFAULT Column Option


MariaDB starting with 10.2.1
The DEFAULT clause was enhanced in MariaDB 10.2.1 . Some enhancements include
BLOB and TEXT columns now support DEFAULT .
The DEFAULT clause can now be used with an expression or function.

Specify a default value using the DEFAULT clause. If you don't specify DEFAULT then the following rules apply:

110/3812
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 a row without specifying a value for that column, or if you specify
DEFAULT for that column. Before MariaDB 10.2.1 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 as the default value for a TIMESTAMP column to use the current timestamp at insertion time.
CURRENT_TIMESTAMP may also be used as the default value for a DATETIME
From MariaDB 10.2.1 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 in row mode. 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 or subqueries, and a column used in the clause must already
have been defined earlier in the statement.
Since MariaDB 10.2.1 , it is possible to assign BLOB or TEXT columns a DEFAULT value. In earlier versions, assigning
a default to these columns was not possible.

MariaDB starting with 10.3.3


Starting from 10.3.3 you can also use DEFAULT (NEXT VALUE FOR sequence)

AUTO_INCREMENT Column Option


Use AUTO_INCREMENT 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 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
to get the AUTO_INCREMENT value most recently used by an INSERT statement.

ZEROFILL Column Option


If the ZEROFILL column option is specified for a column using a numeric 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. 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 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 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 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.

Generated Columns
111/3812
A generated column is a column in a table that cannot explicitly be set to a specific value in a DML query. 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 or user-defined functions
(UDFs).
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.

COMPRESSED
MariaDB starting with 10.3.3
Certain columns may be compressed. See Storage-Engine Independent Column Compression.

INVISIBLE
MariaDB starting with 10.3.3
Columns may be made invisible, and hidden in certain contexts. See Invisible Columns.

WITH SYSTEM VERSIONING Column Option


MariaDB starting with 10.3.4
Columns may be explicitly marked as included from system versioning. See System-versioned tables for details.

WITHOUT SYSTEM VERSIONING Column Option


MariaDB starting with 10.3.4
Columns may be explicitly marked as excluded from system versioning. See System-versioned tables for details.

Index Definitions

112/3812
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 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 and MariaDB 10.4.8, a warning is explicitly issued if a name is specified. Before then,
the name was silently ignored.
See Getting Started with Indexes: 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.
See Getting Started with Indexes: 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:
113/3812
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 for more information.

FULLTEXT
Use the FULLTEXT keyword to create full-text indexes.
See Full-Text Indexes for more information.

SPATIAL
Use the SPATIAL keyword to create geometric indexes.
See SPATIAL INDEX for more information.

Index Options
KEY_BLOCK_SIZE Index Option
The KEY_BLOCK_SIZE index option is similar to the KEY_BLOCK_SIZE table option.
With the InnoDB 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 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
storage engine ignores the KEY_BLOCK_SIZE index option. However, the SHOW CREATE TABLE statement may still
report it for the index.
For information about the KEY_BLOCK_SIZE index option, see the KEY_BLOCK_SIZE table option below.

Index Types
Each storage engine supports some or all index types. See Storage Engine Index Types 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 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 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 storage engine.

IGNORED / NOT IGNORED


114/3812
MariaDB starting with 10.6.0
From MariaDB 10.6.0, indexes can be specified to be ignored by the optimizer. See Ignored Indexes.

Periods
MariaDB starting with 10.3.4

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. 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 for details.
The table must also have the WITH SYSTEM VERSIONING clause.

Constraint Expressions
MariaDB starting with 10.2.1
MariaDB 10.2.1 introduced new ways to define a constraint.

Note: Before MariaDB 10.2.1 , constraint expressions were accepted in the syntax but ignored.
MariaDB 10.2.1 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.

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.
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 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.

If the IGNORE_BAD_TABLE_OPTIONS SQL_MODE is enabled, wrong table options generate a warning; otherwise, they
generate an error.

115/3812
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 for the table. If this option is not used, the default storage engine is used
instead. That is, the default_storage_engine session option value if it is set, or the value specified for the --default-
storage-engine mysqld startup option, or the default storage engine, InnoDB. If the specified storage engine is not
installed and active, the default value will be used, unless the NO_ENGINE_SUBSTITUTION SQL MODE 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.

AUTO_INCREMENT
AUTO_INCREMENT specifies the initial value for the AUTO_INCREMENT 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 and Aria storage engines that have
the 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 for details on setting
the character sets.

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

116/3812
operations slower, but CHECKSUM TABLE will be very fast. This option is only supported for MyISAM and Aria tables.

[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 for details on setting the collations

COMMENT
COMMENT is a comment for the table. The maximum length is 2048 characters. Also used to define table parameters
when creating a Spider table.

CONNECTION
CONNECTION is used to specify a server name or a connection string for a Spider, CONNECT, Federated or FederatedX
table.

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 server system variable is enabled, but only in CREATE TABLE, not in ALTER
TABLE. 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 tables (use the partition options instead), or if the server has been invoked with the --skip-symbolic-
links startup option. 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 (an error will be issued if files already exist). These options are ignored if
the NO_DIR_IN_CREATE SQL_MODE 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) 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 table. See InnoDB
Encryption for more information.
Aria does not support the ENCRYPTED table option. See MDEV-18049 .
See Data-at-Rest Encryption for more information.

ENCRYPTION_KEY_ID
The ENCRYPTION_KEY_ID table option can be used to manually set the encryption key of an InnoDB table. See InnoDB
Encryption for more information.
Aria does not support the ENCRYPTION_KEY_ID table option. See MDEV-18049 .
See Data-at-Rest Encryption for more information.

IETF_QUOTES
For the CSV 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
117/3812
INSERT_METHOD is only used with MERGE 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 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 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 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 for InnoDB tables.

PAGE_COMPRESSION_LEVEL
PAGE_COMPRESSION_LEVEL is used to set the compression level for InnoDB page compression for InnoDB tables. The
table must also have the 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, the supported row formats are:
FIXED
DYNAMIC
COMPRESSED
The COMPRESSED row format can only be set by the myisampack command line tool.
See MyISAM Storage Formats for more information.

Supported Aria Row Formats

118/3812
For Aria, the supported row formats are:
PAGE
FIXED
DYNAMIC .
See Aria Storage Formats for more information.

Supported InnoDB Row Formats


For InnoDB, 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 system variable. If the 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 system variable is set to ON , then an error will be raised.
See InnoDB Storage Formats for more information.

Other Storage Engines and ROW_FORMAT


Other storage engines do not support the ROW_FORMAT table option.

SEQUENCE
MariaDB starting with 10.3
If the table is a sequence, 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 is run. If set to DEFAULT , or left out, the value set by the
innodb_stats_auto_recalc system variable applies. See InnoDB Persistent Statistics.

STATS_PERSISTENT
STATS_PERSISTENT indicates whether the InnoDB statistics created by ANALYZE TABLE 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 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.

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 value is used. See InnoDB Persistent Statistics.

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 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.

Partitions
119/3812
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. 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 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 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 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.

Sequences
120/3812
MariaDB starting with 10.3
CREATE TABLE can also be used to create a SEQUENCE. See CREATE SEQUENCE and Sequence Overview.

Atomic DDL
MariaDB starting with 10.6.1
MariaDB 10.6.1 supports Atomic DDL. 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.
How to specify a table-specific character set 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 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
ALTER TABLE
DROP TABLE
Character Sets and Collations
SHOW CREATE TABLE
Storage engines can add their own attributes for columns, indexes and tables.
Variable slave-ddl-exec-mode.

1.1.1.2.1.7 DELETE
Contents
1. Syntax
2. Description
1. PARTITION
2. FOR PORTION OF
3. RETURNING
4. Same Source and Target Table
5. DELETE HISTORY
3. Examples
1. Deleting from the Same Source and
Target
4. See Also

Syntax
Single-table syntax:

121/3812
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
Wait until all SELECT's are done before starting the statement. Used with storage engines that
LOW_PRIORITY uses table locking (MyISAM, Aria etc). See HIGH_PRIORITY and LOW_PRIORITY clauses for
details.
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
QUICK
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 and Aria support this feature.
Don't stop the query even if a not-critical error occurs (like data overflow). See How IGNORE
IGNORE
works 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() 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 clause
is specified, the rows are deleted in the order that is specified. The LIMIT 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 and LIMIT> cannot be used. A DELETE can also reference tables which are located in different databases;
see Identifier Qualifiers 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.
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.
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, and LOCK.

PARTITION
See Partition Pruning and Selection for details.

FOR PORTION OF
122/3812
MariaDB starting with 10.4.3
See Application Time Periods - 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

Same Source and Target Table


Until MariaDB 10.3.1, deleting from a table with the same source and target was not possible. From MariaDB 10.3.1,
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

DELETE HISTORY
One can use DELETE HISTORY to delete historical information from System-versioned tables.

Examples
How to use the ORDER BY and LIMIT 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, 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:

Query OK, 0 rows affected (0.00 sec)

See Also
123/3812
How IGNORE works
SELECT
ORDER BY
LIMIT
REPLACE ... RETURNING
INSERT ... RETURNING
Returning clause (video)

1.1.1.2.1.8 DROP TABLE


Syntax
DROP [TEMPORARY] TABLE [IF EXISTS] [/*COMMENT TO SAVE*/]
tbl_name [, tbl_name] ...
[WAIT n|NOWAIT]
[RESTRICT | CASCADE]

Contents
1. Syntax
2. Description
1. WAIT/NOWAIT
3. DROP TABLE in replication
4. Dropping an Internal #sql-... Table
5. Dropping All Tables in a Database
6. Atomic DROP TABLE
7. Examples
8. Notes
9. See Also

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 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.
If another thread is using the table in an explicit transaction or an autocommit transaction, then the thread acquires a
metadata lock (MDL) on the table. The DROP TABLE statement will wait in the "Waiting for table metadata lock" thread
state 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.
If a foreign key 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. 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 for details.
The DROP privilege 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.

124/3812
MariaDB starting with 10.5.4
From MariaDB 10.5.4, 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

WAIT/NOWAIT
Set the lock wait timeout. See WAIT and NOWAIT.

DROP TABLE in replication


DROP TABLE has the following characteristics in replication:

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.
Dropping of TEMPORARY tables are prefixed in the log with TEMPORARY . These drops are only logged when
running statement or mixed mode 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 to STRICT .

Dropping an Internal #sql-... Table


From MariaDB 10.6, DROP TABLE is atomic and the following does not apply. Until MariaDB 10.5, if the
mariadbd/mysqld process is killed during an ALTER TABLE you may find a table named #sql-... in your data directory. In
MariaDB 10.3, InnoDB tables with this prefix will be deleted automatically during startup. From MariaDB 10.4, 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, 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, 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 and MariaDB 10.3.10, 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, 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 table in the information_schema 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
From MariaDB 10.6, DROP TABLE for a single table is atomic (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 will
include a DROP TABLE statement for the dropped tables. Tables for which the drop had not started will be left intact.
125/3812
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, could have only a part of its internal
files dropped.
In MariaDB 10.5, DROP TABLE was extended to be able to delete a table that was only partly dropped (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 for more information.

Examples
DROP TABLE Employees, Customers;

Notes
Beware that DROP TABLE can drop both tables and sequences. This is mainly done to allow old tools like mysqldump to
work with sequences.

See Also
CREATE TABLE
ALTER TABLE
SHOW CREATE TABLE
DROP SEQUENCE
Variable slave-ddl-exec-mode.

1.1.1.2.1.9 Installing System Tables


(mysql_install_db)
mysql_install_db initializes the MariaDB data directory and creates the system tables in the mysql database, if they
do not exist. MariaDB uses these tables to manage privileges, roles, and plugins. It also uses them to provide the data
for the help command in the mysql client.
mysql_install_db works by starting MariaDB Server's mysqld process in --bootstrap mode and sending commands to
create the system tables and their content.
There is a version specifically for Windows, mysql_install_db.exe.
To invoke mysql_install_db , use the following syntax:

mysql_install_db --user=mysql

For the options supported by mysql_install_db, see mysql_install_db: Options.


For the option groups read by mysql_install_db, see mysql_install_db: Option Groups.
See mysql_install_db: Installing System Tables for information on the installation process.
See mysql_install_db: Troubleshooting Issues for information on how to troubleshoot the installation process.

See Also
mysql_install_db
The Windows version of mysql_install_db : mysql_install_db.exe

1.1.1.2.1.10 mysqlcheck
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-check is a symlink to mysqlcheck .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-check is the name of the tool, with mysqlcheck a symlink .

126/3812
Contents
1. Using mysqlcheck
1. Options
2. Option Files
1. Option Groups
2. Notes
1. Default Values
2. mysqlcheck and auto-repair
3. mysqlcheck and all-databases
4. mysqlcheck and verbose

mysqlcheck 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, REPAIR TABLE, ANALYZE TABLE and OPTIMIZE
TABLE commands, and so, unlike myisamchk and aria_chk, requires the server to be running.
This tool does not work with partitioned tables.

Using mysqlcheck
./client/mysqlcheck [OPTIONS] database [tables]

OR

./client/mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...]

OR

./client/mysqlcheck [OPTIONS] --all-databases

mysqlcheck 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
mysqlcheck supports the following options:

Option Description
-A , --all-
Check all the databases. This is the same as --databases with all databases selected.
databases

Instead of issuing one query for each table, use one query per database, naming all tables in the
-1 , --all-in-1
database in a comma-separated list.
-a , --analyze Analyze given tables.
If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have
--auto-repair
been checked.
--character-
Directory where character set files are installed.
sets-dir=name

-c , --check Check table for errors.


-C , --check-
Check only tables that have changed since last check or haven't been closed properly.
only-changed

-g , --check- Check tables for version-dependent changes. May be used with --auto-repair to correct tables
upgrade requiring version-dependent updates. Automatically enables the --fix-db-names and --fix-
table-names options. Used when upgrading

127/3812
--compress Compress all information sent between the client and server if both support compression.
Check several databases. Note that normally mysqlcheck treats the first argument as a database
-B , --
name, and following arguments as table names. With this option, no tables are given, and all name
databases
arguments are regarded as database names.
-# , --
Output debug log. Often this is 'd:t:o,filename'.
debug[=name]

--debug-check Check memory and open file usage at exit.


--debug-info Print some debug info at exit.
--default-
Default authentication client-side plugin to use.
auth=plugin

--default-
character- Set the default character set.
set=name

If you are using this option with --check , it will ensure that the table is 100 percent consistent, but
-e , --extended 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.
Convert database names to the format used since MySQL 5.1. Only database names that contain
--fix-db-names
special characters are affected. Used when upgrading from an old MySQL version.
--fix-table- Convert table names (including views) to the format used since MySQL 5.1. Only table names that
names contain special characters are affected. Used when upgrading from an old MySQL version.
Flush each table after check. This is useful if you don't want to have the checked tables take up
--flush
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 , --
Connect to the given host.
host=name

-m , --medium- Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for
check most cases.
-o , --optimize Optimize tables.
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
-p , --
--password or -p option on the command line, mysqlcheck prompts for one. Specifying a
password[=name]
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 , -- When using ANALYZE TABLE ( --analyze ), uses the PERSISTENT FOR ALL option, which
persistent forces Engine-independent Statistics for this table to be updated. Added in MariaDB 10.1.10

On Windows, connect to the server via a named pipe. This option applies only if the server
-W , --pipe
supports named-pipe connections.
--plugin-dir Directory for client-side plugins.
-P num , -- Port number to use for connection or 0 for default to, in order of preference, my.cnf,
port=num $MYSQL_TCP_PORT, /etc/services, built-in default (3306).
--process- Perform the requested operation (check, repair, analyze, optimize) on tables. Enabled by default.
tables Use --skip-process-tables to disable.
Perform the requested operation (only CHECK VIEW or REPAIR VIEW). Possible values are NO,
--process-
YES (correct the checksum, if necessary, add the mariadb-version field),
views[=val]
UPGRADE_FROM_MYSQL (same as YES and toggle the algorithm MERGE<->TEMPTABLE.
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
protocol=name
want.
If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to
-q , --quick 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.

128/3812
--shared-
Shared-memory name to use for Windows connections using shared memory to a local server
memory-base-
(started with the --shared-memory option). Case-sensitive.
name

-s , --silent Print only error messages.


--skip-
Don't process the database (case-sensitive) specified as argument.
database

-S name , -- For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named
socket=name pipe to use.
Enables TLS. TLS is also enabled even without setting this option when certain other TLS options
are set. Starting with MariaDB 10.2, the --ssl option will not enable verifying the server
--ssl
certificate by default. In order to verify the server certificate, the user must specify the --ssl-
verify-server-cert option.

Defines a path to a PEM file that should contain one or more X509 certificates for trusted
Certificate Authorities (CAs) to use for TLS. This option requires that you use the absolute path,
--ssl-ca=name
not a relative path. See Secure Connections Overview: Certificate Authorities (CAs) for more
information. This option implies the --ssl 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) to use for TLS. This option requires that
you use the absolute path, not a relative path. The directory specified by this option needs to be
--ssl- run through the openssl rehash command. See Secure Connections Overview: Certificate
capath=name 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 for more information about
which libraries are used on which platforms. This option implies the --ssl option.

--ssl- Defines a path to the X509 certificate file to use for TLS. This option requires that you use the
cert=name absolute path, not a relative path. This option implies the --ssl option.
--ssl-
List of permitted ciphers or cipher suites to use for TLS. This option implies the --ssl option.
cipher=name

Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for
TLS. This option requires that you use the absolute path, not a relative path. See Secure
Connections Overview: Certificate Revocation Lists (CRLs) for more information. This option is
--ssl-crl=name
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 for more information about which libraries are used on which platforms.
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. 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
--ssl- command. See Secure Connections Overview: Certificate Revocation Lists (CRLs) for more
crlpath=name 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 for more information about which libraries are used on
which platforms.
Defines a path to a private key file to use for TLS. This option requires that you use the absolute
--ssl-key=name
path, not a relative path. This option implies the --ssl option.
--ssl-verify-
Enables server certificate verification. This option is disabled by default.
server-cert

Overrides the --databases or -B option such that all name arguments following the option are
--tables
regarded as table names.
For repair operations on MyISAM tables, get table structure from .frm file, so the table can be
--use-frm
repaired even if the .MYI header is corrupted.
-u , --
User for login if not current user.
user=name

Print info about the various stages. You can give this option several times to get even more
-v , --verbose
information. See mysqlcheck and verbose, below.
-V , --version Output version information and exit.
Write ANALYZE, OPTIMIZE and REPAIR TABLE commands to the binary log. Enabled by default;
--write-binlog
use --skip-write-binlog when commands should not be sent to replication slaves.

Option Files
129/3812
In addition to reading options from the command-line, mysqlcheck can also read options from option files. If an
unknown option is provided to mysqlcheck 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 and later, mysqlcheck is linked with MariaDB Connector/C . 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 for more information.

Option Groups
mysqlcheck reads options from the following option groups from option files:

Group Description
[mysqlcheck] Options read by mysqlcheck , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysqlcheck . Available starting with MariaDB 10.4.6.
check]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and MySQL
[client]
clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

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/mysqlcheck --print-defaults
./client/mysqlcheck --help

mysqlcheck and auto-repair


When running mysqlcheck with --auto-repair (as done by mysql_upgrade), mysqlcheck will first check all tables
and then in a separate phase repair those that failed the check.

mysqlcheck and all-databases


mysqlcheck --all-databases will ignore the internal log tables general_log and slow_log as these can't be checked,
repaired or optimized.

mysqlcheck and verbose


Using one --verbose option will give you more information about what mysqlcheck 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, RENAME, and CHECK commands that
mysqlcheck executes.

1.1.1.2.1.11 OPTIMIZE TABLE


130/3812
Syntax
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE
tbl_name [, tbl_name] ...
[WAIT n | NOWAIT]

Contents
1. Syntax
2. Description
1. WAIT/NOWAIT
2. Defragmenting
3. Updating an InnoDB fulltext index
4. Defragmenting InnoDB tablespaces
3. See Also

Description
OPTIMIZE TABLE has two main functions. It can either be used to defragment tables, or to update the InnoDB fulltext
index.

MariaDB starting with 10.3.0


WAIT/NOWAIT
Set the lock wait timeout. See WAIT and NOWAIT.

Defragmenting
OPTIMIZE TABLE works for InnoDB (before MariaDB 10.1.1 , only if the innodb_file_per_table server system variable
is set), Aria, MyISAM and ARCHIVE 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, VARBINARY, BLOB, or TEXT
columns). Deleted rows are maintained in a linked list and subsequent INSERT operations reuse old row positions.
This statement requires SELECT and INSERT privileges for the table.
By default, OPTIMIZE TABLE statements are written to the binary log and will be replicated. 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, OPTIMIZE TABLE statements are not logged to the binary log if read_only is set. See also Read-
Only Replicas.
OPTIMIZE TABLE is also supported for partitioned tables. You can use ALTER TABLE ... 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, and recreates the table. This operation frees the unused space and updates index statistics.
The Aria storage engine supports progress reporting for this statement.
If a MyISAM table is fragmented, concurrent inserts will not be performed until an OPTIMIZE TABLE statement is
executed on that table, unless the 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, 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 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 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 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 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

131/3812
feature loads n pages (determined by 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 for more details.

See Also
Optimize Table in InnoDB with ALGORITHM set to INPLACE
Optimize Table in InnoDB with ALGORITHM set to NOCOPY
Optimize Table in InnoDB with ALGORITHM set to INSTANT

1.1.1.2.1.12 RENAME TABLE


Syntax
RENAME TABLE[S] [IF EXISTS] tbl_name
[WAIT n | NOWAIT]
TO new_tbl_name
[, tbl_name2 TO new_tbl_name2] ...

Contents
1. Syntax
2. Description
1. IF EXISTS
2. WAIT/NOWAIT
3. Privileges
4. Atomic RENAME TABLE

Description
This statement renames one or more tables or views, but not the privileges associated with them.

IF EXISTS
MariaDB starting with 10.5.2
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. 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. 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
132/3812
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
MariaDB starting with 10.3.0
Set the lock wait timeout. See WAIT and NOWAIT.

Privileges
Executing the RENAME TABLE statement requires the DROP, CREATE and INSERT privileges for the table or the
database.

Atomic RENAME TABLE


MariaDB starting with 10.6.1
From MariaDB 10.6, RENAME TABLE is atomic for most engines, including InnoDB, MyRocks, MyISAM and Aria
(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 for more information.

1.1.1.2.1.13 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 and myisamchk for more.


REPAIR TABLE works for Archive, Aria, CSV and MyISAM tables. For InnoDB, see recovery modes. For CSV, see also
Checking and Repairing CSV Tables. 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 for the table.
By default, REPAIR TABLE statements are written to the binary log and will be replicated. 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, REPAIR TABLE statements are not logged to the binary log if read_only is set. See also Read-
Only Replicas.
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 and MyISAM allocate a buffer whose size is defined by aria_sort_buffer_size or
myisam_sort_buffer_size , also used for ALTER TABLE .

REPAIR TABLE is also supported for partitioned tables. However, the USE_FRM option cannot be used with this

133/3812
statement on a partitioned table.
ALTER TABLE ... REPAIR PARTITION can be used to repair one or more partitions.
The Aria storage engine supports progress reporting for this statement.

1.1.1.2.1.14 REPAIR VIEW


Syntax
REPAIR [NO_WRITE_TO_BINLOG | LOCAL] VIEW view_name[, view_name] ... [FROM MYSQL]

Contents
1. Syntax
2. Description
3. See Also

Description
The REPAIR VIEW statement was introduced to assist with fixing MDEV-6916 , an issue introduced in MariaDB 5.2
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 mysql_upgrade, 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 and will be replicated. 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

1.1.1.2.1.15 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 ...]]

134/3812
Contents
1. Syntax
2. Description
1. PARTITION
2. REPLACE RETURNING
1. Examples
3. Examples
4. See Also

Description
REPLACE works exactly like INSERT , 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). This allows to use REPLACE ... SELECT to copy rows between different
databases.

MariaDB starting with 10.5.0


The RETURNING clause was introduced in MariaDB 10.5.0

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 and INSERT ON
DUPLICATE KEY UPDATE.
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 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 for the table.
There are some gotchas you should be aware of, before using REPLACE :
If there is an AUTO_INCREMENT field, a new value will be generated.
If there are foreign keys, ON DELETE action will be activated by REPLACE .
Triggers 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 for details.

PARTITION
See Partition Pruning and Selection 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
135/3812
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

136/3812
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
HIGH_PRIORITY and LOW_PRIORITY clauses
INSERT DELAYED for details on the DELAYED clause

1.1.1.2.1.16 SHOW COLUMNS


Syntax
SHOW [FULL] {COLUMNS | FIELDS} FROM tbl_name [FROM db_name]
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
SHOW COLUMNS displays information about the columns in a given table. It also works for views. The LIKE clause, if
137/3812
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.
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 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 The column is a TIMESTAMP column that is automatically updated on INSERT and
CURRENT_TIMESTAMP 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 and EXPLAIN can be used as shortcuts.

You can also list a table's columns with:

mysqlshow db_name tbl_name

See the mysqlshow command for more details.


The DESCRIBE statement provides information similar to SHOW COLUMNS . The information_schema.COLUMNS table
provides similar, but more complete, information.
The SHOW CREATE TABLE, SHOW TABLE STATUS, and SHOW INDEX statements also provide information about
tables.

Examples

138/3812
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
mysqlshow
SHOW CREATE TABLE
SHOW TABLE STATUS
SHOW INDEX
Extended SHOW
Silent Column Changes

1.1.1.2.1.17 SHOW CREATE TABLE


Syntax
SHOW CREATE TABLE tbl_name

Contents
1. Syntax
2. Description
1. Index Order
3. Examples
4. See Also

Description
Shows the CREATE TABLE statement that created the given table. The statement requires the SELECT privilege for
the table. This statement also works with views and SEQUENCE.
SHOW CREATE TABLE quotes table and column names according to the value of the sql_quote_show_create server
system variable.

Certain SQL_MODE 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, NO_FIELD_OPTIONS and NO_KEY_OPTIONS SQL_MODE flags are used. All
MariaDB-specific table attributes are also not shown when a non-MariaDB/MySQL emulation mode is used, which
includes ANSI, DB2, POSTGRESQL, MSSQL, MAXDB or 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. Remember that replaying a CREATE
TABLE statement with uncommented invalid options will fail with an error, unless the IGNORE_BAD_TABLE_OPTIONS
SQL_MODE is in effect.
Note that SHOW CREATE TABLE is not meant to provide metadata about a table. It provides information about how the
139/3812
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 starting with 10.2.1


MariaDB 10.2.1 permits TEXT and BLOB data types to be assigned a DEFAULT value. As a result, from MariaDB
10.2.1 , SHOW CREATE TABLE will append a DEFAULT NULL to nullable TEXT or BLOB fields if no specific default is
provided.

MariaDB starting with 10.2.2


From MariaDB 10.2.2 , numbers are no longer quoted in the DEFAULT clause in SHOW CREATE statement.
Previously, 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 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 :

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 :

140/3812
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 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 VIEW

1.1.1.2.1.18 SHOW INDEX


Syntax
SHOW {INDEX | INDEXES | KEYS}
FROM tbl_name [FROM db_name]
[WHERE expr]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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:

141/3812
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/mysqlshow command:

mysqlshow -k db_name tbl_name

The information_schema.STATISTICS 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.
Estimated number of unique values in the index. The cardinality statistics are calculated at various
Cardinality
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.

The index type, which can be BTREE , FULLTEXT , HASH or RTREE . See Storage Engine Index
Index_type
Types.
Comment Other information, such as whether the index is disabled.
Index_comment Contents of the COMMENT attribute when the index was created.
Whether or not an index will be ignored by the optimizer. See Ignored Indexes. From MariaDB
Ignored
10.6.0.

The WHERE and LIKE clauses can be given to select rows using more general conditions, as discussed in Extended
SHOW.

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');

142/3812
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

1.1.1.2.1.19 TRUNCATE TABLE


Syntax
TRUNCATE [TABLE] tbl_name
[WAIT n | NOWAIT]

143/3812
Contents
1. Syntax
2. Description
1. WAIT/NOWAIT
2. Oracle-mode
3. Performance
3. See Also

Description
TRUNCATE TABLE empties a table completely. It requires the DROP privilege. See GRANT.
tbl_name can also be specified in the form db_name . tbl_name (see Identifier Qualifiers).

Logically, TRUNCATE TABLE is equivalent to a DELETE statement that deletes all rows, but there are practical
differences under some circumstances.
TRUNCATE TABLE will fail for an InnoDB table 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 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 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 to zero or null, and will
not remove the rows.
For the purposes of binary logging and replication, TRUNCATE TABLE is treated as DROP TABLE followed by CREATE
TABLE (DDL rather than DML).
TRUNCATE TABLE does not work on views. Currently, TRUNCATE TABLE drops all historical records from a system-
versioned table.

MariaDB starting with 10.3.0


WAIT/NOWAIT
Set the lock wait timeout. See WAIT and NOWAIT.

Oracle-mode
Oracle-mode from MariaDB 10.3 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, because it drops and re-creates a table.

With InnoDB, TRUNCATE TABLE is slower if innodb_file_per_table=ON is set (the default). This is because TRUNCATE
TABLE unlinks the underlying tablespace file, which can be an expensive operation. See MDEV-8069 for more details.
144/3812
The performance issues with innodb_file_per_table=ON can be exacerbated in cases where the InnoDB buffer pool is
very large and innodb_adaptive_hash_index=ON is set. In that case, using DROP TABLE followed by CREATE TABLE
instead of TRUNCATE TABLE may perform better. Setting innodb_adaptive_hash_index=OFF (it defaults to ON before
MariaDB 10.5) can also help. In MariaDB 10.2 only, from MariaDB 10.2.19 , this performance can also be improved by
setting innodb_safe_truncate=OFF. See MDEV-9459 for more details.
Setting innodb_adaptive_hash_index=OFF can also improve TRUNCATE TABLE performance in general. See MDEV-
16796 for more details.

See Also
TRUNCATE function
innodb_safe_truncate system variable
Oracle mode from MariaDB 10.3

1.1.1.2.1.20 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]

Contents
1. Syntax
2. Description
1. PARTITION
2. FOR PORTION OF
3. UPDATE Statements With the Same
Source and Target
3. Example
4. See Also

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 clause is specified, the rows are updated in the order that is specified. The LIMIT clause places a limit on
the number of rows that can be updated.
Until MariaDB 10.3.2, for the multiple-table syntax, UPDATE updates rows in each table named in table_references that
satisfy the conditions. In this case, ORDER BY and LIMIT cannot be used. This restriction was lifted in MariaDB 10.3.2
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 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.

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 (available from MariaDB 10.3.5) 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 privilege for any columns that are read but not modified. See GRANT.
The UPDATE statement supports the following modifiers:
145/3812
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 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 for details.

FOR PORTION OF
MariaDB starting with 10.4.3
See Application Time Periods - Updating by Portion.

UPDATE Statements With the Same Source and Target


MariaDB starting with 10.3.2
From MariaDB 10.3.2, 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, 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, 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
SELECT
ORDER BY
LIMIT
Identifier Qualifiers

1.1.1.2.1.21 IGNORE
146/3812
The IGNORE option tells the server to ignore some common errors.
IGNORE can be used with the following statements:
DELETE
INSERT (see also INSERT IGNORE)
LOAD DATA INFILE
UPDATE
ALTER TABLE
CREATE TABLE ... SELECT
INSERT ... SELECT
The logic used:
Variables out of ranges are replaced with the maximum/minimum value.
SQL_MODEs 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
Symbolic error name Description
number
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


Cannot add or update a child row: a foreign key
1452 ER_NO_REFERENCED_ROW_2
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 XtraDB
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 XtraDB/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 server variable can be used to prevent this.

1.1.1.2.1.22 System-Versioned Tables


1.1.1.2.2 ANALYZE and EXPLAIN Statements
ANALYZE FORMAT=JSON
Mix of the EXPLAIN FORMAT=JSON and ANALYZE statement features.

ANALYZE FORMAT=JSON Examples


Examples with ANALYZE FORMAT=JSON.

147/3812
ANALYZE Statement
Invokes the optimizer, executes the statement, and then produces EXPLAIN output.

EXPLAIN
EXPLAIN returns information about index usage, as well as being a synonym for DESCRIBE.

EXPLAIN ANALYZE
Old implementation, now ANALYZE statement

EXPLAIN FORMAT=JSON
Variant of EXPLAIN that produces output in JSON form

SHOW EXPLAIN
Shows an execution plan for a running query.

Using Buffer UPDATE Algorithm


Explanation of UPDATE's "Using Buffer" algorithm.

1.1.1.2.2.1 ANALYZE FORMAT=JSON


Contents
1. Basic Execution Data
2. Advanced Execution Data
3. SHOW ANALYZE FORMAT=JSON
4. Data About Individual Query Plan Nodes
5. Use Cases

ANALYZE FORMAT=JSON is a mix of the EXPLAIN FORMAT=JSON and ANALYZE 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 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
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

148/3812
Use Cases
See Examples of ANALYZE FORMAT=JSON.

1.1.1.2.2.2 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).
149/3812
1.1.1.2.2.3 ANALYZE Statement
Contents
1. Description
2. Command Output
3. Interpreting the Output
1. Joins
2. Meaning of NULL in r_rows and
r_filtered
4. ANALYZE FORMAT=JSON
5. Notes
6. See Also

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 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.

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.

150/3812
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 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 produces JSON output. It produces much more information than tabular ANALYZE .

Notes
151/3812
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 feature allows MariaDB to have ANALYZE output of slow queries printed into
the slow query log (see MDEV-6388 ).

See Also
ANALYZE FORMAT=JSON
ANALYZE TABLE
JIRA task for ANALYZE statement, MDEV-406

1.1.1.2.2.4 EXPLAIN
Syntax
EXPLAIN tbl_name [col_name | wild]

Or

EXPLAIN [EXTENDED | PARTITIONS | FORMAT=JSON]


{SELECT select_options | UPDATE update_options | DELETE delete_options}

Contents
1. Syntax
2. Description
1. Columns in EXPLAIN ... SELECT
1. "Select_type" Column
2. "Type" Column
3. "Extra" Column
2. EXPLAIN EXTENDED
3. Examples
1. Example of ref_or_null Optimization
4. See Also

Description
The EXPLAIN statement can be used either as a synonym for DESCRIBE or as a way to obtain information about how
MariaDB executes a SELECT , UPDATE or DELETE statement:
'EXPLAIN tbl_name' is synonymous with 'DESCRIBE tbl_name' or 'SHOW COLUMNS 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.
ANALYZE statement 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. See EXPLAIN in the Slow Query Log for details.
SHOW EXPLAIN shows the output of a running statement. In some cases, its output can be closer to reality than
EXPLAIN .

The ANALYZE statement 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 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.
152/3812
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.
How many bytes of the key that was used (shows if we are using only parts of the multi-column
key_len
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 The SUBQUERY is
SUBQUERY DEPENDENT .

DEPENDENT
The UNION is DEPENDENT .
UNION

The SELECT is DERIVED


DERIVED
from the PRIMARY .
Materialized tables will be populated at first access and will be
The SUBQUERY is
MATERIALIZED accessed by the primary key (= one key lookup). Number of rows in
MATERIALIZED .
EXPLAIN shows the cost of populating the table
The SELECT is in the
PRIMARY outermost query, but there is
also a SUBQUERY within it.
It is a simple SELECT query
SIMPLE without any SUBQUERY or
UNION .

The SELECT is a SUBQUERY


SUBQUERY
of the PRIMARY .
UNCACHEABLE The SUBQUERY is
SUBQUERY UNCACHEABLE .

UNCACHEABLE
The UNION is UNCACHEABLE .
UNION

The SELECT is a UNION of


UNION
the PRIMARY .

UNION RESULT The result of the UNION .

LATERAL The SELECT uses a Lateral


DERIVED Derived optimization

"Type" Column
This column contains information on how the table is accessed.

Value Description
A full table scan is done for the table (all rows are read). This is bad if the table is large and the
ALL table is joined against a previous table! This happens when the optimizer could not find any
usable index to access rows.
There is only one possibly matching row in the table. The row is read before the optimization
const
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.

153/3812
fulltext A fulltext index is used to access the rows.
A 'range' access is done for for several index and the found rows are merged. The key column
index_merge
shows which keys are used.
index_subquery This is similar as ref, but used for sub queries that are transformed to key lookups.
A full scan over the used index. Better than ALL but still bad if index is large and the table is
index
joined against a previous table.
range The table will be accessed with a key over one or more value ranges.
Like 'ref' but in addition another search for the 'null' value is done if the first value was not found.
ref_or_null
This happens usually with sub queries.
A non unique index or prefix of an unique index is used to find the rows. Good if the prefix doesn't
ref
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
The table was a system table (a table with should exactly one row), but no row was found.
found

If distinct optimization (remove duplicates) was used. This is marked only for the last table in
Distinct
the SELECT .
Full scan on NULL The table is a part of the sub query and if the value that is used to match the sub query will be
key 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
The used WHERE clause is always false so the SELECT will return no rows. This case was
noticed after
detected after we had read all 'const' tables and used the column values as constant in the
reading const
WHERE clause. For example: WHERE const_column=5 and const_column had a value of 4.
tables.

The used WHERE clause is always false so the SELECT will return no rows. For example: WHERE
Impossible WHERE
1=2

No matching During early optimization of MIN() / MAX() values it was detected that no row could match the
min/max row WHERE clause. The MIN() / MAX() function will return NULL .

no matching row The table was a const table (a table with only one possible matching row), but no row was
in const table found.
The SELECT was a sub query that did not use any tables. For example a there was no FROM
No tables used
clause or a FROM DUAL clause.
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
Not exists 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.

154/3812
For information_schema tables. Only the frm (table definition file was opened) was opened
Open_frm_only
for each matching row.
For information_schema tables. A full table open for each matching row is done to retrieve the
Open_full_table
requested information. (Slow)
For information_schema tables. Only the trigger file definition was opened for each matching
Open_trigger_only
row.
This only happens when there was no good default index to use but there may some index that
Range checked could be used when we can treat all columns from previous table as constants. For each row
for each record combination the optimizer will decide which index to use (if any) to fetch a row from this table.
(index map: ...) 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
For information_schema tables. Shows how many times we had to do a directory scan.
databases

All tables in the join was optimized away. This happens when we are only using COUNT(*) ,
Select tables
MIN() and MAX() functions in the SELECT and we where able to replace all of these with
optimized away
constants.
Skip_open_table For information_schema tables. The queried table didn't need to be opened.
unique row not The table was detected to be a const table (a table with only one possible matching row) during
found the early optimization phase, but no row was found.
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
Using filesort
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.
Only the index is used to retrieve the needed information from the table. There is no need to
Using index
perform an extra seek to retrieve the actual record.
Using index Like ' Using where ' but the where condition is pushed down to the table engine for internal
condition optimization at the index level.
Using index
Like ' Using index condition ' but in addition we use batch key access to retrieve rows.
condition(BKA)

The index is being used to resolve a GROUP BY or DISTINCT query. The rows are not read.
Using index for
This is very efficient if the table has a lot of identical index entries as duplicates are quickly
group-by
jumped over.
Using
For index_merge joins. Shows which index are part of the intersect.
intersect(...)

We store previous row combinations in a row buffer to be able to match each row against all of
Using join buffer
the rows combinations in the join buffer at one go.
Using
For index_merge joins. Shows which index are part of the union.
sort_union(...)

A temporary table is created to hold the result. This typically happens if you are using GROUP
Using temporary
BY , DISTINCT or ORDER BY .

A WHERE expression (in additional to the possible key lookup) is used to check if the row should
Using where 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 Like ' Using where ' but the where condition is pushed down to the table engine for internal
pushed condition optimization at the row level.
The UPDATE statement will first buffer the rows, and then run the updates, rather than do
Using buffer
updates on the fly. See Using Buffer UPDATE Algorithm 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 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
155/3812
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:

156/3812
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 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
Ignored Indexes

1.1.1.2.2.5 EXPLAIN ANALYZE


The syntax for the EXPLAIN ANALYZE feature was changed to ANALYZE statement , available since MariaDB 10.1.0 .
See ANALYZE statement.

1.1.1.2.2.6 EXPLAIN FORMAT=JSON


Contents
1. Synopsis
2. Output is different from MySQL
3. Output Format
4. See Also

Synopsis
EXPLAIN FORMAT=JSON is a variant of EXPLAIN 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

157/3812
*************************** 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
The output of MySQL's EXPLAIN FORMAT=JSON is not defined. Even MySQL Workbench has trouble parsing it
(see this blog post ).
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 .

Output Format
TODO: MariaDB's output format description.

See Also
ANALYZE FORMAT=JSON produces output like EXPLAIN FORMAT=JSON , but amended with the data from query
execution.

1.1.1.2.2.7 SHOW EXPLAIN


Contents
1. Syntax
2. Description
1. EXPLAIN FOR CONNECTION
2. FORMAT=JSON
3. Possible Errors
4. Differences Between SHOW EXPLAIN
and EXPLAIN Outputs
1. Background
2. List of Recorded Differences
3. Required Permissions
3. See Also

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 (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.

158/3812
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
The EXPLAIN FOR CONNECTION syntax was added for MySQL compatibility.

FORMAT=JSON
MariaDB starting with 10.9
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 , MDEV-
410 , and lp:1013343 . lp: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.
159/3812
See Also
EXPLAIN
EXPLAIN ANALYZE, which will perform a query and outputs enhanced EXPLAIN results.
It is also possible to save EXPLAIN into the slow query log.

1.1.1.2.2.8 Using Buffer UPDATE Algorithm


This article explains the UPDATE 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 output indicates that the buffer as described above will be used.

1.1.1.2.3 BACKUP Commands


Commands used by backup tools
BACKUP STAGE
Commands to be used by a MariaDB backup tool.

BACKUP LOCK
Blocks a table from DDL statements.

Mariabackup and BACKUP STAGE Commands


How Mariabackup could use BACKUP STAGE commands.

Storage Snapshots and BACKUP STAGE Commands


How storage snapshots could use BACKUP STAGE commands.

1.1.1.2.3.1 BACKUP STAGE


MariaDB starting with 10.4.1
The BACKUP STAGE commands were introduced in MariaDB 10.4.1.

160/3812
Contents
1. Syntax
2. Goals with BACKUP STAGE Commands
3. BACKUP STAGE Commands
1. BACKUP STAGE START
2. BACKUP STAGE FLUSH
3. BACKUP STAGE BLOCK_DDL
4. BACKUP STAGE BLOCK_COMMIT
5. BACKUP STAGE END
4. Using BACKUP STAGE Commands with
Backup Tools
1. Using BACKUP STAGE Commands
with Mariabackup
2. Using BACKUP STAGE Commands
with Storage Snapshots
5. Privileges
6. Notes
7. See Also

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 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:

161/3812
Wait for all statements using write locked non-transactional tables to end.
Blocks CREATE TABLE, DROP TABLE, TRUNCATE TABLE, and RENAME TABLE.
Blocks also start off a new ALTER TABLE and the final rename phase of ALTER TABLE. 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 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 . See Mariabackup and BACKUP
STAGE Commands for some examples on how Mariabackup uses these commands.

If you would like to use a version of Mariabackup that uses the BACKUP STAGE commands in an efficient way,
then one option is to use MariaDB Enterprise Backup that is bundled with 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 for some examples on
how to use each BACKUP STAGE command in an efficient way.

Privileges
BACKUP STAGE requires the RELOAD 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 or 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 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 Locking a table from DDL's.
162/3812
MDEV-5336 . Implement BACKUP STAGE for safe external backups.

1.1.1.2.3.2 BACKUP LOCK


MariaDB starting with 10.4.2
The BACKUP LOCK command was introduced in MariaDB 10.4.2.

Contents
1. Syntax
2. Usage in a Backup Tool
3. Privileges
4. Notes
5. Implementation
6. See Also

BACKUP LOCK blocks a table from DDL statements. This is mainly intended to be used by tools like mariabackup 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 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 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
MDEV-17309 - BACKUP LOCK: DDL locking of tables during backup

163/3812
1.1.1.2.3.3 Mariabackup and BACKUP STAGE
Commands
1.1.1.2.3.4 Storage Snapshots and BACKUP
STAGE Commands
MariaDB starting with 10.4.1
The BACKUP STAGE commands were introduced in MariaDB 10.4.1.

Contents
1. Generic Backup Process 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.

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 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.

1.1.1.2.4 FLUSH Commands


Commands to reset (flush) various caches in MariaDB.
FLUSH
Clear or reload various internal caches.

FLUSH QUERY CACHE


Defragmenting the query cache

FLUSH TABLES FOR EXPORT


Flushes changes to disk for specific tables.

There are 2 related questions .

1.1.1.2.4.1 FLUSH
Syntax
164/3812
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]

Contents
1. Syntax
2. Description
3. FLUSH RELAY LOGS
1. Compatibility with MySQL
4. FLUSH STATUS
1. Global Status Variables that Support
FLUSH STATUS
5. The different usage of FLUSH TABLES
1. The purpose of FLUSH TABLES
2. The purpose of FLUSH TABLES
WITH READ LOCK
3. The purpose of FLUSH TABLES
table_list
4. The purpose of FLUSH TABLES
table_list WITH READ LOCK
6. Implementation of FLUSH TABLES
commands in MariaDB 10.4.8 and above
1. Implementation of FLUSH TABLES
2. Implementation of FLUSH TABLES
WITH READ LOCK
3. Implementation of FLUSH TABLES
table_list
4. Implementation of FLUSH TABLES
table_list FOR EXPORT
7. FLUSH SSL
8. Reducing Memory Usage

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.
The RESET statement is similar to FLUSH . See RESET.
You cannot issue a FLUSH statement from within a stored function or a trigger. 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 Function
Limitations and Trigger Limitations.
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 and will be replicated. 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
XtraDB only. Internal command used for backup purposes. See the Information Schema
CHANGED_PAGE_BITMAPS
CHANGED_PAGE_BITMAPS Table .
CLIENT_STATISTICS Reset client statistics (see SHOW CLIENT_STATISTICS).
DES_KEY_FILE Reloads the DES key file (Specified with the --des-key-file startup option).
Flush the hostname cache (used for converting ip to host names and for unblocking blocked
HOSTS
hosts. See max_connect_errors)
INDEX_STATISTICS Reset index statistics (see SHOW INDEX_STATISTICS).

165/3812
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. FLUSH
[ERROR | ENGINE | ENGINE LOGS will delete all unneeded Aria redo logs. Since MariaDB 10.1.30 and
GENERAL | SLOW | BINARY MariaDB 10.2.11 , FLUSH BINARY LOGS DELETE_DOMAIN_ID=(list-of-domains) can be
| RELAY] LOGS 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.
MASTER Deprecated option, use RESET MASTER instead.
Reload all privileges from the privilege tables in the mysql database. If the server is started
PRIVILEGES
with --skip-grant-table option, this will activate the privilege tables again.
Defragment the query cache to better utilize its memory. If you want to reset the query
QUERY CACHE
cache, you can do it with RESET QUERY CACHE.
QUERY_RESPONSE_TIME See the QUERY_RESPONSE_TIME plugin.
SLAVE Deprecated option, use RESET REPLICA or RESET SLAVE instead.
Used to dynamically reinitialize the server's TLS context by reloading the files defined by
SSL several TLS system variables. See FLUSH SSL for more information. This command was
first added in MariaDB 10.4.1.
Resets all server status variables that can be reset to 0. Not all global status variables
STATUS
support this, so not all global values are reset. See FLUSH STATUS for more information.
Close tables given as options or all open tables if no table list was used. From MariaDB
10.4.1, 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
TABLE 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, 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 For InnoDB tables, flushes table changes to disk to permit binary table copies while the
EXPORT server is running. See FLUSH TABLES ... FOR EXPORT for more.
TABLES WITH READ Closes all open tables. New tables are only allowed to be opened with read locks until an
LOCK UNLOCK TABLES is given.
TABLES WITH READ
As TABLES WITH READ LOCK but also disable all checkpoint writes by transactional table
LOCK AND DISABLE
engines. This is useful when doing a disk snapshot of all tables.
CHECKPOINT

TABLE_STATISTICS Reset table statistics (see SHOW TABLE_STATISTICS).


Resets all per hour user resources. This enables clients that have exhausted their
USER_RESOURCES
resources to connect again.
USER_STATISTICS Reset user statistics (see SHOW USER_STATISTICS).
USER_VARIABLES Reset user variables (see User-defined variables).

You can also use the mysqladmin client to flush things. Use mysqladmin --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
The FOR CHANNEL keyword was added for MySQL compatibility. This is identical as using the channel_name directly
after the FLUSH command .
For example, one can now use:
FLUSH RELAY LOGS FOR CHANNEL 'connection_name';

166/3812
FLUSH STATUS
Server status variables 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
Aborted_connects
Binlog_cache_disk_use
Binlog_cache_use
Binlog_stmt_cache_disk_use
Binlog_stmt_cache_use
Connection_errors_accept
Connection_errors_internal
Connection_errors_max_connections
Connection_errors_peer_address
Connection_errors_select
Connection_errors_tcpwrap
Created_tmp_files
Delayed_errors
Delayed_writes
Feature_check_constraint
Feature_delay_key_write
Max_used_connections
Opened_plugin_libraries
Performance_schema_accounts_lost
Performance_schema_cond_instances_lost
Performance_schema_digest_lost
Performance_schema_file_handles_lost
Performance_schema_file_instances_lost
Performance_schema_hosts_lost
Performance_schema_locker_lost
Performance_schema_mutex_instances_lost
Performance_schema_rwlock_instances_lost
Performance_schema_session_connect_attrs_lost
Performance_schema_socket_instances_lost
Performance_schema_stage_classes_lost
Performance_schema_statement_classes_lost
Performance_schema_table_handles_lost
Performance_schema_table_instances_lost
Performance_schema_thread_instances_lost
Performance_schema_users_lost
Qcache_hits
Qcache_inserts
Qcache_lowmem_prunes
Qcache_not_cached
Rpl_semi_sync_master_no_times
Rpl_semi_sync_master_no_tx
Rpl_semi_sync_master_timefunc_failures
Rpl_semi_sync_master_wait_pos_backtraverse
Rpl_semi_sync_master_yes_tx
Rpl_transactions_multi_engine
Server_audit_writes_failed
Slave_retried_transactions
Slow_launch_threads
Ssl_accept_renegotiates
Ssl_accepts
Ssl_callback_cache_hits
Ssl_client_connects
Ssl_connect_renegotiates
Ssl_ctx_verify_depth
Ssl_ctx_verify_mode
Ssl_finished_accepts
Ssl_finished_connects
167/3812
Ssl_session_cache_hits
Ssl_session_cache_misses
Ssl_session_cache_overflows
Ssl_session_cache_size
Ssl_session_cache_timeouts
Ssl_sessions_reused
Ssl_used_session_cache_entries
Subquery_cache_hit
Subquery_cache_miss
Table_locks_immediate
Table_locks_waited
Tc_log_max_pages_used
Tc_log_page_waits
Transactions_gtid_foreign_engine
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.
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 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.

168/3812
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
The FLUSH SSL command was first added in MariaDB 10.4.

In MariaDB 10.4 and later, the FLUSH SSL command can be used to dynamically reinitialize the server's TLS 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:
ssl_cert
ssl_key
ssl_ca
ssl_capath
ssl_crl
ssl_crlpath
These TLS system variables are not dynamic, so their values can not be changed without restarting the server.
If you want to dynamically reinitialize the server's TLS context, then you need to change the certificate and key files at
the relevant paths defined by these TLS system variables, without actually changing the values of the variables. See
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;

1.1.1.2.4.2 FLUSH QUERY CACHE


Description
You can defragment the query cache 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 statement removes all query results from the query cache. The FLUSH TABLES
statement also does this.

1.1.1.2.4.3 FLUSH TABLES FOR EXPORT


Syntax

169/3812
FLUSH TABLES table_name [, table_name] FOR EXPORT

Contents
1. Syntax
2. Description
3. Example
4. See Also

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, Aria, CSV, InnoDB, MyISAM, MERGE, and XtraDB tables.
The table is read locked until one has issued UNLOCK TABLES.
If a storage engine does not support FLUSH TABLES FOR EXPORT , a 1031 error (SQLSTATE '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.

This statement requires the RELOAD and the LOCK TABLES 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.

See Also
Copying Tables Between Different MariaDB Databases and MariaDB Servers
Copying Transportable InnoDB Tablespaces
myisampack - Compressing the MyISAM data file for easier distribution.
aria_pack - Compressing the Aria data file for easier distribution

1.1.1.2.5 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 has begun the process of renaming. The documentation process is ongoing. See MDEV-
18777 to follow progress on this effort.

A list of replication-related commands. See replication for more replication-related information.

170/3812
CHANGE MASTER TO
1 Set or change replica parameters for connecting to the primary.

START SLAVE
Start replica threads.

STOP SLAVE
Stop replica threads.

RESET REPLICA/SLAVE
1 Forget replica connection information and start a new relay log file.

SET GLOBAL SQL_SLAVE_SKIP_COUNTER


Skips a number of events from the primary.

SHOW RELAYLOG EVENTS


Show events in the relay log.

SHOW SLAVE STATUS


Show status for one or all primaries.

SHOW MASTER STATUS


Status information about the binary log.

SHOW SLAVE HOSTS


Display replicas currently registered with the primary.

RESET MASTER
Delete binary log files.

171/3812
1.1.1.2.5.1 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 has begun the process of renaming. The documentation process is ongoing. See 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,..])

172/3812
Contents
1. Syntax
2. Description
3. Multi-Source Replication
1. default_master_connection
2. connection_name
4. Options
1. Connection Options
1. MASTER_USER
2. MASTER_PASSWORD
3. MASTER_HOST
4. MASTER_PORT
5. MASTER_CONNECT_RETRY
6. MASTER_BIND
7. MASTER_HEARTBEAT_PERIOD
2. TLS Options
1. MASTER_SSL
2. MASTER_SSL_CA
3. MASTER_SSL_CAPATH
4. MASTER_SSL_CERT
5. MASTER_SSL_CRL
6. MASTER_SSL_CRLPATH
7. MASTER_SSL_KEY
8. MASTER_SSL_CIPHER
9. MASTER_SSL_VERIFY_SERVER_CERT
3. Binary Log Options
1. MASTER_LOG_FILE
2. MASTER_LOG_POS
4. Relay Log Options
1. RELAY_LOG_FILE
2. RELAY_LOG_POS
5. GTID Options
1. MASTER_USE_GTID
2. MASTER_DEMOTE_TO_SLAVE
6. Replication Filter Options
1. IGNORE_SERVER_IDS
2. DO_DOMAIN_IDS
3. IGNORE_DOMAIN_IDS
7. Delayed Replication Options
1. MASTER_DELAY
5. Changing Option Values
6. Option Persistence
7. GTID Persistence
8. Creating a Replica from a Backup
9. Example
10. See Also

Description
The CHANGE MASTER statement sets the options that a replica uses to connect to and replicate from a primary.

MariaDB starting with 10.7.0


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, 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 system variable prior to executing CHANGE MASTER .


Setting the connection_name parameter when executing CHANGE MASTER .

default_master_connection

173/3812
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 will use to connect to the
primary.
This user account will need the REPLICATION SLAVE privilege (or, from MariaDB 10.5.1, the 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, and 128 characters from MariaDB
10.6.

MASTER_PASSWORD
The MASTER_USER option for CHANGE MASTER defines the password that the replica will use to connect to the primary as
the user account defined by the 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.

MASTER_HOST
The MASTER_HOST option for CHANGE MASTER defines the hostname or IP address of the primary.
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 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 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

174/3812
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 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 and
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 mode for replication by setting the
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, and 255 characters from MariaDB
10.6.

MASTER_PORT
The MASTER_PORT option for CHANGE MASTER defines the TCP/IP port of the primary.
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 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 and
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 mode for replication by setting the
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 option. It can be set either on the command-line
or in a server option group in an option file 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 for more information.

MASTER_HEARTBEAT_PERIOD

175/3812
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 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 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 statement is executed, then the heartbeat interval is reset to the default.

If the 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. 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 option, but these TLS options are ignored unless the replica supports TLS.
See Replication with Secure Connections for more information.

MASTER_SSL
The MASTER_SSL option for CHANGE MASTER tells the replica whether to force TLS for the connection. The valid values
are 0 or 1 .
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. This option requires that you use the absolute path,
not a relative path. This option implies the MASTER_SSL option.
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) 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. 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 command. This option implies the MASTER_SSL option.
For example:

176/3812
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) 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. This option
requires that you use the absolute path, not a relative path. This option implies the MASTER_SSL option.
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. 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 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) 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. 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
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 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) for more information.
177/3812
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. This option requires
that you use the absolute path, not a relative path. This option implies the MASTER_SSL option.
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.
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 for details. This option implies the MASTER_SSL option.
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. 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 for more information.

Binary Log Options


These options are related to the binary log 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 should begin reading from the primary's binary logs 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;

178/3812
The MASTER_LOG_FILE and MASTER_LOG_POS options cannot be specified if the RELAY_LOG_FILE and
RELAY_LOG_POS options were also specified.

The MASTER_LOG_FILE and MASTER_LOG_POS options are effectively ignored if you enable GTID mode for
replication by setting the 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 should begin reading from the primary's binary logs 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 and MASTER_LOG_POS options cannot be specified if the RELAY_LOG_FILE and
RELAY_LOG_POS options were also specified.

The MASTER_LOG_FILE and MASTER_LOG_POS options are effectively ignored if you enable GTID mode for
replication by setting the MASTER_USE_GTID option to some value other than no in the statement.

Relay Log Options


These options are related to the relay log position on the replica.

RELAY_LOG_FILE
The RELAY_LOG_FILE option for CHANGE MASTER can be used along with the RELAY_LOG_POS option to specify the
coordinates at which the replica's SQL thread should begin reading from the relay log the next time the thread starts.
The CHANGE MASTER statement usually deletes all relay log files. However, if the RELAY_LOG_FILE and/or
RELAY_LOG_POS options are specified, then existing relay log files are kept.

When you want to change the relay log position, you only need to stop the replica's SQL thread. The replica's I/O thread
can continue running. The STOP SLAVE and START SLAVE 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 position in the relay logs will
also be changed in the relay-log.info file or the file that is configured by the relay_log_info_file system variable.

The RELAY_LOG_FILE and RELAY_LOG_POS options cannot be specified if the MASTER_LOG_FILE and
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 option to specify the
coordinates at which the replica's SQL thread should begin reading from the relay log the next time the thread starts.
The CHANGE MASTER statement usually deletes all relay log files. However, if the RELAY_LOG_FILE and/or
RELAY_LOG_POS options are specified, then existing relay log files are kept.

When you want to change the relay log position, you only need to stop the replica's SQL thread. The replica's I/O thread
can continue running. The STOP SLAVE and START SLAVE statements support the SQL_THREAD option for this
scenario. For example:

179/3812
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 position in the relay logs will
also be changed in the relay-log.info file or the file that is configured by the relay_log_info_file system variable.

The RELAY_LOG_FILE and RELAY_LOG_POS options cannot be specified if the MASTER_LOG_FILE and
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) when connecting to a primary. The possible values are:
current_pos - Replicate in GTID mode and use gtid_current_pos as the position to start downloading
transactions from the primary. Deprecated from MariaDB 10.10. 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> option
instead.
slave_pos - Replicate in GTID mode and use gtid_slave_pos as the position to start downloading transactions
from the primary. From MariaDB 10.5.1, replica_pos is an alias for slave_pos .
no - Don't replicate in GTID mode.

MASTER_DEMOTE_TO_SLAVE

MariaDB starting with 10.10


Used to transition a primary to become a replica. Replaces the old MASTER_USE_GTID=current_pos 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_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;

Replication Filter Options


Also see Replication filters.

IGNORE_SERVER_IDS
The IGNORE_SERVER_IDS option for CHANGE MASTER can be used to configure a replica to ignore binary log events that
originated from certain servers. Filtered binary log events will not get logged to the replica’s relay log, 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 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:
180/3812
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 to only apply binary log events if the
transaction's GTID is in a specific gtid_domain_id value. Filtered binary log events will not get logged to the replica’s
relay log, 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 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 option and the 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 option, and the IGNORE_DOMAIN_IDS option was
previously set, then you need to clear the value of the 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 mode. Therefore, the
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 to ignore binary log events if the
transaction's GTID is in a specific gtid_domain_id value. Filtered binary log events will not get logged to the replica’s
relay log, 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 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 option and the 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 option, and the DO_DOMAIN_IDS option was
previously set, then you need to clear the value of the DO_DOMAIN_IDS option. For example:

181/3812
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 mode. Therefore, the
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. 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 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 and MASTER_PORT
options are changed.

Option Persistence
The values of the MASTER_LOG_FILE and MASTER_LOG_POS options (i.e. the binary log 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 option. The replica's I/O thread keeps this binary log position updated as it downloads events only
when MASTER_USE_GTID option is set to NO . Otherwise the file is not updated on a per event basis.
The master_info_file option can be set either on the command-line or in a server option group in an option file prior to
starting up the server. For example:

[mariadb]
...
master_info_file=/mariadb/myserver1-master.info

The values of the RELAY_LOG_FILE and RELAY_LOG_POS options (i.e. the relay log position) are written to either
the default relay-log.info file or the file that is configured by the relay_log_info_file system variable. The replica's
SQL thread keeps this relay log position updated as it applies events.
The relay_log_info_file system variable can be set either on the command-line or in a server option group in an option
file prior to starting up the server. For example:

[mariadb]
...
relay_log_info_file=/mariadb/myserver1-relay-log.info

GTID Persistence
182/3812
If the replica is replicating binary log events that contain GTIDs, then the replica's SQL thread will write every GTID that
it applies to the mysql.gtid_slave_pos table. This GTID can be inspected and modified through the gtid_slave_pos
system variable.
If the replica has the log_slave_updates system variable enabled and if the replica has the binary log enabled, then
every write by the replica's SQL thread will also go into the replica's binary log. This means that GTIDs of replicated
transactions would be reflected in the value of the 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 position or GTID position corresponding to the backup.
After restoring the backup on the replica, you could execute something like this to use the binary log 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 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 for more information on how to do this with Mariabackup.

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
START SLAVE
Multi-source replication
RESET SLAVE. Removes a connection created with CHANGE MASTER TO .
Global Transaction ID

183/3812
1.1.1.2.5.2 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 has begun the process of renaming. The documentation process is ongoing. See 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

Contents
1. Syntax
2. Description
1. START SLAVE UNTIL
2. connection_name
3. START ALL SLAVES
4. START REPLICA
3. See Also

Description
START SLAVE ( START REPLICA from MariaDB 10.5.1) with no thread_type options starts both of the replica threads (see
replication). The I/O thread reads events from the primary server and stores them in the relay log. The SQL thread
reads events from the relay log and executes them. START SLAVE requires the SUPER privilege, or, from MariaDB
10.5.2, the 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, or some other problem). START SLAVE does not warn you about this. You must check the
replica's error log for error messages generated by the replica threads, or check that they are running satisfactorily with
SHOW SLAVE STATUS (SHOW REPLICA STATUS from MariaDB 10.5.1).

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 for more details.

connection_name
If there is only one nameless primary, or the default primary (as specified by the 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


The FOR CHANNEL keyword was added for MySQL compatibility. This is identical as using the channel_name directly
after START SLAVE .

184/3812
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.

START REPLICA

MariaDB starting with 10.5.1


START REPLICA is an alias for START SLAVE from MariaDB 10.5.1.

See Also
Setting up replication.
CHANGE MASTER TO is used to create and change connections.
STOP SLAVE is used to stop a running connection.
RESET SLAVE is used to reset parameters for a connection and also to permanently delete a primary
connection.

1.1.1.2.5.3 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 has begun the process of renaming. The documentation process is ongoing. See 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

Contents
1. Syntax
2. Description
1. STOP ALL SLAVES
2. connection_name
3. STOP REPLICA
3. See Also

Description
Stops the replica threads. STOP SLAVE requires the SUPER privilege, or, from MariaDB 10.5.2, the REPLICATION
SLAVE ADMIN privilege.
Like START SLAVE, 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 or KILL CONNECTION
statement.
Note that STOP SLAVE doesn't delete the connection permanently. Next time you execute START SLAVE or the
MariaDB server restarts, the replica connection is restored with it's original arguments. If you want to delete a
connection, you should execute RESET SLAVE.

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.

185/3812
connection_name
The connection_name option is used for multi-source replication.
If there is only one nameless master, or the default master (as specified by the 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


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


STOP REPLICA is an alias for STOP SLAVE from MariaDB 10.5.1.

See Also
CHANGE MASTER TO is used to create and change connections.
START SLAVE is used to start a predefined connection.
RESET SLAVE is used to reset parameters for a connection and also to permanently delete a master connection.

1.1.1.2.5.4 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 has begun the process of renaming. The documentation process is ongoing. See 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"]

Contents
1. Syntax
2. Description
1. connection_name
2. RESET REPLICA
3. See Also

Description
RESET REPLICA/SLAVE makes the replica forget its replication position in the master's binary log. 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 files, and starts a
new relay log file. To use RESET REPLICA/SLAVE, the replica threads must be stopped (use STOP REPLICA/SLAVE 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
186/3812
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.

connection_name
The connection_name option is used for multi-source replication.
If there is only one nameless primary, or the default primary (as specified by the 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


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


RESET REPLICA is an alias for RESET SLAVE from MariaDB 10.5.1.

See Also
STOP REPLICA/SLAVE stops the replica, but it can be restarted with START REPLICA/SLAVE or after next
MariaDB server restart.

1.1.1.2.5.5 SET GLOBAL


SQL_SLAVE_SKIP_COUNTER
Syntax
SET GLOBAL sql_slave_skip_counter = N

Contents
1. Syntax
2. Description
3. Example
4. Multiple Replication Domains
5. See Also

Description
This statement skips the next N events from the primary. This is useful for recovering from replication 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 system variable.
Note that, if the event is a transaction, 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;

187/3812
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 is in use and if
gtid_slave_pos contains multiple 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.

See Also
Selectively Skipping Replication of Binlog Events

1.1.1.2.5.6 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 has begun the process of renaming. The documentation process is ongoing. See 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, this command shows the events in the relay log. If 'log_name' is not specified, the first relay log is shown.
Syntax for the LIMIT clause is the same as for SELECT ... 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/mysqlbinlog.
On the primary, this command does nothing.
Requires the REPLICA MONITOR privilege (>= MariaDB 10.5.9), the REPLICATION SLAVE ADMIN privilege (>=
MariaDB 10.5.2) or the REPLICATION SLAVE privilege (<= MariaDB 10.5.1).

connection_name
If there is only one nameless primary, or the default primary (as specified by the 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


The FOR CHANNEL keyword was added for MySQL compatibility. This is identical as using the channel_name directly
after SHOW RELAYLOG .

1.1.1.2.5.7 SHOW SLAVE STATUS


188/3812
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

Contents
1. Syntax
2. Description
1. Multi-Source
2. Column Descriptions
3. SHOW REPLICA STATUS
3. Examples
4. See Also

Description
This statement is to be run on a replica and provides status information on essential parameters of the replica threads.
This statement requires the SUPER privilege, the REPLICATION_CLIENT privilege, or, from MariaDB 10.5.2, the
REPLICATION SLAVE ADMIN privilege, or, from MariaDB 10.5.9, the REPLICA MONITOR privilege.

Multi-Source
The ALL and "connection_name" options allow you to connect to many primaries at the same time.
ALL SLAVES (or ALL REPLICAS from MariaDB 10.5.1) 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


The FOR CHANNEL keyword was added for MySQL compatibility. This is identical as using the channel_name directly
after SHOW SLAVE .

Column Descriptions
Name Description Added
Name of the primary connection. Returned with SHOW ALL SLAVES
Connection_name
STATUS (or SHOW ALL REPLICAS STATUS from MariaDB 10.5.1) only.

State of SQL thread. Returned with SHOW ALL SLAVES STATUS (or
Slave_SQL_State SHOW ALL REPLICAS STATUS from MariaDB 10.5.1) only. See Slave
SQL Thread States.
Slave_IO_State State of I/O thread. See Slave I/O Thread States.
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.
Time in seconds between retries to connect. The default is 60. The
Connect_Retry CHANGE MASTER TO statement can set this. The master-retry-count
option determines the maximum number of reconnection attempts.
Name of the primary binary log file that the I/O thread is currently
Master_Log_File
reading from.
Position up to which the I/O thread has read in the current primary
Read_Master_Log_Pos
binary log file.
Relay_Log_File Name of the relay log file that the SQL thread is currently processing.
189/3812
Position up to which the SQL thread has finished processing in the
Relay_Log_Pos
current relay log file.
Name of the primary binary log file that contains the most recent event
Relay_Master_Log_File
executed by the SQL thread.
Whether the replica I/O thread is running and connected ( Yes ),
Slave_IO_Running running but not connected to a primary ( Connecting ) or not running
( No ).
Slave_SQL_Running Whether or not the SQL thread is running.
Replicate_Do_DB Databases specified for replicating with the replicate_do_db option.
Databases specified for ignoring with the replicate_ignore_db
Replicate_Ignore_DB
option.
Replicate_Do_Table Tables specified for replicating with the replicate_do_table option.
Tables specified for ignoring with the replicate_ignore_table
Replicate_Ignore_Table
option.
Tables specified for replicating with the replicate_wild_do_table
Replicate_Wild_Do_Table
option.
Tables specified for ignoring with the replicate_wild_ignore_table
Replicate_Wild_Ignore_Table
option.
Last_Errno Alias for Last_SQL_Errno (see below)
Last Error Alias for Last_SQL_Error (see below)
Number of events that a replica skips from the master, as recorded in
Skip_Counter
the sql_slave_skip_counter system variable.
Position up to which the SQL thread has processed in the current
master binary log file. Can be used to start a new replica from a
Exec_Master_Log_Pos
current replica with the CHANGE MASTER TO ...
MASTER_LOG_POS 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 condition.
Until_Log_Pos The MASTER_LOG_POS value of the START SLAVE UNTIL condition.
Whether an SSL connection is permitted ( Yes ), not permitted ( No ) or
Master_SSL_Allowed permitted but without the replica having SSL support enabled
( Ignored )
Master_SSL_CA_File The MASTER_SSL_CA option of the CHANGE MASTER TO statement.
Master_SSL_CA_Path The MASTER_SSL_CAPATH option of the CHANGE MASTER TO statement.
Master_SSL_Cert The MASTER_SSL_CERT option of the CHANGE MASTER TO statement.
Master_SSL_Cipher The MASTER_SSL_CIPHER option of the CHANGE MASTER TO statement.
Master_SSL_Key The MASTER_SSL_KEY option of the CHANGE MASTER TO statement.
Difference between the timestamp logged on the master for the event
that the replica is currently processing, and the current timestamp on
Seconds_Behind_Master the replica. Zero if the replica is not currently processing an event.
With parallel replication, seconds_behind_master is updated only
after transactions commit.
The MASTER_SSL_VERIFY_SERVER_CERT option of the CHANGE MASTER
Master_SSL_Verify_Server_Cert
TO statement.

Error code of the most recent error that caused the I/O thread to stop
Last_IO_Errno (also recorded in the replica's error log). 0 means no error. RESET
SLAVE or RESET MASTER will reset this value.
Error message of the most recent error that caused the I/O thread to
Last_IO_Error stop (also recorded in the replica's error log). An empty string means
no error. RESET SLAVE or RESET MASTER will reset this value.
Error code of the most recent error that caused the SQL thread to stop
Last_SQL_Errno (also recorded in the replica's error log). 0 means no error. RESET
SLAVE or RESET MASTER will reset this value.
190/3812
Error message of the most recent error that caused the SQL thread to
Last_SQL_Error stop (also recorded in the replica's error log). An empty string means
no error. RESET SLAVE or RESET MASTER will reset this value.
List of server_ids that are currently being ignored for replication
Replicate_Ignore_Server_Ids purposes, or an empty string for none, as specified in the
IGNORE_SERVER_IDS option of the CHANGE MASTER TO statement.

Master_Server_Id The master's server_id value.


Master_SSL_Crl The MASTER_SSL_CRL option of the CHANGE MASTER TO statement.
Master_SSL_Crlpath The MASTER_SSL_CRLPATH option of the CHANGE MASTER TO statement.
Whether or not global transaction ID's are being used for replication
Using_Gtid
(can be No , Slave_Pos , or Current_Pos ).
Gtid_IO_Pos Current global transaction ID value.
Number of retried transactions for this connection. Returned with SHOW
Retried_transactions
ALL SLAVES STATUS only.

Max relay log size for this connection. Returned with SHOW ALL SLAVES
Max_relay_log_size
STATUS only.

How many log entries the replica has executed. Returned with SHOW
Executed_log_entries
ALL SLAVES STATUS only.

How many heartbeats we have got from the master. Returned with
Slave_received_heartbeats
SHOW ALL SLAVES STATUS only.

How often to request a heartbeat packet from the master (in seconds).
Slave_heartbeat_period
Returned with SHOW ALL SLAVES STATUS only.
GTID of the last event group replicated on a replica server, for each
Gtid_Slave_Pos replication domain, as stored in the gtid_slave_pos system variable.
Returned with SHOW ALL SLAVES STATUS only.
MariaDB
SQL_Delay Value specified by MASTER_DELAY in CHANGE MASTER (or 0 if none).
10.2.3
When the replica is delaying the execution of an event due to
MariaDB
SQL_Remaining_Delay MASTER_DELAY , this is the number of seconds of delay remaining
10.2.3
before the event will be applied. Otherwise, the value is NULL .
The state of the SQL driver threads, same as in SHOW PROCESSLIST .
When the replica is delaying the execution of an event due to MariaDB
Slave_SQL_Running_State
MASTER_DELAY , this field displays: " Waiting until MASTER_DELAY 10.2.3
seconds after master executed event ".

This status variable counts the occurrence of DDL statements. This is MariaDB
Slave_DDL_Groups
a replica-side counter for optimistic parallel replication. 10.3.7
This status variable counts the occurrence of non-transactional event MariaDB
Slave_Non_Transactional_Groups
groups. This is a replica-side counter for optimistic parallel replication. 10.3.7
This status variable counts the occurrence of transactional event MariaDB
Slave_Transactional_Groups
groups. This is a replica-side counter for optimistic parallel replication. 10.3.7

SHOW REPLICA STATUS


MariaDB starting with 10.5.1
SHOW REPLICA STATUS is an alias for SHOW SLAVE STATUS from MariaDB 10.5.1.

Examples
If you issue this statement using the mysql client, you can use a \G statement terminator rather than a semicolon to
obtain a more readable vertical layout.

191/3812
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:

192/3812
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

193/3812
See Also
MariaDB replication

1.1.1.2.5.8 SHOW MASTER STATUS


Syntax
SHOW MASTER STATUS
SHOW BINLOG STATUS -- From MariaDB 10.5.2

Description
Provides status information about the binary log files of the primary.
This statement requires the SUPER privilege, the REPLICATION_CLIENT privilege, or, from MariaDB 10.5.2, the
BINLOG MONITOR privilege.
To see information about the current GTIDs in the binary log, use the gtid_binlog_pos variable.
SHOW MASTER STATUS was renamed to SHOW BINLOG STATUS in MariaDB 10.5.2, 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
Using and Maintaining the Binary Log
The gtid_binlog_pos variable

1.1.1.2.5.9 SHOW SLAVE HOSTS


Contents
1. Syntax
2. Description
1. SHOW REPLICA HOSTS
3. See Also

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 list is displayed on any server (not just the primary server). The output looks like this:

194/3812
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.
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. This variable was never used, and
was eventually removed in MariaDB 10.1.2 .
Requires the REPLICATION MASTER ADMIN privilege (>= MariaDB 10.5.2) or the REPLICATION SLAVE privilege (<=
MariaDB 10.5.1).

SHOW REPLICA HOSTS

MariaDB starting with 10.5.1


SHOW REPLICA HOSTS is an alias for SHOW SLAVE HOSTS from MariaDB 10.5.1.

See Also
MariaDB replication
Replication threads
SHOW PROCESSLIST. In SHOW PROCESSLIST output, replica threads are identified by Binlog Dump

1.1.1.2.5.10 RESET MASTER


RESET MASTER [TO #]

Deletes all binary log 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 from the binary log.

See Also
The PURGE BINARY LOGS statement is intended for use in active replication.

1.1.1.2.6 Plugin SQL Statements


Plugin commands.
SHOW PLUGINS
Display information about installed plugins.

SHOW PLUGINS SONAME


Information about all available plugins, installed or not.

INSTALL PLUGIN
3 Install a plugin.

UNINSTALL PLUGIN
Remove a single installed plugin.

195/3812
INSTALL SONAME
2 Installs all plugins from a given library.

UNINSTALL SONAME
Remove all plugins belonging to a specified library.

mysql_plugin
Tool for enabling or disabling plugins.

1.1.1.2.6.1 SHOW PLUGINS


Syntax
SHOW PLUGINS;

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
SHOW PLUGINS displays information about installed plugins. The Library column indicates the plugin library - if it is
NULL , the plugin is built-in and cannot be uninstalled.

The PLUGINS 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 table
and the SHOW ENGINES 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
Plugin Overview
INFORMATION_SCHEMA.PLUGINS Table
INSTALL PLUGIN
INFORMATION_SCHEMA.ALL_PLUGINS Table (all plugins, installed or not)
INSTALL SONAME
196/3812
UNINSTALL PLUGIN
UNINSTALL SONAME

1.1.1.2.6.2 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 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 table, called ALL_PLUGINS , which contains more complete
information.

1.1.1.2.6.3 INSTALL PLUGIN


Syntax
INSTALL PLUGIN [IF NOT EXISTS] plugin_name SONAME 'plugin_library'

Contents
1. Syntax
2. Description
1. IF NOT EXISTS
3. Examples
4. See Also

Description
This statement installs an individual plugin from the specified library. To install the whole library (which could be
required), use INSTALL SONAME. See also 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 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 is a relative path name, it is taken to be relative to the MySQL base directory (the value of the
basedir system variable).

197/3812
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 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.

MariaDB starting with 10.4.0


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.

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:

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
Plugin Overview
INFORMATION_SCHEMA.PLUGINS Table
mysql_plugin
SHOW PLUGINS
INSTALL SONAME
UNINSTALL PLUGIN
UNINSTALL SONAME

1.1.1.2.6.4 UNINSTALL PLUGIN


Syntax
UNINSTALL PLUGIN [IF EXISTS] plugin_name

198/3812
Contents
1. Syntax
2. Description
1. IF EXISTS
3. Examples
4. See Also

Description
This statement removes a single installed plugin. To uninstall the whole library which contains the plugin, use
UNINSTALL SONAME. 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 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 privilege for the mysql.plugin table.

MariaDB starting with 10.4.0


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.

Examples
UNINSTALL PLUGIN example;

From MariaDB 10.4.0:

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
mysql_plugin
INSTALL PLUGIN
List of Plugins

1.1.1.2.6.5 INSTALL SONAME


Syntax
INSTALL SONAME 'plugin_library'

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
This statement is a variant of INSTALL PLUGIN. It installs all plugins from a given plugin_library . See INSTALL
199/3812
PLUGIN 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 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 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 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.
If you need to install only one plugin from a library, use the INSTALL PLUGIN 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
Plugin Overview
SHOW PLUGINS
INSTALL PLUGIN
UNINSTALL PLUGIN
UNINSTALL SONAME
SHOW PLUGINS
INFORMATION_SCHEMA.PLUGINS Table
mysql_plugin

1.1.1.2.6.6 UNINSTALL SONAME


Syntax
UNINSTALL SONAME [IF EXISTS] 'plugin_library'

200/3812
Contents
1. Syntax
2. Description
1. IF EXISTS
3. Examples
4. See Also

Description
This statement is a variant of UNINSTALL PLUGIN statement, that removes all plugins belonging to a specified
plugin_library . See UNINSTALL PLUGIN 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 for the mysql.plugin table.

MariaDB starting with 10.4.0


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.

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:

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
SHOW PLUGINS
INSTALL PLUGIN
UNINSTALL PLUGIN
SHOW PLUGINS
INFORMATION_SCHEMA.PLUGINS Table
mysql_plugin
List of Plugins

1.1.1.2.6.7 mysql_plugin
1.1.1.2.7 SET Commands
SET
1 Set a variable value.

SET CHARACTER SET


Maps all strings sent between the current client and the server with the given mapping.

SET GLOBAL SQL_SLAVE_SKIP_COUNTER


Skips a number of events from the primary.
201/3812
SET NAMES
The character set used to send statements to the server, and results back to the client.

SET PASSWORD
Assign password to an existing MariaDB user.

SET ROLE
1 Enable a role.

SET SQL_LOG_BIN
Set binary logging for the current connection.

SET STATEMENT
Set variable values on a per-query basis

SET TRANSACTION
5 Sets the transaction isolation level.

SET Variable
1 Used to insert a value into a variable with a code block.

There are 1 related questions .

1.1.1.2.7.1 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

Contents
1. Syntax
2. Description
1. GLOBAL / SESSION
2. DEFAULT
3. Examples
4. See Also

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.
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.
For setting variables on a per-query basis, see SET STATEMENT.
See SHOW VARIABLES for documentation on viewing server system variables.
See Server System Variables 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.
202/3812
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 is a global variable.
skip_parallel_replication is a session variable.
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 will by default return the session value unless the variable is global only.

203/3812
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
SET STATEMENT
SET Variable
SET Data Type
DECLARE Variable

1.1.1.2.7.2 SET CHARACTER SET


Syntax
SET {CHARACTER SET | CHARSET}
{charset_name | DEFAULT}

Description
Sets the character_set_client and character_set_results session system variables to the specified character set and
collation_connection to the value of collation_database, which implicitly sets character_set_connection to the value of
character_set_database.
This maps all strings sent between the current client and the server with the given mapping.

Example

204/3812
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

1.1.1.2.7.3 SET GLOBAL


SQL_SLAVE_SKIP_COUNTER
1.1.1.2.7.4 SET NAMES
Syntax
SET NAMES {'charset_name'
[COLLATE 'collation_name'] | DEFAULT}

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Sets the character_set_client, character_set_connection, character_set_results and, implicitly, the collation_connection
205/3812
session system variables to the specified character set and collation.
This determines which character set the client will use to send statements to the server, and the server will use for
sending results back to the client.
ucs2 , utf16 , 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 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
206/3812
SET CHARACTER SET
Character Sets and Collations

1.1.1.2.7.5 SET PASSWORD


1.1.1.2.7.6 SET ROLE
1.1.1.2.7.7 SET SQL_LOG_BIN
Syntax
SET [SESSION] sql_log_bin = {0|1}

Description
Sets the sql_log_bin system variable, which disables or enables binary logging for the current connection, if the client
has the SUPER privilege. The statement is refused with an error if the client does not have that privilege.
Before MariaDB 5.5 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.

1.1.1.2.7.8 SET STATEMENT


Contents
1. Syntax
2. Description
3. Examples
4. Limitations
5. Source

MariaDB starting with 10.1.2


Per-query variables were introduced in MariaDB 10.1.2

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 :
207/3812
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
MariaDB ported the patch and fixed many bugs. The task in MariaDB Jira is MDEV-5231 .

1.1.1.2.7.9 SET TRANSACTION


Syntax

208/3812
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

Contents
1. Syntax
2. Description
1. Isolation Level
2. Isolation Levels
1. READ UNCOMMITTED
2. READ COMMITTED
3. REPEATABLE READ
4. SERIALIZABLE
3. Access Mode
3. Examples

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 the next (not started)
transaction performed within the current session.
A change to the global default isolation level requires the SUPER 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 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-COMMITTED , REPEATABLE-READ , or SERIALIZABLE . For example, to set the default
isolation level to REPEATABLE READ , use these lines in the [mysqld] section of an option file:

[mysqld]
transaction-isolation = REPEATABLE-READ

To determine the global and session transaction isolation levels at runtime, check the value of the tx_isolation
system variable:

SELECT @@GLOBAL.tx_isolation, @@tx_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, 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 .

209/3812
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 MySQL
replication and recovery to work.
Note: If the READ COMMITTED isolation level is used or the innodb_locks_unsafe_for_binlog system variable is enabled,
there is no InnoDB gap locking except for foreign-key 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.

SERIALIZABLE
This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... LOCK
IN SHARE MODE if 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 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 system variable). READ ONLY mode allows the storage engine to apply optimizations
that cannot be used for transactions which write data. The only exception to this rule is that read only transactions can
perform DDL statements on temporary tables.
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 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

1.1.1.2.7.10 SET Variable


210/3812
Syntax
SET var_name = expr [, var_name = expr] ...

Contents
1. Syntax
2. Description
3. See Also

Description
The SET statement in stored programs is an extended version of the general SET 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 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 and user-defined variables.

When setting several variables using the columns returned by a query, SELECT INTO should be preferred.
To set many variables to the same value, the LAST_VALUE( ) function can be used.
Below is an example of how a user-defined variable may be set:

SET @x = 1;

See Also
SET
SET STATEMENT
DECLARE Variable

1.1.1.2.8 SHOW
Articles on the various SHOW commands.
About SHOW
General information about the SHOW statement.

Extended Show
Extended SHOW with WHERE and LIKE.

SHOW AUTHORS
Information about the people who work on MariaDB.

SHOW BINARY LOGS


SHOW BINARY LOGS lists all binary logs on the server.

SHOW BINLOG EVENTS


Show events in the binary log.

SHOW CHARACTER SET


Available character sets.

SHOW CLIENT_STATISTICS
Statistics about client connections.

SHOW COLLATION
Supported collations.

SHOW COLUMNS
Column information.

211/3812
SHOW CONTRIBUTORS
Companies and people who financially contribute to MariaDB.

SHOW CREATE DATABASE


Shows the CREATE DATABASE statement that created the database.

SHOW CREATE EVENT


Displays the CREATE EVENT statement needed to re-create a given event

SHOW CREATE FUNCTION


Statement that created the function.

SHOW CREATE PACKAGE


Show the CREATE statement that creates the given package specification.

SHOW CREATE PACKAGE BODY


Show the CREATE statement that creates the given package body (i.e. implementation).

SHOW CREATE PROCEDURE


Returns the string used for creating a stored procedure.

SHOW CREATE SEQUENCE


Shows the CREATE SEQUENCE statement that created the sequence.

SHOW CREATE TABLE


Shows the CREATE TABLE statement that created the table.

SHOW CREATE TRIGGER


Shows the CREATE TRIGGER statement used to create the trigger

SHOW CREATE USER


Show the CREATE USER statement for a specified user.

SHOW CREATE VIEW


Show the CREATE VIEW statement that created a view.

SHOW DATABASES
Lists the databases on the server.

SHOW ENGINE
Show storage engine information.

SHOW ENGINE INNODB STATUS


Display extensive InnoDB information.

SHOW ENGINES
Server storage engine info

SHOW ERRORS
1 Displays errors.

SHOW EVENTS
Shows information about events

SHOW EXPLAIN
Shows an execution plan for a running query.

SHOW FUNCTION CODE


Representation of the internal implementation of the stored function

SHOW FUNCTION STATUS


Stored function characteristics

SHOW GRANTS
9 View GRANT statements.

SHOW INDEX
Information about table indexes.

212/3812
SHOW INDEX_STATISTICS
Index usage statistics.

SHOW INNODB STATUS (removed)


Removed synonym for SHOW ENGINE INNODB STATUS

SHOW LOCALES
View locales information.

SHOW MASTER STATUS


Status information about the binary log.

SHOW OPEN TABLES


List non-temporary open tables.

SHOW PACKAGE BODY STATUS


Returns characteristics of stored package bodies (implementations).

SHOW PACKAGE STATUS


Returns characteristics of stored package specifications.

SHOW PLUGINS
Display information about installed plugins.

SHOW PLUGINS SONAME


Information about all available plugins, installed or not.

SHOW PRIVILEGES
Shows the list of supported system privileges.

SHOW PROCEDURE CODE


Display internal implementation of a stored procedure.

SHOW PROCEDURE STATUS


Stored procedure characteristics.

SHOW PROCESSLIST
1 Running threads and information about them.

SHOW PROFILE
Display statement resource usage

SHOW PROFILES
Show statement resource usage

SHOW QUERY_RESPONSE_TIME
Retrieving information from the QUERY_RESPONSE_TIME plugin.

SHOW RELAYLOG EVENTS


Show events in the relay log.

SHOW SLAVE HOSTS


Display replicas currently registered with the primary.

SHOW SLAVE STATUS


Show status for one or all primaries.

SHOW STATUS
Server status information.

SHOW TABLE STATUS


SHOW TABLES with information about non-temporary tables.

SHOW TABLES
List of non-temporary tables, views or sequences.

SHOW TABLE_STATISTICS
Table usage statistics.

213/3812
SHOW TRIGGERS
Shows currently-defined triggers

SHOW USER_STATISTICS
User activity statistics.

SHOW VARIABLES
Displays the values of system variables.

SHOW WARNINGS
Displays errors, warnings and notes.

SHOW WSREP_MEMBERSHIP
Galera node cluster membership information.

SHOW WSREP_STATUS
Galera node cluster status information.

1.1.1.2.8.1 About SHOW


SHOW has many forms that provide information about databases, tables, columns, or status information about the
server. These include:
SHOW AUTHORS
SHOW CHARACTER SET [like_or_where]
SHOW COLLATION [like_or_where]
SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [like_or_where]
SHOW CONTRIBUTORS
SHOW CREATE DATABASE db_name
SHOW CREATE EVENT event_name
SHOW CREATE PACKAGE package_name
SHOW CREATE PACKAGE BODY package_name
SHOW CREATE PROCEDURE proc_name
SHOW CREATE TABLE tbl_name
SHOW CREATE TRIGGER trigger_name
SHOW CREATE VIEW view_name
SHOW DATABASES [like_or_where]
SHOW ENGINE engine_name {STATUS | MUTEX}
SHOW [STORAGE] ENGINES
SHOW ERRORS [LIMIT [offset,] row_count]
SHOW [FULL] EVENTS
SHOW FUNCTION CODE func_name
SHOW FUNCTION STATUS [like_or_where]
SHOW GRANTS FOR user
SHOW INDEX FROM tbl_name [FROM db_name]
SHOW INNODB STATUS
SHOW OPEN TABLES [FROM db_name] [like_or_where]
SHOW PLUGINS
SHOW PROCEDURE CODE proc_name
SHOW PROCEDURE STATUS [like_or_where]
SHOW PRIVILEGES
SHOW [FULL] PROCESSLIST
SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n]
SHOW PROFILES
SHOW [GLOBAL | SESSION] STATUS [like_or_where]
SHOW TABLE STATUS [FROM db_name] [like_or_where]
SHOW TABLES [FROM db_name] [like_or_where]
SHOW TRIGGERS [FROM db_name] [like_or_where]
SHOW [GLOBAL | SESSION] VARIABLES [like_or_where]
SHOW WARNINGS [LIMIT [offset,] row_count]

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.
214/3812
1.1.1.2.8.2 Extended Show
Contents
1. Examples

The following SHOW statements can be extended by using a WHERE clause and a LIKE clause to refine the results:
SHOW CHARACTER SET
SHOW COLLATION
SHOW COLUMNS
SHOW DATABASES
SHOW FUNCTION STATUS
SHOW INDEX
SHOW OPEN TABLES
SHOW PACKAGE STATUS
SHOW PACKAGE BODY STATUS
SHOW INDEX
SHOW PROCEDURE STATUS
SHOW STATUS
SHOW TABLE STATUS
SHOW TABLES
SHOW TRIGGERS
SHOW VARIABLES
As with a regular SELECT , the WHERE clause can be used for the specific columns returned, and the LIKE 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.

215/3812
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 |
+------------------------------------------+---------------------+

1.1.1.2.8.3 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 ***************************
216/3812
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
217/3812
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. This list all members and sponsors of the MariaDB Foundation and other sponsors.

1.1.1.2.8.4 SHOW BINARY LOGS


Syntax
SHOW BINARY LOGS
SHOW MASTER LOGS

Description
Lists the binary log files on the server. This statement is used as part of the procedure described in PURGE BINARY
LOGS , that shows how to determine which logs can be purged.

This statement requires the SUPER privilege, the REPLICATION_CLIENT privilege, or, from MariaDB 10.5.2, the
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 |
+--------------------+-----------+

218/3812
1.1.1.2.8.5 SHOW BINLOG EVENTS
Syntax
SHOW BINLOG EVENTS
[IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

Description
Shows the events in the binary log. If you do not specify ' log_name ', the first binary log is displayed.
Requires the BINLOG MONITOR privilege (>= MariaDB 10.5.2) or the REPLICATION SLAVE privilege (<= MariaDB
10.5.1).

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) |
+-------------------------------+-----+-------------------+-----------+-------------+------------------
------------------------------+

1.1.1.2.8.6 SHOW CHARACTER SET


Syntax
SHOW CHARACTER SET
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The SHOW CHARACTER SET statement shows all available character sets. 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.
The same information can be queried from the Information Schema CHARACTER_SETS table.
See Setting Character Sets and Collations for details on specifying the character set at the server, database, table and
column levels.

Examples
219/3812
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
Setting Character Sets and Collations
Information Schema CHARACTER_SETS

1.1.1.2.8.7 SHOW CLIENT_STATISTICS


Syntax
SHOW CLIENT_STATISTICS

Description
The SHOW CLIENT_STATISTICS statement is part of the User Statistics feature. It was removed as a separate statement
in MariaDB 10.1.1 , but effectively replaced by the generic SHOW information_schema_table statement. The
information_schema.CLIENT_STATISTICS table holds statistics about client connections.
The userstat system variable must be set to 1 to activate this feature. See the User Statistics and
information_schema.CLIENT_STATISTICS articles for more information.

Example

220/3812
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

1.1.1.2.8.8 SHOW COLLATION


1.1.1.2.8.9 SHOW COLUMNS
1.1.1.2.8.10 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 as well as other financial contributors.

Example

221/3812
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 .
SHOW AUTHORS list the authors of MariaDB (including documentation, QA etc).
MariaDB Foundation page on contributing financially

1.1.1.2.8.11 SHOW CREATE DATABASE


Syntax
SHOW CREATE {DATABASE | SCHEMA} db_name

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Shows the CREATE DATABASE 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 variable.

222/3812
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 off:

SHOW CREATE DATABASE test;


+----------+---------------------------------------------------------------+
| Database | Create Database |
+----------+---------------------------------------------------------------+
| test | CREATE DATABASE test /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+---------------------------------------------------------------+

With a comment, from MariaDB 10.5:

SHOW CREATE DATABASE p;


+----------+--------------------------------------------------------------------------------------+
| Database | Create Database |
+----------+--------------------------------------------------------------------------------------+
| p | CREATE DATABASE `p` /*!40100 DEFAULT CHARACTER SET latin1 */ COMMENT 'presentations' |
+----------+--------------------------------------------------------------------------------------+

See Also
CREATE DATABASE
ALTER DATABASE
Character Sets and Collations

1.1.1.2.8.12 SHOW CREATE EVENT


Syntax
SHOW CREATE EVENT event_name

Description
This statement displays the CREATE EVENT statement needed to re-create a given event, as well as the SQL_MODE 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 .
The output of this statement is unreliably affected by the sql_quote_show_create server system variable - see
http://bugs.mysql.com/bug.php?id=12719
The information_schema.EVENTS table provides similar, but more complete, information.

Examples

223/3812
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
CREATE EVENT
ALTER EVENT
DROP EVENT

1.1.1.2.8.13 SHOW CREATE FUNCTION


Syntax
SHOW CREATE FUNCTION func_name

Description
This statement is similar to SHOW CREATE PROCEDURE but for stored functions.
The output of this statement is unreliably affected by the 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
CREATE FUNCTION

1.1.1.2.8.14 SHOW CREATE PACKAGE


224/3812
MariaDB starting with 10.3.5
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
SHOW CREATE PACKAGE [ db_name . ] package_name

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The SHOW CREATE PACKAGE statement can be used when Oracle SQL_MODE 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_AUT
O_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
DROP PACKAGE
CREATE PACKAGE BODY
SHOW CREATE PACKAGE BODY
DROP PACKAGE BODY
Oracle SQL_MODE

1.1.1.2.8.15 SHOW CREATE PACKAGE


BODY
MariaDB starting with 10.3.5
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
SHOW CREATE PACKAGE BODY [ db_name . ] package_name

225/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The SHOW CREATE PACKAGE BODY statement can be used when Oracle SQL_MODE 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_AUT
O_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
SHOW CREATE PACKAGE
DROP PACKAGE
CREATE PACKAGE BODY
DROP PACKAGE BODY
Oracle SQL_MODE

226/3812
1.1.1.2.8.16 SHOW CREATE PROCEDURE
Syntax
SHOW CREATE PROCEDURE proc_name

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
This statement is a MariaDB extension. It returns the exact string that can be used to re-create the named stored
procedure, as well as the SQL_MODE that was used when the trigger has been created and the character set used by
the connection.. A similar statement, SHOW CREATE FUNCTION , displays information about stored functions.
Both statements require that you are the owner of the routine or have the SELECT privilege on the mysql.proc 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 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 variable - see
http://bugs.mysql.com/bug.php?id=12719

Examples
Here's a comparison of the SHOW CREATE PROCEDURE and SHOW CREATE FUNCTION 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 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 privilege on mysql.proc 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
227/3812
Stored Procedure Overview
CREATE PROCEDURE
ALTER PROCEDURE
DROP PROCEDURE
SHOW PROCEDURE STATUS
Stored Routine Privileges
Information Schema ROUTINES Table

1.1.1.2.8.17 SHOW CREATE SEQUENCE


MariaDB starting with 10.3.1
Sequences were introduced in MariaDB 10.3.

Syntax
SHOW CREATE SEQUENCE sequence_name;

Contents
1. Syntax
2. Description
3. Example
4. Notes
5. See Also

Description
Shows the CREATE SEQUENCE statement that created the given sequence. 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 on the
SEQUENCE . You can also use SELECT to read the current recorded state of the SEQUENCE :

228/3812
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
ALTER SEQUENCE

1.1.1.2.8.18 SHOW CREATE TABLE


1.1.1.2.8.19 SHOW CREATE TRIGGER
Syntax
SHOW CREATE TRIGGER trigger_name

Contents
1. Syntax
2. Description
3. Examples
4. See also

Description
This statement shows a CREATE TRIGGER statement that creates the given trigger, as well as the SQL_MODE that was
used when the trigger has been created and the character set used by the connection.
The output of this statement is unreliably affected by the sql_quote_show_create server system variable - see
http://bugs.mysql.com/bug.php?id=12719

Examples

229/3812
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


The Created column was added in MySQL 5.7 and MariaDB 10.2.3 as part of introducing multiple trigger events
per action.

See also
Trigger Overview
CREATE TRIGGER
DROP TRIGGER
information_schema.TRIGGERS Table
SHOW TRIGGERS
Trigger Limitations

1.1.1.2.8.20 SHOW CREATE USER


1.1.1.2.8.21 SHOW CREATE VIEW
Syntax
SHOW CREATE VIEW view_name

Description
This statement shows a CREATE VIEW statement that creates the given view, 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 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 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

230/3812
Grants
To be able to see a view, you need to have the SHOW VIEW and the SELECT privilege on the view:

GRANT SHOW VIEW,SELECT ON test_database.test_view TO 'test'@'localhost';

See Also
Grant privileges to tables, views etc

1.1.1.2.8.22 SHOW DATABASES


Syntax
SHOW {DATABASES | SCHEMAS}
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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.
You see only those databases for which you have some kind of privilege, unless you have the global SHOW
DATABASES privilege. You can also get this list using the mysqlshow 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.
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 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
ALTER DATABASE
DROP DATABASE
SHOW CREATE DATABASE
Character Sets and Collations
231/3812
Information Schema SCHEMATA Table

1.1.1.2.8.23 SHOW ENGINE


Contents
1. Syntax
2. Description
1. SHOW ENGINE INNODB STATUS
2. SHOW ENGINE INNODB MUTEX
3. SHOW ENGINE
PERFORMANCE_SCHEMA STATUS
4. SHOW ENGINE ROCKSDB STATUS

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 is installed, the following is also supported:

SHOW ENGINE SPHINX STATUS

See 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 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
232/3812
spin_rounds may indicate scalability problems.
The information_schema.INNODB_MUTEXES table provides similar information.

SHOW ENGINE PERFORMANCE_SCHEMA STATUS


This statement shows how much memory is used for performance_schema 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

1.1.1.2.8.24 SHOW ENGINE INNODB STATUS


SHOW ENGINE INNODB STATUS is a specific form of the SHOW ENGINE statement that displays the InnoDB Monitor
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 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) 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 for more. Similar
information is also available from the INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS 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 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
-----------------
233/3812
-----------------
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 234/3812
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
============================

1.1.1.2.8.25 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 table provides the same information.
Since storage engines are plugins, different information about them is also shown in the information_schema.PLUGINS
table and by the SHOW PLUGINS 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. The same applies to FederatedX .
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, XA transactions and transaction savepoints
are supported by the engine.

Examples

235/3812
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)

1.1.1.2.8.26 SHOW ERRORS


Syntax
236/3812
SHOW ERRORS [LIMIT [offset,] row_count]
SHOW ERRORS [LIMIT row_count OFFSET offset]
SHOW COUNT(*) ERRORS

Contents
1. Syntax
2. Description
3. Examples

Description
This statement is similar to SHOW WARNINGS, except that instead of displaying errors, warnings, and notes, it displays
only errors.
The LIMIT clause has the same syntax as for the SELECT statement.
The SHOW COUNT(*) ERRORS statement displays the number of errors. You can also retrieve this number from the
error_count variable.

SHOW COUNT(*) ERRORS;


SELECT @@error_count;

The value of error_count might be greater than the number of messages displayed by SHOW WARNINGS if the
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.

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 |
+-------+------+---------------------------+

1.1.1.2.8.27 SHOW EVENTS


Syntax
SHOW EVENTS [{FROM | IN} schema_name]
[LIKE 'pattern' | WHERE expr]

Description
Shows information about Event Manager events (created with CREATE EVENT ). Requires the EVENT privilege. Without
any arguments, SHOW EVENTS lists all of the events in the current schema:

237/3812
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 instead, or look at the information_schema.EVENTS 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.

1.1.1.2.8.28 SHOW FUNCTION CODE


1.1.1.2.8.29 SHOW FUNCTION STATUS
Syntax
SHOW FUNCTION STATUS
[LIKE 'pattern' | WHERE expr]

Description
This statement is similar to SHOW PROCEDURE STATUS but for stored functions.
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.
The information_schema.ROUTINES table contains more detailed information.

Examples
Showing all stored functions:

238/3812
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

1.1.1.2.8.30 SHOW GRANTS


1.1.1.2.8.31 SHOW INDEX
1.1.1.2.8.32 SHOW INDEX_STATISTICS
Syntax
SHOW INDEX_STATISTICS

Description
The SHOW INDEX_STATISTICS statement was introduced in MariaDB 5.2 as part of the User Statistics feature. It was
removed as a separate statement in MariaDB 10.1.1 , but effectively replaced by the generic SHOW
information_schema_table statement. The information_schmea.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.
The userstat system variable must be set to 1 to activate this feature. See the User Statistics and
information_schema.INDEX_STATISTICS table for more information.

239/3812
Example
SHOW INDEX_STATISTICS;
+--------------+-------------------+------------+-----------+
| Table_schema | Table_name | Index_name | Rows_read |
+--------------+-------------------+------------+-----------+
| test | employees_example | PRIMARY | 1 |
+--------------+-------------------+------------+-----------+

1.1.1.2.8.34 SHOW LOCALES


SHOW LOCALES was introduced as part of the Information Schema plugin extension .

SHOW LOCALES is used to return locales information as part of the Locales plugin. While the
information_schema.LOCALES 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 |
...

1.1.1.2.8.35 SHOW BINLOG STATUS


1.1.1.2.8.36 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.
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, each use of, for example, LOCK TABLE ... WRITE would increment In_use for that table. With the
implementation of the metadata locking improvements in MariaDB 5.5, 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 .

240/3812
Example
SHOW OPEN TABLES;
+----------+---------------------------+--------+-------------+
| Database | Table | In_use | Name_locked |
+----------+---------------------------+--------+-------------+
...
| test | xjson | 0 | 0 |
| test | jauthor | 0 | 0 |
| test | locks | 1 | 0 |
...
+----------+---------------------------+--------+-------------+

1.1.1.2.8.37 SHOW PACKAGE BODY STATUS


MariaDB starting with 10.3.5
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
SHOW PACKAGE BODY STATUS
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 , 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.
The ROUTINES table 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 CREATE PACKAGE BODY
CREATE PACKAGE BODY
DROP PACKAGE BODY
Oracle SQL_MODE

241/3812
1.1.1.2.8.38 SHOW PACKAGE STATUS
MariaDB starting with 10.3.5
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
SHOW PACKAGE STATUS
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 , 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.
The ROUTINES table 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 CREATE PACKAGE
CREATE PACKAGE
DROP PACKAGE
Oracle SQL_MODE

1.1.1.2.8.39 SHOW PLUGINS


1.1.1.2.8.40 SHOW PLUGINS SONAME
1.1.1.2.8.41 SHOW PRIVILEGES
Syntax
SHOW PRIVILEGES

242/3812
Description
SHOW PRIVILEGES shows the list of system privileges that the MariaDB server supports. The exact list of privileges
depends on the version of your server.
Note that before MariaDB 10.3.23, MariaDB 10.4.13 and MariaDB 10.5.2 , the Delete history privilege displays as
Delete versioning rows (MDEV-20382 ).

Example
From MariaDB 10.5.9

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
243/3812
| 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 shows how the user was created.
SHOW GRANTS shows the GRANTS/PRIVILEGES for a user.

1.1.1.2.8.42 SHOW PROCEDURE CODE


Syntax
SHOW PROCEDURE CODE proc_name

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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. A similar statement, SHOW
FUNCTION CODE , displays information about stored functions.
Both statements require that you be the owner of the routine or have SELECT access to the mysql.proc 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

244/3812
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
CREATE PROCEDURE
ALTER PROCEDURE
DROP PROCEDURE
SHOW CREATE PROCEDURE
SHOW PROCEDURE STATUS
Stored Routine Privileges
Information Schema ROUTINES Table

1.1.1.2.8.43 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 , 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.
The ROUTINES table 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
245/3812
Stored Procedure Overview
CREATE PROCEDURE
ALTER PROCEDURE
DROP PROCEDURE
SHOW CREATE PROCEDURE
Stored Routine Privileges
Information Schema ROUTINES Table

1.1.1.2.8.44 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 table or the mysqladmin processlist command. 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). 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.
The amount of time, in seconds, the process has been in its current state. For a replica SQL thread
TIME before MariaDB 10.1, this is the time in seconds between the last replicated event's timestamp and the
replica machine's real time.
STATE See Thread States.
INFO The statement being executed.
PROGRESS The total progress of the process (0-100%) (see Progress Reporting).

See TIME_MS column in information_schema.PROCESSLIST for differences in the TIME column between MariaDB and
MySQL.
The information_schema.PROCESSLIST 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 statement.
Since queries on this table are locking, if the performance_schema is enabled, you may want to query the THREADS
table instead.

246/3812
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()

1.1.1.2.8.45 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 statements display profiling information that indicates resource usage for
statements executed during the course of the current session.
Profiling is controlled by the 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 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 , 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

247/3812
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 table contains similar information.

Examples

248/3812
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 |
+----------------------+----------+----------+------------+

1.1.1.2.8.46 SHOW PROFILES


Syntax
SHOW PROFILES

Description
The SHOW PROFILES statement displays profiling information that indicates resource usage for statements executed
249/3812
during the course of the current session. It is used together with SHOW PROFILE .

1.1.1.2.8.47 SHOW
QUERY_RESPONSE_TIME
It is possible to use SHOW QUERY_RESPONSE_TIME as an alternative for retrieving information from the
QUERY_RESPONSE_TIME plugin.
This was introduced as part of the Information Schema plugin extension .

1.1.1.2.8.48 SHOW RELAYLOG EVENTS


1.1.1.2.8.49 SHOW REPLICA HOSTS
1.1.1.2.8.50 SHOW REPLICA STATUS
1.1.1.2.8.51 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 mysqladmin
extended-status command, or by querying the Information Schema GLOBAL_STATUS and SESSION_STATUS
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 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.

Examples
Full output from MariaDB 10.1.17 :

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 250/3812
| 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
|
| Aria_pagecache_blocks_used | 0
|
| Aria_pagecache_read_requests | 0
|
| Aria_pagecache_reads | 0
|
| Aria_pagecache_write_requests | 0
|
| Aria_pagecache_writes | 0
|
| Aria_transaction_log_syncs | 0
|
| Binlog_commits | 0
|
| Binlog_group_commits | 0
|
| Binlog_group_commit_trigger_count | 0
|
| Binlog_group_commit_trigger_lock_wait | 0
|
| Binlog_group_commit_trigger_timeout | 0
|
| Binlog_snapshot_file |
|
| Binlog_snapshot_position | 0
|
| Binlog_bytes_written | 0
|
| Binlog_cache_disk_use | 0
|
| Binlog_cache_use | 0
|
| Binlog_stmt_cache_disk_use | 0
|
| Binlog_stmt_cache_use | 0
|
| Busy_time | 0.000000
|
| Bytes_received | 432
|
| Bytes_sent | 15183
|
| Com_admin_commands | 1
|
| Com_alter_db | 0
|
| Com_alter_db_upgrade | 0
|
| Com_alter_event | 0
|
| Com_alter_function | 0
|
| Com_alter_procedure | 0
|
| Com_alter_server | 0
|
| Com_alter_table | 0
|
| Com_alter_tablespace | 0
|
| Com_analyze | 0
|
| Com_assign_to_keycache | 0
|
| Com_begin | 0
|
251/3812
| Com_binlog | 0
|
| Com_call_procedure | 0
|
| Com_change_db | 0
|
| Com_change_master | 0
|
| Com_check | 0
|
| Com_checksum | 0
|
| Com_commit | 0
|
| Com_compound_sql | 0
|
| Com_create_db | 0
|
| Com_create_event | 0
|
| Com_create_function | 0
|
| Com_create_index | 0
|
| Com_create_procedure | 0
|
| Com_create_role | 0
|
| Com_create_server | 0
|
| Com_create_table | 0
|
| Com_create_temporary_table | 0
|
| Com_create_trigger | 0
|
| Com_create_udf | 0
|
| Com_create_user | 0
|
| Com_create_view | 0
|
| Com_dealloc_sql | 0
|
| Com_delete | 0
|
| Com_delete_multi | 0
|
| Com_do | 0
|
| Com_drop_db | 0
|
| Com_drop_event | 0
|
| Com_drop_function | 0
|
| Com_drop_index | 0
|
| Com_drop_procedure | 0
|
| Com_drop_role | 0
|
| Com_drop_server | 0
|
| Com_drop_table | 0
|
| Com_drop_temporary_table | 0
|
| Com_drop_trigger | 0
|
| Com_drop_user | 0
|
| Com_drop_view | 0
|
| Com_empty_query | 0
|
| Com_execute_sql | 0
|
| Com_flush | 0
|
| Com_get_diagnostics | 0
|
252/3812
|
| Com_grant | 0
|
| Com_grant_role | 0
|
| Com_ha_close | 0
|
| Com_ha_open | 0
|
| Com_ha_read | 0
|
| Com_help | 0
|
| Com_insert | 0
|
| Com_insert_select | 0
|
| Com_install_plugin | 0
|
| Com_kill | 0
|
| Com_load | 0
|
| Com_lock_tables | 0
|
| Com_optimize | 0
|
| Com_preload_keys | 0
|
| Com_prepare_sql | 0
|
| Com_purge | 0
|
| Com_purge_before_date | 0
|
| Com_release_savepoint | 0
|
| Com_rename_table | 0
|
| Com_rename_user | 0
|
| Com_repair | 0
|
| Com_replace | 0
|
| Com_replace_select | 0
|
| Com_reset | 0
|
| Com_resignal | 0
|
| Com_revoke | 0
|
| Com_revoke_all | 0
|
| Com_revoke_role | 0
|
| Com_rollback | 0
|
| Com_rollback_to_savepoint | 0
|
| Com_savepoint | 0
|
| Com_select | 1
|
| Com_set_option | 0
|
| Com_show_authors | 0
|
| Com_show_binlog_events | 0
|
| Com_show_binlogs | 0
|
| Com_show_charsets | 0
|
| Com_show_collations | 0
|
| Com_show_contributors | 0
|
| Com_show_create_db | 0
|
| Com_show_create_event | 0
| 253/3812
|
| Com_show_create_func | 0
|
| Com_show_create_proc | 0
|
| Com_show_create_table | 0
|
| Com_show_create_trigger | 0
|
| Com_show_databases | 0
|
| Com_show_engine_logs | 0
|
| Com_show_engine_mutex | 0
|
| Com_show_engine_status | 0
|
| Com_show_errors | 0
|
| Com_show_events | 0
|
| Com_show_explain | 0
|
| Com_show_fields | 0
|
| Com_show_function_status | 0
|
| Com_show_generic | 0
|
| Com_show_grants | 0
|
| Com_show_keys | 0
|
| Com_show_master_status | 0
|
| Com_show_open_tables | 0
|
| Com_show_plugins | 0
|
| Com_show_privileges | 0
|
| Com_show_procedure_status | 0
|
| Com_show_processlist | 0
|
| Com_show_profile | 0
|
| Com_show_profiles | 0
|
| Com_show_relaylog_events | 0
|
| Com_show_slave_hosts | 0
|
| Com_show_slave_status | 0
|
| Com_show_status | 2
|
| Com_show_storage_engines | 0
|
| Com_show_table_status | 0
|
| Com_show_tables | 0
|
| Com_show_triggers | 0
|
| Com_show_variables | 0
|
| Com_show_warnings | 0
|
| Com_shutdown | 0
|
| Com_signal | 0
|
| Com_start_all_slaves | 0
|
| Com_start_slave | 0
|
| Com_stmt_close | 0
|
| Com_stmt_execute | 0
|
| Com_stmt_fetch | 0
254/3812
| Com_stmt_fetch | 0
|
| Com_stmt_prepare | 0
|
| Com_stmt_reprepare | 0
|
| Com_stmt_reset | 0
|
| Com_stmt_send_long_data | 0
|
| Com_stop_all_slaves | 0
|
| Com_stop_slave | 0
|
| Com_truncate | 0
|
| Com_uninstall_plugin | 0
|
| Com_unlock_tables | 0
|
| Com_update | 0
|
| Com_update_multi | 0
|
| Com_xa_commit | 0
|
| Com_xa_end | 0
|
| Com_xa_prepare | 0
|
| Com_xa_recover | 0
|
| Com_xa_rollback | 0
|
| Com_xa_start | 0
|
| Compression | OFF
|
| Connection_errors_accept | 0
|
| Connection_errors_internal | 0
|
| Connection_errors_max_connections | 0
|
| Connection_errors_peer_address | 0
|
| Connection_errors_select | 0
|
| Connection_errors_tcpwrap | 0
|
| Connections | 4
|
| Cpu_time | 0.000000
|
| Created_tmp_disk_tables | 0
|
| Created_tmp_files | 6
|
| Created_tmp_tables | 2
|
| Delayed_errors | 0
|
| Delayed_insert_threads | 0
|
| Delayed_writes | 0
|
| Delete_scan | 0
|
| Empty_queries | 0
|
| Executed_events | 0
|
| Executed_triggers | 0
|
| Feature_delay_key_write | 0
|
| Feature_dynamic_columns | 0
|
| Feature_fulltext | 0
|
| Feature_gis | 0
|
| Feature_locale | 0
255/3812
| Feature_locale | 0
|
| Feature_subquery | 0
|
| Feature_timezone | 0
|
| Feature_trigger | 0
|
| Feature_xml | 0
|
| Flush_commands | 1
|
| Handler_commit | 1
|
| Handler_delete | 0
|
| Handler_discover | 0
|
| Handler_external_lock | 0
|
| Handler_icp_attempts | 0
|
| Handler_icp_match | 0
|
| Handler_mrr_init | 0
|
| Handler_mrr_key_refills | 0
|
| Handler_mrr_rowid_refills | 0
|
| Handler_prepare | 0
|
| Handler_read_first | 3
|
| Handler_read_key | 0
|
| Handler_read_last | 0
|
| Handler_read_next | 0
|
| Handler_read_prev | 0
|
| Handler_read_retry | 0
|
| Handler_read_rnd | 0
|
| Handler_read_rnd_deleted | 0
|
| Handler_read_rnd_next | 537
|
| Handler_rollback | 0
|
| Handler_savepoint | 0
|
| Handler_savepoint_rollback | 0
|
| Handler_tmp_update | 0
|
| Handler_tmp_write | 516
|
| Handler_update | 0
|
| Handler_write | 0
|
| Innodb_available_undo_logs | 128
|
| Innodb_background_log_sync | 222
|
| Innodb_buffer_pool_bytes_data | 2523136
|
| Innodb_buffer_pool_bytes_dirty | 0
|
| Innodb_buffer_pool_dump_status | Dumping buffer pool(s) not yet started
|
| Innodb_buffer_pool_load_status | Loading buffer pool(s) not yet started
|
| Innodb_buffer_pool_pages_data | 154
|
| Innodb_buffer_pool_pages_dirty | 0
|
| Innodb_buffer_pool_pages_flushed | 1
|
| Innodb_buffer_pool_pages_free | 8037 256/3812
| Innodb_buffer_pool_pages_free | 8037
|
| Innodb_buffer_pool_pages_lru_flushed | 0
|
| Innodb_buffer_pool_pages_made_not_young | 0
|
| Innodb_buffer_pool_pages_made_young | 0
|
| Innodb_buffer_pool_pages_misc | 0
|
| Innodb_buffer_pool_pages_old | 0
|
| Innodb_buffer_pool_pages_total | 8191
|
| Innodb_buffer_pool_read_ahead | 0
|
| Innodb_buffer_pool_read_ahead_evicted | 0
|
| Innodb_buffer_pool_read_ahead_rnd | 0
|
| Innodb_buffer_pool_read_requests | 558
|
| Innodb_buffer_pool_reads | 155
|
| Innodb_buffer_pool_wait_free | 0
|
| Innodb_buffer_pool_write_requests | 1
|
| Innodb_checkpoint_age | 0
|
| Innodb_checkpoint_max_age | 80826164
|
| Innodb_data_fsyncs | 5
|
| Innodb_data_pending_fsyncs | 0
|
| Innodb_data_pending_reads | 0
|
| Innodb_data_pending_writes | 0
|
| Innodb_data_read | 2609664
|
| Innodb_data_reads | 172
|
| Innodb_data_writes | 5
|
| Innodb_data_written | 34304
|
| Innodb_dblwr_pages_written | 1
|
| Innodb_dblwr_writes | 1
|
| Innodb_deadlocks | 0
|
| Innodb_have_atomic_builtins | ON
|
| Innodb_history_list_length | 0
|
| Innodb_ibuf_discarded_delete_marks | 0
|
| Innodb_ibuf_discarded_deletes | 0
|
| Innodb_ibuf_discarded_inserts | 0
|
| Innodb_ibuf_free_list | 0
|
| Innodb_ibuf_merged_delete_marks | 0
|
| Innodb_ibuf_merged_deletes | 0
|
| Innodb_ibuf_merged_inserts | 0
|
| Innodb_ibuf_merges | 0
|
| Innodb_ibuf_segment_size | 2
|
| Innodb_ibuf_size | 1
|
| Innodb_log_waits | 0
|
| Innodb_log_write_requests | 0
|
257/3812
|
| Innodb_log_writes | 1
|
| Innodb_lsn_current | 1616829
|
| Innodb_lsn_flushed | 1616829
|
| Innodb_lsn_last_checkpoint | 1616829
|
| Innodb_master_thread_active_loops | 0
|
| Innodb_master_thread_idle_loops | 222
|
| Innodb_max_trx_id | 2308
|
| Innodb_mem_adaptive_hash | 2217568
|
| Innodb_mem_dictionary | 630703
|
| Innodb_mem_total | 140771328
|
| Innodb_mutex_os_waits | 1
|
| Innodb_mutex_spin_rounds | 30
|
| Innodb_mutex_spin_waits | 1
|
| Innodb_oldest_view_low_limit_trx_id | 0
|
| Innodb_os_log_fsyncs | 3
|
| Innodb_os_log_pending_fsyncs | 0
|
| Innodb_os_log_pending_writes | 0
|
| Innodb_os_log_written | 512
|
| Innodb_page_size | 16384
|
| Innodb_pages_created | 0
|
| Innodb_pages_read | 154
|
| Innodb_pages_written | 1
|
| Innodb_purge_trx_id | 0
|
| Innodb_purge_undo_no | 0
|
| Innodb_read_views_memory | 88
|
| Innodb_row_lock_current_waits | 0
|
| Innodb_row_lock_time | 0
|
| Innodb_row_lock_time_avg | 0
|
| Innodb_row_lock_time_max | 0
|
| Innodb_row_lock_waits | 0
|
| Innodb_rows_deleted | 0
|
| Innodb_rows_inserted | 0
|
| Innodb_rows_read | 0
|
| Innodb_rows_updated | 0
|
| Innodb_system_rows_deleted | 0
|
| Innodb_system_rows_inserted | 0
|
| Innodb_system_rows_read | 0
|
| Innodb_system_rows_updated | 0
|
| Innodb_s_lock_os_waits | 2
|
| Innodb_s_lock_spin_rounds | 60
|
| Innodb_s_lock_spin_waits | 2
| 258/3812
|
| Innodb_truncated_status_writes | 0
|
| Innodb_x_lock_os_waits | 0
|
| Innodb_x_lock_spin_rounds | 0
|
| Innodb_x_lock_spin_waits | 0
|
| Innodb_page_compression_saved | 0
|
| Innodb_page_compression_trim_sect512 | 0
|
| Innodb_page_compression_trim_sect1024 | 0
|
| Innodb_page_compression_trim_sect2048 | 0
|
| Innodb_page_compression_trim_sect4096 | 0
|
| Innodb_page_compression_trim_sect8192 | 0
|
| Innodb_page_compression_trim_sect16384 | 0
|
| Innodb_page_compression_trim_sect32768 | 0
|
| Innodb_num_index_pages_written | 0
|
| Innodb_num_non_index_pages_written | 5
|
| Innodb_num_pages_page_compressed | 0
|
| Innodb_num_page_compressed_trim_op | 0
|
| Innodb_num_page_compressed_trim_op_saved | 0
|
| Innodb_num_pages_page_decompressed | 0
|
| Innodb_num_pages_page_compression_error | 0
|
| Innodb_num_pages_encrypted | 0
|
| Innodb_num_pages_decrypted | 0
|
| Innodb_have_lz4 | OFF
|
| Innodb_have_lzo | OFF
|
| Innodb_have_lzma | OFF
|
| Innodb_have_bzip2 | OFF
|
| Innodb_have_snappy | OFF
|
| Innodb_defragment_compression_failures | 0
|
| Innodb_defragment_failures | 0
|
| Innodb_defragment_count | 0
|
| Innodb_onlineddl_rowlog_rows | 0
|
| Innodb_onlineddl_rowlog_pct_used | 0
|
| Innodb_onlineddl_pct_progress | 0
|
| Innodb_secondary_index_triggered_cluster_reads | 0
|
| Innodb_secondary_index_triggered_cluster_reads_avoided | 0
|
| Innodb_encryption_rotation_pages_read_from_cache | 0
|
| Innodb_encryption_rotation_pages_read_from_disk | 0
|
| Innodb_encryption_rotation_pages_modified | 0
|
| Innodb_encryption_rotation_pages_flushed | 0
|
| Innodb_encryption_rotation_estimated_iops | 0
|
| Innodb_scrub_background_page_reorganizations | 0
|
| Innodb_scrub_background_page_splits | 0
259/3812
|
| Innodb_scrub_background_page_split_failures_underflow | 0
|
| Innodb_scrub_background_page_split_failures_out_of_filespace | 0
|
| Innodb_scrub_background_page_split_failures_missing_index | 0
|
| Innodb_scrub_background_page_split_failures_unknown | 0
|
| 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
|
| Last_query_cost | 0.000000
|
| Master_gtid_wait_count | 0
|
| Master_gtid_wait_time | 0
|
| Master_gtid_wait_timeouts | 0
|
| Max_statement_time_exceeded | 0
|
| Max_used_connections | 1
|
| Memory_used | 273614696
|
| Not_flushed_delayed_rows | 0
|
| Open_files | 25
|
| Open_streams | 0
|
| Open_table_definitions | 18
|
| Open_tables | 11
|
| Opened_files | 77
|
| Opened_plugin_libraries | 0
|
| Opened_table_definitions | 18
|
| Opened_tables | 18
|
| Opened_views | 0
|
| Performance_schema_accounts_lost | 0
|
| Performance_schema_cond_classes_lost | 0
|
| Performance_schema_cond_instances_lost | 0
|
| Performance_schema_digest_lost | 0
|
| Performance_schema_file_classes_lost | 0
|
| Performance_schema_file_handles_lost | 0
|
| Performance_schema_file_instances_lost | 0
|
| Performance_schema_hosts_lost | 0
|
| Performance_schema_locker_lost | 0
|
| Performance_schema_mutex_classes_lost | 0
|
| Performance_schema_mutex_instances_lost | 0
|
| Performance_schema_rwlock_classes_lost | 0
260/3812
| Performance_schema_rwlock_classes_lost | 0
|
| Performance_schema_rwlock_instances_lost | 0
|
| Performance_schema_session_connect_attrs_lost | 0
|
| Performance_schema_socket_classes_lost | 0
|
| Performance_schema_socket_instances_lost | 0
|
| Performance_schema_stage_classes_lost | 0
|
| Performance_schema_statement_classes_lost | 0
|
| Performance_schema_table_handles_lost | 0
|
| Performance_schema_table_instances_lost | 0
|
| Performance_schema_thread_classes_lost | 0
|
| Performance_schema_thread_instances_lost | 0
|
| Performance_schema_users_lost | 0
|
| Prepared_stmt_count | 0
|
| Qcache_free_blocks | 1
|
| Qcache_free_memory | 1031336
|
| Qcache_hits | 0
|
| Qcache_inserts | 0
|
| Qcache_lowmem_prunes | 0
|
| Qcache_not_cached | 0
|
| Qcache_queries_in_cache | 0
|
| Qcache_total_blocks | 1
|
| Queries | 4
|
| Questions | 4
|
| Rows_read | 10
|
| Rows_sent | 517
|
| Rows_tmp_read | 516
|
| Rpl_status | AUTH_MASTER
|
| Select_full_join | 0
|
| Select_full_range_join | 0
|
| Select_range | 0
|
| Select_range_check | 0
|
| Select_scan | 2
|
| Slave_connections | 0
|
| Slave_heartbeat_period | 0.000
|
| Slave_open_temp_tables | 0
|
| Slave_received_heartbeats | 0
|
| Slave_retried_transactions | 0
|
| Slave_running | OFF
|
| Slave_skipped_errors | 0
|
| Slaves_connected | 0
|
| Slaves_running | 0
|
| Slow_launch_threads | 0 261/3812
| Slow_launch_threads | 0
|
| Slow_queries | 0
|
| Sort_merge_passes | 0
|
| Sort_priority_queue_sorts | 0
|
| Sort_range | 0
|
| Sort_rows | 0
|
| Sort_scan | 0
|
| Ssl_accept_renegotiates | 0
|
| Ssl_accepts | 0
|
| Ssl_callback_cache_hits | 0
|
| Ssl_cipher |
|
| Ssl_cipher_list |
|
| Ssl_client_connects | 0
|
| Ssl_connect_renegotiates | 0
|
| Ssl_ctx_verify_depth | 0
|
| Ssl_ctx_verify_mode | 0
|
| Ssl_default_timeout | 0
|
| Ssl_finished_accepts | 0
|
| Ssl_finished_connects | 0
|
| Ssl_server_not_after |
|
| Ssl_server_not_before |
|
| Ssl_session_cache_hits | 0
|
| Ssl_session_cache_misses | 0
|
| Ssl_session_cache_mode | NONE
|
| Ssl_session_cache_overflows | 0
|
| Ssl_session_cache_size | 0
|
| Ssl_session_cache_timeouts | 0
|
| Ssl_sessions_reused | 0
|
| Ssl_used_session_cache_entries | 0
|
| Ssl_verify_depth | 0
|
| Ssl_verify_mode | 0
|
| Ssl_version |
|
| Subquery_cache_hit | 0
|
| Subquery_cache_miss | 0
|
| Syncs | 2
|
| Table_locks_immediate | 21
|
| Table_locks_waited | 0
|
| Tc_log_max_pages_used | 0
|
| Tc_log_page_size | 4096
|
| Tc_log_page_waits | 0
|
| Threadpool_idle_threads | 0
|
262/3812
| Threadpool_threads | 0
|
| Threads_cached | 0
|
| Threads_connected | 1
|
| Threads_created | 2
|
| Threads_running | 1
|
| Update_scan | 0
|
| Uptime | 223
|
| Uptime_since_flush_status | 223
|
| wsrep_cluster_conf_id | 18446744073709551615
|
| wsrep_cluster_size | 0
|
| wsrep_cluster_state_uuid |
|
| wsrep_cluster_status | Disconnected
|
| wsrep_connected | OFF
|
| wsrep_local_bf_aborts | 0
|
| 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)

1.1.1.2.8.52 SHOW TABLE STATUS


Syntax
SHOW TABLE STATUS [{FROM | IN} db_name]
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Views
4. Example

263/3812
Description
SHOW TABLE STATUS works like SHOW TABLES , but provides more extensive information about each non- TEMPORARY
table.
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.
The following information is returned:

Column Description
Name Table name.
Engine Table storage engine.
Version Version number from the table's .frm file.
Row_format Row format (see InnoDB, Aria and MyISAM row formats).
Rows Number of rows in the table. Some engines, such as XtraDB and InnoDB may store an estimate.
Avg_row_length Average row length in the table.
For InnoDB/XtraDB, the index size, in pages, multiplied by the page size. For Aria and MyISAM,
Data_length
length of the data file, in bytes. For MEMORY, the approximate allocated memory.
Maximum length of the data file, ie the total number of bytes that could be stored in the table. Not
Max_data_length
used in XtraDB and InnoDB.
Index_length Length of the index file.
Bytes allocated but unused. For InnoDB tables in a shared tablespace, the free space of the
Data_free shared tablespace with small safety margin. An estimate in the case of partitioned tables - see the
PARTITIONS table.

Auto_increment Next AUTO_INCREMENT value.


Time the table was created. Some engines just return the ctime information from the file system
Create_time 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.
Time the table was last updated. On Windows, the timestamp is not updated on update, so
MyISAM values will be inaccurate. In InnoDB, if shared tablespaces are used, will be NULL , while
Update_time
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.
Checksum Live checksum value, if any.
Create_options Extra CREATE TABLE options.
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.
Placeholder to signal that a table is a temporary table. Currently always "N", except "Y" for
Temporary
generated information_schema tables and NULL for views. Added in MariaDB 10.3.5.

Similar information can be found in the information_schema.TABLES table as well as by using mysqlshow :

mysqlshow --status db_name

Views
For views, all columns in SHOW TABLE STATUS are NULL except 'Name' and 'Comment'

Example

264/3812
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:

1.1.1.2.8.53 SHOW TABLES


Syntax
SHOW [FULL] TABLES [FROM db_name]
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
SHOW TABLES lists the non- TEMPORARY tables, sequences and views 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. 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 and SEQUENCE for a sequence.
You can also get this information using:

mysqlshow db_name

See mysqlshow 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 mysqlshow
db_name .
The information_schema.TABLES table, as well as the SHOW TABLE STATUS statement, provide extended
information about tables.

Examples
SHOW TABLES;
+----------------------+
| Tables_in_test |
+----------------------+
| animal_count |
| animals |
| are_the_mooses_loose |
| aria_test2 |
| t1 |
| view1 |
+----------------------+

265/3812
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 |
+----------------+------------+

See Also
SHOW TABLE STATUS
The information_schema.TABLES table

1.1.1.2.8.54 SHOW TABLE_STATISTICS


Syntax
SHOW TABLE_STATISTICS

Description
The SHOW TABLE_STATISTICS statementis part of the User Statistics feature. It was removed as a separate statement in
MariaDB 10.1.1 , but effectively replaced by the generic SHOW information_schema_table statement. The
information_schema.TABLE_STATISTICS table shows statistics on table usage
The userstat system variable must be set to 1 to activate this feature. See the User Statistics and
information_schema.TABLE_STATISTICS articles for more information.

Example

266/3812
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

1.1.1.2.8.55 SHOW TRIGGERS


Syntax
SHOW TRIGGERS [FROM db_name]
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Examples
4. See also

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 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.
Similar information is stored in the information_schema.TRIGGERS table.

MariaDB starting with 10.2.3


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:

267/3812
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 system variable when the trigger was
created.
collation_connection is the session value of the 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 has NULL in the Created column.

See also
Trigger Overview
CREATE TRIGGER
DROP TRIGGER
information_schema.TRIGGERS table
SHOW CREATE TRIGGER
Trigger Limitations

268/3812
1.1.1.2.8.56 SHOW USER_STATISTICS
Syntax
SHOW USER_STATISTICS

Description
The SHOW USER_STATISTICS statement is part of the User Statistics feature. It was removed as a separate statement in
MariaDB 10.1.1 , but effectively replaced by the generic SHOW information_schema_table statement. The
information_schema.USER_STATISTICS 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 system variable must be set to 1 to activate this feature. See the User Statistics and
information_schema.USER_STATISTICS 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

1.1.1.2.8.57 SHOW VARIABLES


Syntax
SHOW [GLOBAL | SESSION] VARIABLES
[LIKE 'pattern' | WHERE expr]

Contents
1. Syntax
2. Description
3. Examples

Description
SHOW VARIABLES shows the values of MariaDB system variables. This information also can be obtained using the
mysqladmin variables 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
269/3812
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.
See SET for information on setting server system variables.
See Server System Variables 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 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 |
+------------------------------------------+---------------------+

270/3812
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 |
+------------------------+-------+

1.1.1.2.8.58 SHOW WARNINGS


Syntax
SHOW WARNINGS [LIMIT [offset,] row_count]
SHOW ERRORS [LIMIT row_count OFFSET offset]
SHOW COUNT(*) WARNINGS

Contents
1. Syntax
2. Description
3. Examples
1. Stack Trace
4. See Also

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.
271/3812
A note is different to a warning in that it only appears if the sql_notes variable is set to 1 (the default), and is not
converted to an error if strict mode is enabled.
A related statement, SHOW ERRORS , 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 variable:

SHOW COUNT(*) WARNINGS;


SELECT @@warning_count;

The value of warning_count might be greater than the number of messages displayed by SHOW WARNINGS if the
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 .
SHOW WARNINGS can be used after EXPLAIN EXTENDED to see how a query is internally rewritten by MariaDB.
If the 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 statement instead.
For a list of MariaDB error codes, see MariaDB Error Codes.
The mysql 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 10.3.1 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
From MariaDB 10.3.1, displaying a stack trace:

272/3812
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

1.1.1.2.8.59 SHOW WSREP_MEMBERSHIP


SHOW WSREP_MEMBERSHIP is part of the WSREP_INFO plugin.

Syntax
SHOW WSREP_MEMBERSHIP

Description
The SHOW WSREP_MEMBERSHIP statement returns Galera node cluster membership information. It returns the same
information as found in the information_schema.WSREP_MEMBERSHIP table. Only users with the SUPER 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 |
+-------+--------------------------------------+----------+-----------------+

1.1.1.2.8.60 SHOW WSREP_STATUS


SHOW WSREP_STATUS is part of the WSREP_INFO plugin.

Syntax
273/3812
SHOW WSREP_STATUS

Description
The SHOW WSREP_STATUS statement returns Galera node and cluster status information. It returns the same information
as found in the information_schema.WSREP_STATUS table. Only users with the SUPER privilege can access this
information.

Examples
SHOW WSREP_STATUS;
+------------+-------------+----------------+--------------+
| Node_Index | Node_Status | Cluster_Status | Cluster_Size |
+------------+-------------+----------------+--------------+
| 0 | Synced | Primary | 3 |
+------------+-------------+----------------+--------------+

1.1.1.2.9 System Tables


Information Schema
Articles about the Information Schema

Performance Schema
Monitoring server performance.

The mysql Database Tables


mysql database tables.

Sys Schema
Collection of views, functions and procedures to help administrators get in...

mariadb_schema
mariadb_schema is used to enforce MariaDB native types independent of SQL_MODE.

Writing Logs Into Tables


The general query log and the slow query log can be written into system tables

1.1.1.2.9.1 Information Schema


Articles about the Information Schema
Information Schema Tables
Tables in the Information_Schema database

Extended Show
Extended SHOW with WHERE and LIKE.

TIME_MS column in INFORMATION_SCHEMA.PROCESSLIST


Microseconds in the INFORMATION_SCHEMA.PROCESSLIST table

There are 1 related questions .

1.1.1.2.9.1.1 Information Schema Tables


Information Schema InnoDB Tables
All InnoDB-specific Information Schema tables.

Information Schema MyRocks Tables


List of Information Schema tables specifically related to MyRocks.

Information Schema XtraDB Tables


All XtraDB-specific Information Schema tables.
274/3812
ColumnStore Information Schema Tables
ColumnStore-related Information Schema tables

Information Schema ALL_PLUGINS Table


Information about server plugins, whether installed or not.

Information Schema APPLICABLE_ROLES Table


Roles available to be used.

Information Schema CHARACTER_SETS Table


Supported character sets.

Information Schema CHECK_CONSTRAINTS Table


Supported check constraints.

Information Schema CLIENT_STATISTICS Table


Statistics about client connections.

Information Schema COLLATION_CHARACTER_SET_APPLICABILITY Table


Collations and associated character sets

Information Schema COLLATIONS Table


Supported collations.

Information Schema COLUMN_PRIVILEGES Table


Column privileges

Information Schema COLUMNS Table


Information about table fields.

Information Schema DISKS Table


Plugin that allows the disk space situation to be monitored.

Information Schema ENABLED_ROLES Table


Enabled roles for the current session.

Information Schema ENGINES Table


Storage engine information.

Information Schema EVENTS Table


Server event information

Information Schema FEEDBACK Table


Contents submitted by the Feedback Plugin

Information Schema FILES Table


The FILES tables is unused in MariaDB.

Information Schema GEOMETRY_COLUMNS Table


Support for Spatial Reference systems for GIS data

Information Schema GLOBAL_STATUS and SESSION_STATUS Tables


Global and session status variables

Information Schema GLOBAL_VARIABLES and SESSION_VARIABLES Tables


Global and session system variables

Information Schema INDEX_STATISTICS Table


Statistics on index usage

Information Schema KEY_CACHES Table


Segmented key cache statistics.

Information Schema KEY_COLUMN_USAGE Table


Key columns that have constraints.

Information Schema KEYWORDS Table


MariaDB keywords.

275/3812
Information Schema LOCALES Table
Compiled-in server locales.

Information Schema METADATA_LOCK_INFO Table


Active metadata locks.

Information Schema MROONGA_STATS Table


Mroonga activities statistics.

Information Schema OPTIMIZER_TRACE Table


Contains Optimizer Trace information.

Information Schema PARAMETERS Table


Information about stored procedures and stored functions parameters.

Information Schema PARTITIONS Table


Table partition information

Information Schema PLUGINS Table


Information Schema table containing information on plugins installed on a server.

Information Schema PROCESSLIST Table


Thread information.

Information Schema PROFILING Table


Statement resource usage

Information Schema QUERY_CACHE_INFO Table


View the contents of the query cache.

Information Schema QUERY_RESPONSE_TIME Table


Query time information.

Information Schema REFERENTIAL_CONSTRAINTS Table


Foreign key information

Information Schema ROUTINES Table


Stored procedures and stored functions information

Information Schema SCHEMA_PRIVILEGES Table


Database privilege information

Information Schema SCHEMATA Table


Information about databases.

Information Schema SPATIAL_REF_SYS Table


Information on each spatial reference system used in the database

Information Schema SPIDER_ALLOC_MEM Table


Information about Spider's memory usage.

Information Schema SPIDER_WRAPPER_PROTOCOLS Table


Installed along with the Spider storage engine.

Information Schema SQL_FUNCTIONS Table


Functions in MariaDB.

Information Schema STATISTICS Table


Table index information.

Information Schema SYSTEM_VARIABLES Table


Current global and session values and various metadata of all system variables.

Information Schema TABLE_CONSTRAINTS Table


Tables containing constraints.

Information Schema TABLE_PRIVILEGES Table


Table privileges

276/3812
Information Schema TABLE_STATISTICS Table
Statistics on table usage.

Information Schema TABLES Table


Database table information.

Information Schema TABLESPACES Table


Information about active tablespaces.

Information Schema THREAD_POOL_GROUPS Table


Information Schema THREAD_POOL_GROUPS Table.

Information Schema THREAD_POOL_QUEUES Table


Information Schema THREAD_POOL_QUEUES Table.

Information Schema THREAD_POOL_STATS Table


Information Schema THREAD_POOL_STATS Table.

Information Schema THREAD_POOL_WAITS Table


Information Schema THREAD_POOL_WAITS Table.

Information Schema TRIGGERS Table


Information about triggers

Information Schema USER_PRIVILEGES Table


Global user privilege information derived from the mysql.user grant table

Information Schema USER_STATISTICS Table


User activity

Information Schema USER_VARIABLES Table


User-defined variable information.

Information Schema VIEWS Table


Information about views.

Information Schema WSREP_MEMBERSHIP Table


Galera node cluster membership information.

Information Schema WSREP_STATUS Table


Galera node cluster status information.

There are 2 related questions .

1.1.1.2.9.1.1.1 Information Schema InnoDB


Tables
List of Information Schema tables specifically related to InnoDB. Tables that are specific to XtraDB shares with InnoDB
are listed in Information Schema XtraDB Tables .
Information Schema INNODB_BUFFER_PAGE Table
Buffer pool page information.

Information Schema INNODB_BUFFER_PAGE_LRU Table


Buffer pool pages and their eviction order.

Information Schema INNODB_BUFFER_POOL_PAGES Table


XtraDB buffer pool page information.

Information Schema INNODB_BUFFER_POOL_PAGES_BLOB Table


XtraDB buffer pool blob pages.

Information Schema INNODB_BUFFER_POOL_PAGES_INDEX Table


XtraDB buffer pool index pages.

277/3812
Information Schema INNODB_BUFFER_POOL_STATS Table
InnoDB buffer pool information.

Information Schema INNODB_CHANGED_PAGES Table


Modified pages from the bitmap file data.

Information Schema INNODB_CMP and INNODB_CMP_RESET Tables


XtraDB/InnoDB compression performances with different page sizes.

Information Schema INNODB_CMPMEM and INNODB_CMPMEM_RESET Tables


Number of InnoDB compressed pages of different page sizes.

Information Schema INNODB_CMP_PER_INDEX and


INNODB_CMP_PER_INDEX_RESET Tables
XtraDB/InnoDB compression performances for different indexes and tables.

Information Schema INNODB_FT_BEING_DELETED Table


Fulltext being deleted.

Information Schema INNODB_FT_CONFIG Table


InnoDB fulltext metadata.

Information Schema INNODB_FT_DEFAULT_STOPWORD Table


Default InnoDB stopwords.

Information Schema INNODB_FT_DELETED Table


Deleted InnoDB fulltext rows.

Information Schema INNODB_FT_INDEX_CACHE Table


Newly added fulltext row information.

Information Schema INNODB_FT_INDEX_TABLE Table


InnoDB fulltext information.

Information Schema INNODB_LOCK_WAITS Table


Blocked InnoDB transactions.

Information Schema INNODB_LOCKS Table


2 InnoDB lock information.

Information Schema INNODB_METRICS Table


InnoDB performance metrics.

Information Schema INNODB_MUTEXES Table


Monitor mutex waits.

Information Schema INNODB_SYS_COLUMNS Table


InnoDB column information.

Information Schema INNODB_SYS_DATAFILES Table


InnoDB tablespace paths.

Information Schema INNODB_SYS_FIELDS Table


Fields part of an InnoDB index.

Information Schema INNODB_SYS_FOREIGN Table


InnoDB foreign key information.

Information Schema INNODB_SYS_FOREIGN_COLS Table


Foreign key column information.

Information Schema INNODB_SYS_INDEXES Table


InnoDB index information.

Information Schema INNODB_SYS_SEMAPHORE_WAITS Table


Information about current semaphore waits.

278/3812
Information Schema INNODB_SYS_TABLES Table
InnoDB table information.

Information Schema INNODB_SYS_TABLESPACES Table


InnoDB tablespace information.

Information Schema INNODB_SYS_TABLESTATS Table


InnoDB status for high-level performance monitoring.

Information Schema INNODB_SYS_VIRTUAL Table


Information about base columns of virtual columns.

Information Schema INNODB_TABLESPACES_ENCRYPTION Table


Encryption metadata for InnoDB tablespaces.

Information Schema INNODB_TABLESPACES_SCRUBBING Table


Data scrubbing information.

Information Schema INNODB_TRX Table


Currently-executing InnoDB locks.

Information Schema TEMP_TABLES_INFO Table


Information about active InnoDB temporary tables.

1.1.1.2.9.1.1.1.1 Information Schema


INNODB_BUFFER_PAGE Table
The Information Schema INNODB_BUFFER_PAGE table contains information about pages in the buffer pool.
The PROCESS privilege is required to view the table.
It has the following columns:

Column Description
Buffer Pool identifier. From MariaDB 10.5.1 returns a value of 0, since multiple InnoDB buffer
POOL_ID
pool instances has been removed.
BLOCK_ID Buffer Pool Block identifier.
SPACE Tablespace identifier. Matches the SPACE value in the INNODB_SYS_TABLES table.
PAGE_NUMBER Buffer pool page number.
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),
PAGE_TYPE
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.

Count of the threads using this block in the buffer pool. When it is zero, the block can be
FIX_COUNT
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.

279/3812
Page state; one of FILE_PAGE (page from a file) or MEMORY (page from an in-memory object)
PAGE_STATE
for valid data, or one of NULL , READY_FOR_USE , NOT_USED , REMOVE_HASH .
Whether there is I/O pending for the page; one of IO_NONE (no pending I/O), IO_READ (read
IO_FIX
pending), IO_WRITE (write pending).
IS_OLD Whether the page is old or not.
Freed_page_clock counter, which tracks the number of blocks removed from the end of the
FREE_PAGE_CLOCK
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 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
...

1.1.1.2.9.1.1.1.2 Information Schema


INNODB_BUFFER_PAGE_LRU Table
The Information Schema INNODB_BUFFER_PAGE_LRU table contains information about pages in the buffer pool and how
they are ordered for eviction purposes.
The PROCESS privilege is required to view the table.
280/3812
It has the following columns:

Column Description
Buffer Pool identifier. From MariaDB 10.5.1 returns a value of 0, since multiple InnoDB buffer
POOL_ID
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 table.
PAGE_NUMBER Buffer pool page number.
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),
PAGE_TYPE
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.


Count of the threads using this block in the buffer pool. When it is zero, the block can be
FIX_COUNT
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; one of FILE_PAGE (page from a file) or MEMORY (page from an in-memory object)
PAGE_STATE
for valid data, or one of NULL , READY_FOR_USE , NOT_USED , REMOVE_HASH .
Whether there is I/O pending for the page; one of IO_NONE (no pending I/O), IO_READ (read
IO_FIX
pending), IO_WRITE (write pending).
IS_OLD Whether the page is old or not.
Freed_page_clock counter, which tracks the number of blocks removed from the end of the
FREE_PAGE_CLOCK
LRU list, at the time the block was last placed at the head of the list.

The related INFORMATION_SCHEMA.INNODB_BUFFER_PAGE table contains the same information, but with a block
id rather than LRU position.

Example

281/3812
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
...

1.1.1.2.9.1.1.1.3 Information Schema


INNODB_BUFFER_POOL_PAGES Table
The Information Schema INNODB_BUFFER_POOL_PAGES table is a Percona enhancement, and is only available for
XtraDB, not InnoDB (see XtraDB and InnoDB). It contains a record for each page in the buffer pool.
It has the following columns:

Column Description
Type of page; one of index , undo_log , inode , ibuf_free_list , allocated, bitmap , sys ,
PAGE_TYPE
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.
Page reference count, incremented each time the page is accessed. 0 if the page is not currently
FIX_COUNT
being accessed.
FLUSH_TYPE Flush type of the most recent flush. 0 (LRU), 2 (flush_list)

282/3812
1.1.1.2.9.1.1.1.4 Information Schema
INNODB_BUFFER_POOL_PAGES_BLOB
Table
The Information Schema INNODB_BUFFER_POOL_PAGES_BLOB table is a Percona enchancement, and is only available for
XtraDB, not InnoDB (see XtraDB and InnoDB). It contains information about buffer pool 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.
Page reference count, incremented each time the page is accessed. 0 if the page is not currently
FIX_COUNT
being accessed.
FLUSH_TYPE Flush type of the most recent flush. 0 (LRU), 2 (flush_list)

1.1.1.2.9.1.1.1.5 Information Schema


INNODB_BUFFER_POOL_PAGES_INDEX
Table
The Information Schema INNODB_BUFFER_POOL_PAGES table is a Percona enhancement, and is only available for
XtraDB, not InnoDB (see XtraDB and InnoDB). It contains information about buffer pool 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.


Page reference count, incremented each time the page is accessed. 0 if the page is not currently
FIX_COUNT
being accessed.
FLUSH_TYPE Flush type of the most recent flush. 0 (LRU), 2 (flush_list)

1.1.1.2.9.1.1.1.6 Information Schema


INNODB_BUFFER_POOL_STATS Table
The Information Schema INNODB_BUFFER_POOL_STATS table contains information about pages in the buffer pool, similar
to what is returned with the SHOW ENGINE INNODB STATUS statement.
The PROCESS privilege is required to view the table.

283/3812
It has the following columns:

Column Description
Buffer Pool identifier. From MariaDB 10.5.1 returns a value of 0, since multiple
POOL_ID
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.
Hits that do not cause blocks to move to the top of the new sublist due to the
PAGES_MADE_NOT_YOUNG_RATE
innodb_old_blocks 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.
Number of pages read since the last printout divided by the time elapsed,
PAGES_READ_RATE
giving pages read per second.
Number of pages created since the last printout divided by the time elapsed,
PAGES_CREATE_RATE
giving pages created per second.
Number of pages written since the last printout divided by the time elapsed,
PAGES_WRITTEN_RATE
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 of pages read ahead by the read-ahead thread that were later evicted
NUMBER_READ_AHEAD_EVICTED
without being accessed by any queries.
Pages read ahead since the last printout divided by the time elapsed, giving
READ_AHEAD_RATE
read-ahead rate per second.
Read-ahead pages not accessed since the last printout divided by time
READ_AHEAD_EVICTED_RATE 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

284/3812
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 | |
+----------------------------------+---------------------+------+-----+---------+-------+

1.1.1.2.9.1.1.1.7 Information Schema


INNODB_CHANGED_PAGES Table
The Information Schema 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 system variable.
The PROCESS privilege 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)

1.1.1.2.9.1.1.1.8 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.
The PROCESS privilege is required to query this table.
These tables contain the following columns:

Column Name Description

285/3812
Compressed page size, in bytes. This value is unique in the table; other values are totals which
PAGE_SIZE
refer to pages of this size.

How many times a page of the size PAGE_SIZE has been compressed. This happens when a new
COMPRESS_OPS page is created because the compression log runs out of space. This value includes both
successful operations and compression failures.
How many times a page of the size PAGE_SIZE has been successfully compressed. This value
COMPRESS_OPS_OK 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.
Time (in seconds) spent to compress pages of the size PAGE_SIZE . This value includes time
COMPRESS_TIME
spent in compression failures.
How many times a page of the size PAGE_SIZE has been uncompressed. This happens when an
UNCOMPRESS_OPS 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
INNODB_CMPMEM and INNODB_CMPMEM_RESET

1.1.1.2.9.1.1.1.9 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 (see InnoDB COMPRESSED format).
The PROCESS privilege is required to query this table.
These tables contain the following columns:

Column Name Description


Compressed page size, in bytes. This value is unique in the table; other values are totals
PAGE_SIZE
which refer to pages of this size.
Buffer Pool identifier. From MariaDB 10.5.1 returns a value of 0, since multiple InnoDB
BUFFER_POOL_INSTANCE
buffer pool instances has been removed.
PAGES_USED Number of pages of the size PAGE_SIZE which are currently in the buffer pool.

286/3812
Number of pages of the size PAGE_SIZE which are currently free, and thus are available for
PAGES_FREE allocation. This value represents the buffer pool's fragmentation. A totally unfragmented
buffer pool has at most 1 free page.
How many times a page of the size PAGE_SIZE has been relocated. This happens when
RELOCATION_OPS 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).
Time (in seconds) spent in relocation operations for pages of the size PAGE_SIZE . This
RELOCATION_TIME
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
INNODB_CMP_PER_INDEX and INNODB_CMP_PER_INDEX_RESET

1.1.1.2.9.1.1.1.10 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, grouped by individual indexes. These tables are only
populated if the innodb_cmp_per_index_enabled system variable is set to ON .
The PROCESS 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.
How many times a page of INDEX_NAME has been compressed. This happens when a new page
COMPRESS_OPS is created because the compression log runs out of space. This value includes both successful
operations and compression failures.
How many times a page of INDEX_NAME has been successfully compressed. This value should be
COMPRESS_OPS_OK 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.
Time (in seconds) spent to compress pages of the size PAGE_SIZE . This value includes time
COMPRESS_TIME
spent in compression failures.

287/3812
How many times a page of INDEX_NAME has been uncompressed. This happens when an
UNCOMPRESS_OPS 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
INNODB_CMPMEM and INNODB_CMPMEM_RESET

1.1.1.2.9.1.1.1.11 Information Schema


INNODB_FT_BEING_DELETED Table
The Information Schema INNODB_FT_BEING_DELETED table is only used while document ID's in the related
INNODB_FT_DELETED are being removed from an InnoDB fulltext index while an OPTIMIZE TABLE is underway. At
all other times the table will be empty.
The SUPER privilege is required to view the table, and it also requires the innodb_ft_aux_table system variable to be
set.
It has the following column:

Column Description
Document ID of the row being deleted. Either an underlying ID value, or a sequence value generated by
DOC_ID
InnoDB if no usable option exists.

1.1.1.2.9.1.1.1.12 Information Schema


INNODB_FT_CONFIG Table
The Information Schema INNODB_FT_CONFIG table contains InnoDB fulltext index metadata.
The SUPER privilege is required to view the table, and it also requires the innodb_ft_aux_table system variable to be
set.
It has the following columns:

Column Description

KEY Metadata item name.

VALUE Associated value.

Example

288/3812
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 |
+---------------------------+-------+

1.1.1.2.9.1.1.1.13 Information Schema


INNODB_FT_DEFAULT_STOPWORD Table
The Information Schema INNODB_FT_DEFAULT_STOPWORD table contains a list of default stopwords used when creating
an InnoDB fulltext index.
The PROCESS privilege is required to view the table.
It has the following column:

Column Description
Default stopword for an InnoDB fulltext index. Setting either the innodb_ft_server_stopword_table or the
VALUE
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

1.1.1.2.9.1.1.1.14 Information Schema


INNODB_FT_DELETED Table
The Information Schema INNODB_FT_DELETED table contains rows that have been deleted from an InnoDB fulltext 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 statement is underway. The related
INNODB_FT_BEING_DELETED table contains rows being deleted while an OPTIMIZE TABLE is in the process of
running.
The SUPER privilege is required to view the table, and it also requires the innodb_ft_aux_table system variable to be
set.
It has the following column:

Column Description
Document ID of the deleted row deleted. Either an underlying ID value, or a sequence value generated by
DOC_ID
InnoDB if no usable option exists.

Example
289/3812
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 |
+--------+

1.1.1.2.9.1.1.1.15 Information Schema


INNODB_FT_INDEX_CACHE Table
The Information Schema INNODB_FT_INDEX_CACHE table contains information about rows that have recently been
inserted into an InnoDB fulltext 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 is run.
The SUPER privilege is required to view the table, and it also requires the innodb_ft_aux_table system variable to be
set.
It has the following columns:

Column Description
Word from the text of a newly added row. Words can appear multiple times in the table, once per
WORD
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 of this word instance within the DOC_ID , as an offset added to the previous POSITION
POSITION
instance.

Note that for OPTIMIZE TABLE to process InnoDB fulltext index data, the 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 table will be updated.

Examples

290/3812
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 variable wasn't set:

291/3812
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)

1.1.1.2.9.1.1.1.16 Information Schema


INNODB_FT_INDEX_TABLE Table
The Information Schema INNODB_FT_INDEX_TABLE table contains information about InnoDB fulltext indexes. 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 is run. See the INNODB_FT_INDEX_CACHE table.
The SUPER privilege is required to view the table, and it also requires the innodb_ft_aux_table system variable to be
set.
It has the following columns:

Column Description
Word from the text of a column with a fulltext index. Words can appear multiple times in the table,
WORD
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 of this word instance within the DOC_ID , as an offset added to the previous POSITION
POSITION
instance.

Note that for OPTIMIZE TABLE to process InnoDB fulltext index data, the 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 table will be updated.

Examples

292/3812
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 |
+------------+--------------+-------------+-----------+--------+----------+

1.1.1.2.9.1.1.1.17 Information Schema


INNODB_LOCK_WAITS Table
The Information Schema INNODB_LOCK_WAITS table contains information about blocked InnoDB transactions. The
PROCESS privilege is required to view the table.

It contains the following columns:

Column Description
REQUESTING_TRX_ID Requesting transaction ID from the INNODB_TRX table.
REQUESTED_LOCK_ID Lock ID from the INNODB.LOCKS table for the waiting transaction.
BLOCKING_TRX_ID Blocking transaction ID from the INNODB_TRX table.
Lock ID from the INNODB.LOCKS table of a lock held by a transaction that is blocking another
BLOCKING_LOCK_ID
transaction.

The table is often used in conjunction with the INNODB_LOCKS and INNODB_TRX tables to diagnose problematic
locks and transactions.

1.1.1.2.9.1.1.1.18 Information Schema


INNODB_LOCKS Table
The Information Schema 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 column.
Lock mode. One of S (shared), X (exclusive), IS (intention shared), IX (intention exclusive row
LOCK_MODE 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).

LOCK_TYPE Whether the lock is RECORD (row level) or TABLE level.


LOCK_TABLE Name of the locked table,or table containing locked rows.

293/3812
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.
Locked record primary key as an SQL string if a RECORD LOCK_TYPE , or NULL if not. If no primary key
LOCK_DATA 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

The table is often used in conjunction with the INNODB_LOCK_WAITS and INNODB_TRX 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

1.1.1.2.9.1.1.1.19 Information Schema


INNODB_METRICS Table

294/3812
Contents
1. Enabling and Disabling Counters
2. Resetting Counters
3. Simplifying from MariaDB 10.6
4. Examples

The Information Schema 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 is required to view the table.
It has the following columns:

Column Description
NAME Unique counter name.
InnoDB subsystem. See below for the matching module to use to enable/disable monitoring this
SUBSYSTEM
subsytem with the innodb_monitor_enable and 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 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

295/3812
module_index index

adaptive_hash_index From MariaDB 10.6.2, if innodb_adaptive_hash_index is disabled


module_adaptive_hash
(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 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
(for individual counters) and innodb_monitor_reset_all (for all counters) system variables.

Simplifying from MariaDB 10.6


MariaDB starting with 10.6
From MariaDB 10.6, 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
buffer_LRU_batch_evict_total_pages: innodb_buffer_pool_pages_LRU_freed
The intention is to eventually remove the interface entirely (see MDEV-15706 ).

Examples
MariaDB 10.8:

296/3812
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

1.1.1.2.9.1.1.1.20 Information Schema


297/3812
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 , the table has only been providing information about rw_lock_t, not any mutexes.
From MariaDB 10.2.2 until MariaDB 10.2.32 , MariaDB 10.3.23, MariaDB 10.4.13 and MariaDB 10.5.1, the NAME
column was not populated (MDEV-21636 ).
The SHOW ENGINE INNODB STATUS 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 |
+------------------------------+---------------------+-------------+----------+

1.1.1.2.9.1.1.1.21 Information Schema


INNODB_SYS_COLUMNS Table
The Information Schema INNODB_SYS_COLUMNS table contains information about InnoDB fields.
The PROCESS privilege 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.
NAME Column name.
Ordinal position of the column in the table, starting from 0 . This value is adjusted when columns are
POS
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

2 CHAR

3 FIXBINARY

4 BINARY

5 BLOB

6 INT

7 SYS_CHILD

8 SYS

298/3812
9 FLOAT

10 DOUBLE

11 DECIMAL

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)

1.1.1.2.9.1.1.1.22 Information Schema


INNODB_SYS_DATAFILES Table
MariaDB until 10.5
The INNODB_SYS_DATAFILES table was added in MariaDB 10.0.4 , and removed in MariaDB 10.6.0.

The Information Schema 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. The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description
SPACE Numeric tablespace. Matches the INNODB_SYS_TABLES.SPACE 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 |
+-------+--------------------------------+

299/3812
1.1.1.2.9.1.1.1.23 Information Schema
INNODB_SYS_FIELDS Table
The Information Schema INNODB_SYS_FIELDS table contains information about fields that are part of an InnoDB index.
The PROCESS privilege 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.
NAME Field name, matching the value from INNODB_SYS_COLUMNS.NAME.
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)

1.1.1.2.9.1.1.1.24 Information Schema


INNODB_SYS_FOREIGN Table
The Information Schema INNODB_SYS_FOREIGN table contains information about InnoDB foreign keys.
The PROCESS privilege 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

300/3812
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
...

1.1.1.2.9.1.1.1.25 Information Schema


INNODB_SYS_FOREIGN_COLS Table
The Information Schema INNODB_SYS_FOREIGN_COLS table contains information about InnoDB foreign key columns.
The PROCESS privilege 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 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.

1.1.1.2.9.1.1.1.26 Information Schema


INNODB_SYS_INDEXES Table
The Information Schema INNODB_SYS_INDEXES table contains information about InnoDB indexes.
The PROCESS privilege is required to view the table.
It has the following columns:

Field Type Null Key Default Description


bigint(21)
INDEX_ID NO 0 A unique index identifier.
unsigned
Index name, lowercase for all user-created indexes, or
uppercase for implicitly-created indexes; PRIMARY
NAME varchar(64) NO (primary key), GEN_CLUST_INDEX (index representing
primary key where there isn't one), ID_IND , FOR_IND
(validating foreign key constraint) , REF_IND .
bigint(21) Table identifier, matching the value from
TABLE_ID NO 0
unsigned INNODB_SYS_TABLES.TABLE_ID.
Numeric type identifier; one of 0 (secondary index), 1
TYPE int(11) NO 0 (clustered index), 2 (unique index), 3 (primary index),
32 (full-text index).

Number of columns in the index. GEN_CLUST_INDEX's


N_FIELDS int(11) NO 0 have a value of 0 as the index is not based on an actual
column in the table.
Index B-tree's root page number. -1 (unused) for full-
PAGE_NO int(11) NO 0 text indexes, as they are laid out over several auxiliary
tables.
Tablespace identifier where the index resides. 0
represents the InnoDB system tablespace, while any
other value represents a table created in file-per-table
SPACE int(11) NO 0
mode (see the innodb_file_per_table system variable).
Remains unchanged after a TRUNCATE TABLE
statement, and not necessarily unique.
MERGE_THRESHOLD int(11) NO 0

Example
301/3812
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)

1.1.1.2.9.1.1.1.27 Information Schema


INNODB_SYS_SEMAPHORE_WAITS Table
The Information Schema INNODB_SYS_SEMAPHORE_WAITS table is meant to contain information about current
semaphore waits. At present it is not correctly populated. See MDEV-21330 .
The PROCESS privilege 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

302/3812
LAST_WRITER_FILE Last writer file name
LAST_WRITER_LINE Above line number
OS_WAIT_COUNT Wait count

1.1.1.2.9.1.1.1.28 Information Schema


INNODB_SYS_TABLES Table
The Information Schema INNODB_SYS_TABLES table contains information about InnoDB tables.
The PROCESS privilege 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.
Database and table name, or the uppercase
NAME varchar(655) NO
InnoDB system table name.
FLAG int(11) NO 0 See Flag below
int(11) unsigned (>=
MariaDB 10.5)
N_COLS NO 0 Number of columns in the table.
int(11) (<= MariaDB
10.4)
Tablespace identifier where the index resides. 0
int(11) unsigned (>= represents the InnoDB system tablespace, while
MariaDB 10.5) any other value represents a table created in file-
SPACE NO 0
int(11) (<= MariaDB per-table mode (see the innodb_file_per_table
10.4) system variable). Remains unchanged after a
TRUNCATE TABLE statement.

InnoDB file format (Antelope or Barracuda).


FILE_FORMAT varchar(10) YES NULL
Removed in MariaDB 10.3.
enum('Redundant',
'Compact',
'Compressed',
InnoDB storage format (Compact, Redundant,
ROW_FORMAT 'Dynamic') (>= YES NULL
Dynamic, or Compressed).
MariaDB 10.5)
varchar(12) (<=
MariaDB 10.4)
ZIP_PAGE_SIZE int(11) unsigned NO 0 For Compressed tables, the zipped page size.
enum('Single','System')
(>= MariaDB 10.5)
SPACE_TYPE YES NULL
varchar(10) (<=
MariaDB 10.4)

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
0 , except for ROW_FORMAT=COMPRESSED, where they will determine the KEY_BLOCK_SIZE (the
to
compressed page size).
4

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 Determine the page_compression_level.
11

303/3812
12 Normally 00 , but 11 for "no-rollback tables" (MariaDB 10.3 CREATE SEQUENCE). In MariaDB 10.1, these
13 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

1.1.1.2.9.1.1.1.29 Information Schema


INNODB_SYS_TABLESPACES Table
The Information Schema INNODB_SYS_TABLESPACES table contains information about InnoDB tablespaces. Until
MariaDB 10.5 it was based on the internal SYS_TABLESPACES table. This internal table was removed in MariaDB 10.6.0,
so this Information Schema table has been repurposed to directly reflect the filesystem (fil_system.space_list).
The PROCESS privilege 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 , otherwise 0 .

FILE_FORMAT InnoDB file format. Removed in MariaDB 10.3.1


InnoDB storage format used for this tablespace. If the Antelope file format is used, this value is
ROW_FORMAT
always Compact or Redundant .
Page size in bytes for this tablespace. Until MariaDB 10.5.0, this was the value of the
PAGE_SIZE innodb_page_size variable. From MariaDB 10.6.0, 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.
Tablespace type. Can be General for general tablespaces or Single for file-per-table
SPACE_TYPE
tablespaces. Introduced MariaDB 10.2.1 . Removed MariaDB 10.5.0.

FS_BLOCK_SIZE File system block size. Introduced MariaDB 10.2.1 .

FILE_SIZE Maximum size of the file, uncompressed. Introduced MariaDB 10.2.1 .


ALLOCATED_SIZE Actual size of the file as per space allocated on disk. Introduced MariaDB 10.2.1 .
Tablespace datafile path, previously part of the INNODB_SYS_DATAFILES table. Added in
FILENAME
MariaDB 10.6.0.

304/3812
Examples
MariaDB 10.4:

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:

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

1.1.1.2.9.1.1.1.30 Information Schema


INNODB_SYS_TABLESTATS Table
The Information Schema 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 is required to view the table.
Note that the MySQL InnoDB and Percona XtraDB versions of the tables differ (see XtraDB and InnoDB).
It contains the following columns:

Column Description
TABLE_ID Table ID, matching the INNODB_SYS_TABLES.TABLE_ID value.
SCHEMA Database name (XtraDB only).
NAME Table name, matching the INNODB_SYS_TABLES.NAME value.
STATS_INITIALIZED Initialized if statistics have already been collected, otherwise Uninitialized .

Estimated number of rows currently in the table. Updated after each statement modifying the
NUM_ROWS
data, but uncommited transactions mean it may not be accurate.
Number of pages on disk storing the clustered index, holding InnoDB table data in primary
CLUST_INDEX_SIZE key order, or NULL if not statistics yet collected.

Number of pages on disk storing secondary indexes for the table, or NULL if not statistics
OTHER_INDEX_SIZE
yet collected.
305/3812
MODIFIED_COUNTER Number of rows modified by statements modifying data.
AUTOINC Auto_increment value.
Countdown to zero, when table metadata can be removed from the table cache. (InnoDB
REF_COUNT
only)
MYSQL_HANDLES_OPENED (XtraDB only).

1.1.1.2.9.1.1.1.31 Information Schema


INNODB_SYS_VIRTUAL Table
MariaDB starting with 10.2
The INNODB_SYS_VIRTUAL table was added in MariaDB 10.2.

The Information Schema INNODB_SYS_VIRTUAL table contains information about base columns of virtual columns. The
PROCESS privilege 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

1.1.1.2.9.1.1.1.32 Information Schema


INNODB_TABLESPACES_ENCRYPTION
Table
The Information Schema INNODB_TABLESPACES_ENCRYPTION table contains metadata about encrypted InnoDB
tablespaces. When you enable encryption for an InnoDB tablespace, an entry for the tablespace is added to this table.
If you later disable encryption for the InnoDB tablespace, 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 privilege, although a bug in versions before MariaDB 10.1.46 , 10.2.33 ,
10.3.24, 10.4.14 and 10.5.5 mean the SUPER privilege was required (MDEV-23003 ).
It has the following columns:

Column Description Added


SPACE InnoDB tablespace ID.
NAME Path to the InnoDB tablespace file, without the extension.
Key derivation algorithm. Only 1 is currently used to represent
ENCRYPTION_SCHEME an algorithm. If this value is 0 , then the tablespace is
unencrypted.
Number of times InnoDB has had to request a key from the
KEYSERVER_REQUESTS encryption key management plugin. The three most recent keys
are cached internally.
Minimum key version used to encrypt a page in the tablespace.
MIN_KEY_VERSION
Different pages may be encrypted with different key versions.
Key version that will be used to encrypt pages. If this value is 0 ,
CURRENT_KEY_VERSION
then the tablespace is unencrypted.

Page that a background encryption thread is currently rotating. If


KEY_ROTATION_PAGE_NUMBER
key rotation is not enabled, then the value will be NULL .
When a background encryption thread starts rotating a
KEY_ROTATION_MAX_PAGE_NUMBER tablespace, the field contains its current size. If key rotation is not
enabled, then the value will be NULL .
MariaDB
CURRENT_KEY_ID Key ID for the encryption key currently in use.
10.1.13

306/3812
MariaDB
Current key rotation status. If this value is 1 , then the
10.2.5 ,
ROTATING_OR_FLUSHING background encryption threads are working on the tablespace.
MariaDB
See MDEV-11738 .
10.1.23

When the InnoDB system tablespace 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
Data at Rest Encryption
Why Encrypt MariaDB Data?
Encryption Key Management

1.1.1.2.9.1.1.1.33 Information Schema


INNODB_TABLESPACES_SCRUBBING Table
MariaDB 10.1.3 - 10.5.1
InnoDB and XtraDB data scrubbing was introduced in MariaDB 10.1.3 . The table was removed in MariaDB 10.5.2 -
see MDEV-15528 .

The Information Schema INNODB_TABLESPACES_SCRUBBING table contains data scrubbing information.


The PROCESS privilege 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.
Date and time when the last scrub was completed, or NULL if never been
LAST_SCRUB_COMPLETED
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.

307/3812
When a scrubbing starts rotating a table space, the field contains its current size.
CURRENT_SCRUB_MAX_PAGE_NUMBER
NULL if not enabled.

The field contains 1 when MariaDB detects that the table space is on a SSD
ON_SSD
based storage. 0 if not SSD or it could not be determined (since MariaDB 10.4.4)

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)

1.1.1.2.9.1.1.1.34 Information Schema


INNODB_TRX Table
The Information Schema INNODB_TRX table stores information about all currently executing InnoDB transactions.
It has the following columns:

Column Description
TRX_ID Unique transaction ID number.
Transaction execution state; one of RUNNING , LOCK WAIT , ROLLING BACK or
TRX_STATE
COMMITTING .

TRX_STARTED Time that the transaction started.


If TRX_STATE is LOCK_WAIT , the INNODB_LOCKS.LOCK_ID value of the lock being
TRX_REQUESTED_LOCK_ID
waited on. NULL if any other state.
If TRX_STATE is LOCK_WAIT , the time the transaction started waiting for the lock,
TRX_WAIT_STARTED
otherwise NULL .
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.
TRX_WEIGHT
Transactions that have affected non-transactional tables are always treated as
having a heavier weight.
Thread ID from the PROCESSLIST table (note that the locking and transaction
TRX_MYSQL_THREAD_ID 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 .
Number of InnoDB tables currently being used for processing the current SQL
TRX_TABLES_IN_USE
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.
Total size in bytes of the memory used to hold the lock structures for the current
TRX_LOCK_MEMORY_BYTES
transaction in memory.
Number of rows the current transaction has locked. locked by this transaction. An
TRX_ROWS_LOCKED 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.
Indicates how much work the current transaction can do before being swapped out,
TRX_CONCURRENCY_TICKETS
see the innodb_concurrency_tickets system variable.
TRX_ISOLATION_LEVEL Isolation level of the current transaction.

308/3812
Whether unique checks are on or off for the current transaction. Bulk data are a
TRX_UNIQUE_CHECKS
case where unique checks would be off.
Whether foreign key checks are on or off for the current transaction. Bulk data are
TRX_FOREIGN_KEY_CHECKS
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.
Whether the adaptive hash index is locked by the current transaction or not. One
TRX_ADAPTIVE_HASH_LATCHED
transaction at a time can change the adaptive hash index.
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
TRX_ADAPTIVE_HASH_TIMEOUT
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 .

1 if the transaction only contains this one statement, that is, a SELECT statement not
using FOR UPDATE or LOCK IN SHARED MODE , and with autocommit on. If this and
TRX_AUTOCOMMIT_NON_LOCKING
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 and INNODB_LOCK_WAITS tables to diagnose
problematic locks and transactions.
XA transactions 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

309/3812
1.1.1.2.9.1.1.1.35 Information Schema
TEMP_TABLES_INFO Table
MariaDB 10.2.2 - 10.2.3
The TEMP_TABLES_INFO table was introduced in MariaDB 10.2.2 and was removed in MariaDB 10.2.4 . See
MDEV-12459 progress on an alternative.

The Information Schema 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.
Number of columns in the temporary table, including three hidden columns that InnoDB
N_COLS
creates ( DB_ROW_ID , DB_TRX_ID , and DB_ROLL_PTR ).
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
SPACE
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.
If TRUE , the temporary table resides in a separate per-table tablespace. If FALSE , it resides
PER_TABLE_TABLESPACE
in the shared temporary tablespace.
IS_COMPRESSED TRUE if the table is compressed.

The PROCESS privilege 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 |
+----------+--------------+--------+-------+----------------------+---------------+

1.1.1.2.9.1.1.2 Information Schema MyRocks


Tables
List of Information Schema tables specifically related to MyRocks.
Information Schema ROCKSDB_CFSTATS Table
The Information Schema ROCKSDB_CFSTATS table is included as part of the MyR...

310/3812
Information Schema ROCKSDB_CF_OPTIONS Table
Information about MyRocks Column Families.

Information Schema ROCKSDB_COMPACTION_STATS Table


The Information Schema ROCKSDB_COMPACTION_STATS table is included as part o...

Information Schema ROCKSDB_DBSTATS Table


The Information Schema ROCKSDB_DBSTATS table is included as part of the MyR...

Information Schema ROCKSDB_DDL Table


The Information Schema ROCKSDB_DDL table is included as part of the MyRocks...

Information Schema ROCKSDB_DEADLOCK Table


The Information Schema ROCKSDB_DEADLOCK table is included as part of the My...

Information Schema ROCKSDB_GLOBAL_INFO Table


The Information Schema ROCKSDB_GLOBAL_INFO table is included as part of the...

Information Schema ROCKSDB_INDEX_FILE_MAP Table


The Information Schema ROCKSDB_INDEX_FILE_MAP table is included as part of ...

Information Schema ROCKSDB_LOCKS Table


The Information Schema ROCKSDB_LOCKS table is included as part of the MyRoc...

Information Schema ROCKSDB_PERF_CONTEXT Table


Per-table/partition counters.

Information Schema ROCKSDB_PERF_CONTEXT_GLOBAL Table


Global counters.

Information Schema ROCKSDB_SST_PROPS Table


The Information Schema ROCKSDB_SST_PROPS table is included as part of the M...

Information Schema ROCKSDB_TRX Table


The Information Schema ROCKSDB_TRX table is included as part of the MyRocks...

1.1.1.2.9.1.1.2.1 Information Schema


ROCKSDB_CFSTATS Table
The Information Schema ROCKSDB_CFSTATS table is included as part of the MyRocks storage engine.
The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description
CF_NAME

STAT_TYPE

VALUE

1.1.1.2.9.1.1.2.2 Information Schema


ROCKSDB_CF_OPTIONS Table
The Information Schema ROCKSDB_CF_OPTIONS table is included as part of the MyRocks storage engine, and contains
infomation about MyRocks column families.
The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description
CF_NAME Column family name.
OPTION_TYPE

VALUE
311/3812
1.1.1.2.9.1.1.2.3 Information Schema
ROCKSDB_COMPACTION_STATS Table
The Information Schema ROCKSDB_COMPACTION_STATS table is included as part of the MyRocks storage engine.
The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description
CF_NAME

LEVEL

TYPE

VALUE

1.1.1.2.9.1.1.2.4 Information Schema


ROCKSDB_DBSTATS Table
The Information Schema ROCKSDB_DBSTATS table is included as part of the MyRocks storage engine.
The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description
STAT_TYPE

VALUE

1.1.1.2.9.1.1.2.5 Information Schema


ROCKSDB_DDL Table
The Information Schema ROCKSDB_DDL table is included as part of the MyRocks storage engine.
The PROCESS privilege 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

1.1.1.2.9.1.1.2.6 Information Schema


ROCKSDB_DEADLOCK Table
The Information Schema ROCKSDB_DEADLOCK table is included as part of the MyRocks storage engine.
312/3812
The PROCESS privilege 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

1.1.1.2.9.1.1.2.7 Information Schema


ROCKSDB_GLOBAL_INFO Table
The Information Schema ROCKSDB_GLOBAL_INFO table is included as part of the MyRocks storage engine.
The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description
TYPE

NAME

VALUE

1.1.1.2.9.1.1.2.8 Information Schema


ROCKSDB_INDEX_FILE_MAP Table
The Information Schema ROCKSDB_INDEX_FILE_MAP table is included as part of the MyRocks storage engine.
The PROCESS privilege 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

1.1.1.2.9.1.1.2.9 Information Schema


ROCKSDB_LOCKS Table
The Information Schema ROCKSDB_LOCKS table is included as part of the MyRocks storage engine.

313/3812
The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description
COLUMN_FAMILY_ID

TRANSACTION_ID

KEY

MODE

1.1.1.2.9.1.1.2.10 Information Schema


ROCKSDB_PERF_CONTEXT Table
The Information Schema ROCKSDB_PERF_CONTEXT table is included as part of the MyRocks storage engine and includes
per-table/partition counters .
The PROCESS privilege 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

1.1.1.2.9.1.1.2.11 Information Schema


ROCKSDB_PERF_CONTEXT_GLOBAL Table
The Information Schema ROCKSDB_PERF_CONTEXT_GLOBAL table is included as part of the MyRocks storage engine and
includes global counter information.
The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description
STAT_TYPE

VALUE

1.1.1.2.9.1.1.2.12 Information Schema


ROCKSDB_SST_PROPS Table
The Information Schema ROCKSDB_SST_PROPS table is included as part of the MyRocks storage engine.
The PROCESS privilege is required to view the table.
It contains the following columns:

Column Description

SST_NAME

COLUMN_FAMILY

DATA_BLOCKS

ENTRIES

RAW_KEY_SIZE
314/3812
RAW_VALUE_SIZE

DATA_BLOCK_SIZE

INDEX_BLOCK_SIZE

INDEX_PARTITIONS

TOP_LEVEL_INDEX_SIZE

FILTER_BLOCK_SIZE

COMPRESSION_ALGO

CREATION_TIME

1.1.1.2.9.1.1.2.13 Information Schema


ROCKSDB_TRX Table
The Information Schema ROCKSDB_TRX table is included as part of the MyRocks storage engine.
The PROCESS privilege 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

1.1.1.2.9.1.1.3 ColumnStore Information


Schema Tables
1. COLUMNSTORE_TABLES
2. COLUMNSTORE_COLUMNS
3. COLUMNSTORE_EXTENTS
4. COLUMNSTORE_FILES
5. Stored Procedures
1. total_usage()
2. table_usage()
3. compression_ratio()

MariaDB ColumnStore has four Information Schema tables that expose information about the table and column storage.
These tables were added in version 1.0.5 of ColumnStore and were heavily modified for 1.0.6.

COLUMNSTORE_TABLES
The first table is the INFORMATION_SCHEMA.COLUMNSTORE_TABLES. This contains information about the tables
inside ColumnStore. The table layout is as follows:
315/3812
Column Description
TABLE_SCHEMA The database schema for the table
TABLE_NAME The table name
OBJECT_ID The ColumnStore object ID for the table
CREATION_DATE The date the table was created
COLUMN_COUNT The number of columns in the table
AUTOINCREMENT The start autoincrement value for the table set during CREATE TABLE

Note: Tables created with ColumnStore 1.0.4 or lower will have the year field of the creation data set incorrectly by
1900 years.

COLUMNSTORE_COLUMNS
The INFORMATION_SCHEMA.COLUMNSTORE_COLUMNS table contains information about every single column
inside ColumnStore. The table layout is as follows:

Column Description
TABLE_SCHEMA The database schema for the table
TABLE_NAME The table name for the column
COLUMN_NAME The column name
OBJECT_ID The object ID for the column
DICTIONARY_OBJECT_ID The dictionary object ID for the column (NULL if there is no dictionary object
LIST_OBJECT_ID Placeholder for future information
TREE_OBJECT_ID Placeholder for future information
DATA_TYPE The data type for the column
COLUMN_LENGTH The data length for the column
COLUMN_POSITION The position of the column in the table, starting at 0
COLUMN_DEFAULT The default value for the column
IS_NULLABLE Whether or not the column can be set to NULL
NUMERIC_PRECISION The numeric precision for the column
NUMERIC_SCALE The numeric scale for the column
IS_AUTOINCREMENT Set to 1 if the column is an autoincrement column
COMPRESSION_TYPE The type of compression (either "None" or "Snappy")

COLUMNSTORE_EXTENTS
This table displays the extent map in a user consumable form. An extent is a collection of details about a section of data
related to a columnstore column. A majority of columns in ColumnStore will have multiple extents and the columns table
above can be joined to this one to filter results by table or column. The table layout is as follows:

Column Description
OBJECT_ID The object ID for the extent
OBJECT_TYPE Whether this is a "Column" or "Dictionary" extent
LOGICAL_BLOCK_START ColumnStore's internal start LBID for this extent
LOGICAL_BLOCK_END ColumnStore's internal end LBID for this extent
MIN_VALUE This minimum value stored in this extent
MAX_VALUE The maximum value stored in this extent
WIDTH The data width for the extent
DBROOT The DBRoot number for the extent

316/3812
PARTITION_ID The parition ID for the extent
SEGMENT_ID The segment ID for the extent
BLOCK_OFFSET The block offset for the data file, each data file can contain multiple extents for a column
MAX_BLOCKS The maximum number of blocks for the extent
HIGH_WATER_MARK The last block committed to the extent (starting at 0)
STATE The state of the extent (see below)
The availability status for the column which is either "Available", "Unavailable" or "Out of
STATUS
service"
DATA_SIZE The uncompressed data size for the extent calculated as (HWM + 1) * BLOCK_SIZE

Notes:
1. The state is "Valid" for a normal state, "Invalid" if a cpimport has completed but the table has not yet been
accessed (min/max values will be invalid) or "Updating" if there is a DML statement writing to the column
2. In ColumnStore the block size is 8192 bytes
3. By default ColumnStore will write create an extent file of 256*1024*WIDTH bytes for the first partition, if this
is too small then for uncompressed data it will create a file of the maximum size for the extent (MAX_BLOCKS
* BLOCK_SIZE). Snappy always compression adds a header block.
4. Object IDs of less than 3000 are for internal tables and will not appear in any of the information schema
tables
5. Prior to 1.0.12 / 1.1.2 DATA_SIZE was incorrectly calculated
6. HWM is set to zero for the lower segments when there are multiple segments in an extent file, these can be
observed when BLOCK_OFFSET > 0
7. When HWM is 0 the DATA_SIZE will show 0 instead of 8192 to avoid confusion when there is multiple
segments in an extent file

COLUMNSTORE_FILES
The columnstore_files table provides information about each file associated with extensions. Each extension can reuse
a file at different block offsets so this is not a 1:1 relationship to the columnstore_extents table.

Column Description
OBJECT_ID The object ID for the extent
SEGMENT_ID The segment ID for the extent
PARTITION_ID The partition ID for the extent
The full path and filename for the extent file, multiple extents for the same column can
FILENAME
point to this file with different BLOCK_OFFSETs
FILE_SIZE The disk file size for the extent
COMPRESSED_DATA_SIZE The amount of the compressed file used, NULL if this is an uncompressed file

Stored Procedures
A few stored procedures were added in 1.0.6 to provide summaries based on the information schema tables. These can
be accessed from the COLUMNSTORE_INFO schema.

total_usage()
The total_usage() procedure gives a total disk usage summary for all the columns in ColumnStore with the exception of
the columns used for internal maintenance. It is executed using the following query:

> call columnstore_info.total_usage();

table_usage()
The table_usage() procedure gives a the total data disk usage, dictionary disk usage and grand total disk usage per-
table. It can be called in several ways, the first gives a total for each table:

> call columnstore_info.table_usage(NULL, NULL);

Or for a specific table, my_table in my_schema in this example:


317/3812
> call columnstore_info.table_usage('my_schema', 'my_table');

You can also request all tables for a specified schema:

> call columnstore_info.table_usage('my_schema', NULL);

Note: The quotes around the table name are required, an error will occur without them.

compression_ratio()
The compression_ratio() procedure calculates the average compression ratio across all the compressed extents in
ColumnStore. It is called using:

> call columnstore_info.compression_ratio();

Note: The compression ratio is incorrectly calculated before versions 1.0.12 / 1.1.2

1.1.1.2.9.1.1.4 Information Schema


ALL_PLUGINS Table
Description
The Information Schema ALL_PLUGINS table contains information about server plugins, 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; STORAGE ENGINE , INFORMATION_SCHEMA , AUTHENTICATION , REPLICATION ,
PLUGIN_TYPE
DAEMON or AUDIT .

PLUGIN_TYPE_VERSION Version from the plugin's type-specific descriptor.


Plugin's shared object file name, located in the directory specified by the plugin_dir
PLUGIN_LIBRARY system variable, and used by the INSTALL PLUGIN and UNINSTALL PLUGIN 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.
How the plugin was loaded; one of OFF , ON , FORCE or FORCE_PLUS_PERMANENT . See
LOAD_OPTION
Installing Plugins.
Plugin's maturity level; one of Unknown , Experimental , Alpha , Beta , 'Gamma , and
PLUGIN_MATURITY
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 statement, as well as the
information_schema.PLUGINS table. For specific information about storage engines (a particular type of plugin), see
the Information Schema ENGINES table and the SHOW ENGINES statement.
The table is not a standard Information Schema table, and is a MariaDB extension.

Example
318/3812
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

1.1.1.2.9.1.1.5 Information Schema


APPLICABLE_ROLES Table
The Information Schema APPLICABLE_ROLES table shows the role authorizations that the current user may use.

319/3812
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

The current role is in the ENABLED_ROLES 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 |
+----------------+-------------+--------------+------------+

1.1.1.2.9.1.1.6 Information Schema


CHARACTER_SETS Table
The Information Schema CHARACTER_SETS table contains a list of supported character sets, 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 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 for details on specifying the character set at the server, database, table and
column levels, and Supported Character Sets and Collations 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 |
+--------------------+

1.1.1.2.9.1.1.7 Information Schema


320/3812
CHECK_CONSTRAINTS Table
MariaDB starting with 10.2.22
The Information Schema CHECK_CONSTRAINTS Table was introduced in MariaDB 10.3.10 and MariaDB 10.2.22
.

The Information Schema CHECK_CONSTRAINTS table stores metadata about the constraints 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
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.

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 :

321/3812
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:

322/3812
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)

1.1.1.2.9.1.1.8 Information Schema


CLIENT_STATISTICS Table
The Information Schema CLIENT_STATISTICS table holds statistics about client connections. This is part of the User
Statistics 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.
The cumulative number of seconds elapsed while there were
CONNECTED_TIME INT(21)
connections from this client.

The cumulative number of seconds there was activity on


BUSY_TIME DOUBLE
connections from this client.
The cumulative CPU time elapsed while servicing this client's
connections. Note that this number may be wrong on SMP system if
CPU_TIME DOUBLE
there was a CPU migration for the thread during the execution of the
query.

323/3812
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.
The number of bytes written to the binary log from this client's
BINLOG_BYTES_WRITTEN INT(21)
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.
The number of SELECT commands executed from this client's
SELECT_COMMANDS INT(21)
connections.
The number of UPDATE commands executed from this client's
UPDATE_COMMANDS INT(21)
connections.
The number of other commands executed from this client's
OTHER_COMMANDS INT(21)
connections.
The number of COMMIT commands issued by this client's
COMMIT_TRANSACTIONS INT(21)
connections.
The number of ROLLBACK commands issued by this client's
ROLLBACK_TRANSACTIONS INT(21)
connections.
DENIED_CONNECTIONS INT(21) The number of connections denied to this client.
The number of this client's connections that were terminated
LOST_CONNECTIONS INT(21)
uncleanly.
The number of times this client's connections issued commands that
ACCESS_DENIED INT(21)
were denied.
The number of times this client's connections sent queries that
EMPTY_QUERIES INT(21)
returned no results to the server.
The number of TLS connections created for this client. (>= MariaDB
TOTAL_SSL_CONNECTIONS INT(21)
10.1.1 )
The number of times a statement was aborted, because it was
MAX_STATEMENT_TIME_EXCEEDED INT(21) executed longer than its MAX_STATEMENT_TIME threshold. (>=
MariaDB 10.1.1 )

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

324/3812
1.1.1.2.9.1.1.9 Information Schema
COLLATION_CHARACTER_SET_APPLICABILITY
Table
The Information Schema COLLATION_CHARACTER_SET_APPLICABILITY table shows which character sets 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 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 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 |
+---------------------+--------------------+

1.1.1.2.9.1.1.10 Information Schema


COLLATIONS Table
Contents
1. NO PAD collations
2. Example
3. See Also

325/3812
The Information Schema COLLATIONS table contains a list of supported collations.
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 statement returns the same results and both can be reduced in a similar way.
For example, in MariaDB Server 10.6, 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 Server 10.5 and before, utf8 should be specified instead of utf8mb3 .

NO PAD collations
MariaDB starting with 10.2
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 - specifying the character set at the server, database, table and column
levels
Supported Character Sets and Collations - full list of supported characters sets and collations.

1.1.1.2.9.1.1.11 Information Schema


326/3812
COLUMN_PRIVILEGES Table
The Information Schema COLUMN_PRIVILEGES table contains column privilege information derived from the
mysql.columns_priv 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 for this privilege.

Similar information can be accessed with the SHOW FULL COLUMNS and SHOW GRANTS statements. See the GRANT article
for more about privileges.
This information is also stored in the columns_priv table, in the mysql system database.
For a description of the privileges that are shown in this table, see column privileges.

Example
In the following example, no column-level privilege has been explicitly assigned:

SELECT * FROM information_schema.COLUMN_PRIVILEGES;


Empty set

1.1.1.2.9.1.1.12 Information Schema


COLUMNS Table
The Information Schema COLUMNS table provides information about columns in each table on the server.
It contains the following columns:

Column Description Introduced


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.
Default value for the column. From MariaDB 10.2.7 , literals are quoted
to distinguish them from expressions. NULL means that the column has
COLUMN_DEFAULT no default. In MariaDB 10.2.6 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.
CHARACTER_MAXIMUM_LENGTH Maximum length.
Same as the CHARACTER_MAXIMUM_LENGTH except for multi-byte character
CHARACTER_OCTET_LENGTH
sets.
For numeric types, the precision (number of significant digits) for the
NUMERIC_PRECISION
column. NULL if not a numeric field.
For numeric types, the scale (significant digits to the right of the decimal
NUMERIC_SCALE
point). NULL if not a numeric field.
DATETIME_PRECISION Fractional-seconds precision, or NULL if not a time data type.
327/3812
CHARACTER_SET_NAME Character set if a non-binary string data type, otherwise NULL.
COLLATION_NAME Collation if a non-binary string data type, otherwise NULL.
COLUMN_TYPE Column definition, a MySQL and MariaDB extension.
Index type. PRI for primary key, UNI for unique index, MUL for multiple
COLUMN_KEY
index. A MySQL and MariaDB extension.
Additional information about a column, for example whether the column is
an invisible column, or, from MariaDB 10.3.6, WITHOUT SYSTEM
EXTRA
VERSIONING if the table is not a system-versioned table. A MySQL and
MariaDB extension.
Which privileges you have for the column. A MySQL and MariaDB
PRIVILEGES
extension.
COLUMN_COMMENT Column comments.
Indicates whether the column value is generated (virtual, or computed). MariaDB
IS_GENERATED
Can be ALWAYS or NEVER . 10.2.5
The expression used for computing the column value in a generated MariaDB
GENERATION_EXPRESSION
(virtual, or computed) column. 10.2.5

It provides information similar to, but more complete, than SHOW COLUMNS and mysqlshow .

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';

328/3812
From MariaDB 10.2.7 :

+------------+-------------+------------------+-----------------------+------------------------+
| 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. Note that while mysql-command-line-client 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 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 |
+------------+-------------+------------------+-----------------+------------------------+

1.1.1.2.9.1.1.13 Information Schema DISKS


Table
MariaDB 10.1.32
The DISKS table was introduced in MariaDB 10.1.32 , MariaDB 10.2.14 , and MariaDB 10.3.6 as part of the
DISKS plugin.

Contents
1. Description
2. Example
3. See Also

Description
The DISKS table is created when the DISKS plugin is enabled, and shows metadata about disks on the system.
Before MariaDB 10.4.7, MariaDB 10.3.17, MariaDB 10.2.26 and MariaDB 10.1.41 , this plugin did not check user
privileges. 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, MariaDB 10.3.17, MariaDB 10.2.26 and MariaDB 10.1.41 , it requires the FILE privilege.
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,
329/3812
'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 for details on installing, options
Plugin Overview for details on managing plugins.

1.1.1.2.9.1.1.14 Information Schema


ENABLED_ROLES Table
The Information Schema ENABLED_ROLES table shows the enabled roles 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 table.
See also CURRENT_ROLE().

Examples
SELECT * FROM information_schema.ENABLED_ROLES;
+-----------+
| ROLE_NAME |
+-----------+
| NULL |
+-----------+

SET ROLE staff;

SELECT * FROM information_schema.ENABLED_ROLES;


+-----------+
| ROLE_NAME |
+-----------+
| staff |
+-----------+

1.1.1.2.9.1.1.15 Information Schema ENGINES


Table
The Information Schema ENGINES table displays status information about the server's storage engines.
It contains the following columns:

Column Description
ENGINE
Name of the storage engine.

330/3812
SUPPORT Whether the engine is the default, or is supported or not.
COMMENT Storage engine comments.
TRANSACTIONS Whether or not the engine supports transactions.
XA Whether or not the engine supports XA transactions.
SAVEPOINTS Whether or not savepoints are supported.

It provides identical information to the SHOW ENGINES statement. Since storage engines are plugins, different information
about them is also shown in the information_schema.PLUGINS table and by the SHOW PLUGINS 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. The same applies to FederatedX .

Example

331/3812
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:


332/3812
SELECT ENGINE FROM information_schema.ENGINES WHERE XA = 'YES';
+--------+
| ENGINE |
+--------+
| InnoDB |
+--------+

1.1.1.2.9.1.1.16 Information Schema EVENTS


Table
The Information Schema EVENTS table stores information about Events 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 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 at the time the event was created.
STARTS Start DATETIME for a recurring event, NULL if not defined or not recurring.
ENDS End DATETIME 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 statement, or an empty string if none.
ORIGINATOR MariaDB server ID on which the event was created.
CHARACTER_SET_CLIENT character_set_client system variable session value at the time the event was created.

COLLATION_CONNECTION collation_connection system variable session value at the time the event was created.
DATABASE_COLLATION Database collation with which the event is linked.

The SHOW EVENTS and SHOW CREATE EVENT statements provide similar information.

1.1.1.2.9.1.1.17 Information Schema


FEEDBACK Table
The Information Schema FEEDBACK table is created when the Feedback Plugin 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.

333/3812
VARIABLE_VALUE Contents of the item of information being collected.

It is possible to disable automatic collection, by setting the 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 [email protected] 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

1.1.1.2.9.1.1.18 Information Schema FILES


Table
The FILES tables is unused in MariaDB. See MDEV-11426 .

1.1.1.2.9.1.1.19 Information Schema


GEOMETRY_COLUMNS Table
Description
The Information Schema GEOMETRY_COLUMNS table provides support for Spatial Reference systems for GIS data.
It contains the following columns:

Column Type Null Description


334/3812
Together with F_TABLE_SCHEMA and F_TABLE_NAME , the fully qualified
F_TABLE_CATALOG VARCHAR(512) NO
name of the featured table containing the geometry column.
Together with F_TABLE_CATALOG and F_TABLE_NAME , the fully qualified
F_TABLE_SCHEMA VARCHAR(64) NO
name of the featured table containing the geometry column.
Together with F_TABLE_CATALOG and F_TABLE_SCHEMA , the fully
F_TABLE_NAME VARCHAR(64) NO
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.
Integer reflecting the type of geometry stored in this column (see table
GEOMETRY_TYPE INT(7) NO
below).
Number of dimensions in the spatial reference system. Always 2 in
COORD_DIMENSION TINYINT(2) NO
MariaDB.
MAX_PPR TINYINT(2) NO Always 0 in MariaDB.
ID of the Spatial Reference System used for the coordinate geometry in
SRID SMALLINT(5) NO
this table. It is a foreign key reference to the SPATIAL_REF_SYS table .

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 table.

335/3812
1.1.1.2.9.1.1.20 Information Schema
GLOBAL_STATUS and SESSION_STATUS
Tables
The Information Schema GLOBAL_STATUS and SESSION_STATUS tables store a record of all status variables and their
global and session values respectively. This is the same information as displayed by the SHOW STATUS 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 |
+-----------------------------------------------+--------------------+

1.1.1.2.9.1.1.21 Information Schema


GLOBAL_VARIABLES and
SESSION_VARIABLES Tables
The Information Schema GLOBAL_VARIABLES and SESSION_VARIABLES tables stores a record of all system variables and
their global and session values respectively. This is the same information as displayed by the SHOW VARIABLES
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

336/3812
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

1.1.1.2.9.1.1.22 Information Schema


INDEX_STATISTICS Table
The Information Schema 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 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 ).
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 |
+--------------+------------+------------+-----------+

1.1.1.2.9.1.1.23 Information Schema


KEY_CACHES Table
The Information Schema KEY_CACHES table shows statistics about the segmented key cache,.
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 (set to NULL for any regular key caches and for rows containing aggregation
SEGMENT_NUMBER
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

337/3812
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

1.1.1.2.9.1.1.24 Information Schema


KEY_COLUMN_USAGE Table
The Information Schema 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, 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

338/3812
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

1.1.1.2.9.1.1.25 Information Schema


KEYWORDS Table
MariaDB starting with 10.6.3
The KEYWORDS table was added in MariaDB 10.6.3.

Description
The Information Schema 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 | 339/3812
| 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 |
340/3812
| 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 |
341/3812
| 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 | 342/3812
| 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 |
343/3812
| 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 |
344/3812
| 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 | 345/3812
| 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 |
346/3812
| 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 | 347/3812
| WITHOUT |
| WORK |
| WRAPPER |
| WRITE |
| X509 |
| XOR |
| XA |
| XML |
| YEAR |
| YEAR_MONTH |
| ZEROFILL |
| || |
+-------------------------------+
694 rows in set (0.000 sec)

See Also
Reserved Words

1.1.1.2.9.1.1.26 Information Schema LOCALES


Table
Description
The Information Schema LOCALES table contains a list of all compiled-in locales. It is only available if the LOCALES
plugin 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 statement returns a subset of the information.

Example

348/3812
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 |
+-----+-------+-------------------------------------+-----------------------+---------------------+----
-----------+--------------+------------------------+

1.1.1.2.9.1.1.27 Information Schema


METADATA_LOCK_INFO Table
The Information Schema METADATA_LOCK_INFO table is created by the metadata_lock_info plugin. It shows active
metadata locks and user locks (the locks acquired with GET_LOCK).
It has the following columns:

Column Description
THREAD_ID

One of MDL_INTENTION_EXCLUSIVE , MDL_SHARED , MDL_SHARED_HIGH_PRIO , MDL_SHARED_READ ,


LOCK_MODE 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


One of Global read lock , Schema metadata lock , Table metadata lock , Stored function
LOCK_TYPE 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
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
MDL_INTENTION_EXCLUSIVE 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.

349/3812
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
MDL_SHARED
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.
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
MDL_SHARED_HIGH_PRIO
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).
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
MDL_SHARED_READ
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.
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
MDL_SHARED_WRITE 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.
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
MDL_SHARED_UPGRADABLE 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.
A shared metadata lock for cases when we need to read data from table and block all
MDL_SHARED_READ_ONLY concurrent modifications to it (for both data and metadata). Used by LOCK TABLES
READ statement.
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
MDL_SHARED_NO_WRITE 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.
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
MDL_SHARED_NO_READ_WRITE
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.
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
MDL_EXCLUSIVE held. To be used for CREATE/DROP/RENAME TABLE statements and for execution of
certain phases of other DDL statements.

Examples
350/3812
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
Performance Schema metadata_locks table
GET_LOCK).

1.1.1.2.9.1.1.28 Information Schema


MROONGA_STATS Table
The Information Schema MROONGA_STATS table only exists if the Mroonga 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.

1.1.1.2.9.1.1.29 Information Schema


OPTIMIZER_TRACE Table
MariaDB starting with 10.4.3
351/3812
Optimizer Trace was introduced in MariaDB 10.4.3.

Description
The Information Schema OPTIMIZER_TRACE table contains Optimizer Trace 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.
For huge trace, where the trace is truncated due to the
MISSING_BYTES_BEYOND_MAX_MEM_SIZE optimizer_trace_max_mem_size limit being reached, displays the bytes that
are missing in the trace
Set to 1 if the user running the trace does not have the privileges to see the
INSUFFICENT_PRIVILEGES
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

1.1.1.2.9.1.1.30 Information Schema


PARAMETERS Table
The Information Schema PARAMETERS table stores information about stored procedures and stored functions
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.
CHARACTER_MAXIMUM_LENGTH Maximum length.
CHARACTER_OCTET_LENGTH Same as the CHARACTER_MAXIMUM_LENGTH except for multi-byte character sets.
For numeric types, the precision (number of significant digits) for the column. NULL if
NUMERIC_PRECISION
not a numeric field.
For numeric types, the scale (significant digits to the right of the decimal point). NULL if
NUMERIC_SCALE not a numeric field.

DATETIME_PRECISION Fractional-seconds precision, or NULL if not a time data type.


CHARACTER_SET_NAME Character set if a non-binary string data type, otherwise NULL .
COLLATION_NAME Collation if a non-binary string data type, 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 table, and the output of
352/3812
the SHOW CREATE PROCEDURE and SHOW CREATE FUNCTION statements.
To obtain information about the routine itself, you can query the Information Schema ROUTINES table.

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

1.1.1.2.9.1.1.31 Information Schema


PARTITIONS Table
The Information Schema 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.
The partitioning type; one of RANGE , LIST , HASH , LINEAR HASH , KEY or LINEAR
PARTITION_METHOD
KEY .

Subpartition type; one of HASH , LINEAR HASH , KEY or LINEAR KEY , or NULL if
SUBPARTITION_METHOD
not a subpartition.
Expression used to create the partition by the CREATE TABLE or ALTER TABLE
PARTITION_EXPRESSION
statement.
Expression used to create the subpartition by the CREATE TABLE or ALTER TABLE
SUBPARTITION_EXPRESSION
statement, or NULL if not a subpartition.
For a RANGE partition, contains either MAXINTEGER or an integer, as set in the
PARTITION_DESCRIPTION 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.
353/3812
CREATE_TIME Time the partition was created
UPDATE_TIME Time the partition was last modified.
Time the partition was last checked, or NULL for storage engines that don't
CHECK_TIME
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 .

1.1.1.2.9.1.1.32 Information Schema PLUGINS


Table
The Information Schema PLUGINS table contains information about server plugins.
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; STORAGE ENGINE , INFORMATION_SCHEMA , AUTHENTICATION , REPLICATION ,
PLUGIN_TYPE
DAEMON or AUDIT .

PLUGIN_TYPE_VERSION Version from the plugin's type-specific descriptor.


Plugin's shared object file name, located in the directory specified by the plugin_dir
PLUGIN_LIBRARY system variable, and used by the INSTALL PLUGIN and UNINSTALL PLUGIN
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.
How the plugin was loaded; one of OFF , ON , FORCE or FORCE_PLUS_PERMANENT . See
LOAD_OPTION
Installing Plugins.
Plugin's maturity level; one of Unknown , Experimental , Alpha , Beta , 'Gamma , and
PLUGIN_MATURITY
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 statement. For specific information about
storage engines (a particular type of plugins), see the information_schema.ENGINES table and the SHOW ENGINES
statement.
This table provides a subset of the Information Schema information_schema.ALL_PLUGINS 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:

354/3812
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 query would be:

SELECT PLUGIN_NAME, PLUGIN_STATUS,


PLUGIN_TYPE, PLUGIN_LIBRARY, PLUGIN_LICENSE
FROM INFORMATION_SCHEMA.PLUGINS;

Other SELECT queries can be used to see additional information. For example:

355/3812
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:

356/3812
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
Plugin Overview
SHOW PLUGINS
INSTALL PLUGIN
INSTALL SONAME
UNINSTALL PLUGIN
UNINSTALL SONAME

1.1.1.2.9.1.1.33 Information Schema


PROCESSLIST Table
Contents
1. Example
2. See Also

The Information Schema PROCESSLIST table contains information about running threads.
Similar information can also be returned with the SHOW [FULL] PROCESSLIST statement, or the mysqladmin
processlist command.
It contains the following columns:

Column Description
ID Connection identifier.
USER MariaDB User.
The hostname from which this thread is connected.

HOST 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.
Type of command running, corresponding to the Com_ status variables. See Thread Command
COMMAND
Values.
TIME Seconds that the thread has spent on the current COMMAND so far.
STATE Current state of the thread. See Thread States.
INFO Statement the thread is executing, or NULL if none.
Time in milliseconds with microsecond precision that the thread has spent on the current COMMAND
TIME_MS
so far (see more).
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.
Rows examined by the thread. Only updated by UPDATE, DELETE, and similar statements. For
EXAMINED_ROWS
SELECT and other statements, the value remains zero.
QUERY_ID Query ID.
INFO_BINARY Binary data information

357/3812
TID Thread ID (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 . This means that it can be reliably used also for threads that change @TIMESTAMP (such as
the replication SQL thread). See also MySQL Bug #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.
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

1.1.1.2.9.1.1.34 Information Schema


PROFILING Table
The Information Schema PROFILING table contains information about statement resource usage. Profiling information is
only recorded if the profiling session variable is set to 1.
It contains the following columns:

Column Name Description

358/3812
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 and SHOW PROFILES statements.
Profiling is enabled per session. When a session ends, its profiling information is lost.

1.1.1.2.9.1.1.35 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 plugin, and allows you to see the contents of
the query cache. It creates a table in the information_schema database that shows all queries that are in the cache. You
must have the PROCESS privilege (see GRANT) 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 .
MAX_SORT_LENGTH Added MariaDB 10.1.8 .
GROUP_CONCAT_MAX_LENGTH Added MariaDB 10.1.8 .
CHARACTER_SET_CLIENT Added MariaDB 10.1.8 .
CHARACTER_SET_RESULT Added MariaDB 10.1.8 .
COLLATION Added MariaDB 10.1.8 .
TIMEZONE Added MariaDB 10.1.8 .
DEFAULT_WEEK_FORMAT Added MariaDB 10.1.8 .

359/3812
DIV_PRECISION_INCREMENT Added MariaDB 10.1.8 .
SQL_MODE Added MariaDB 10.1.8 .
LC_TIME_NAMES Added MariaDB 10.1.8 .
CLIENT_LONG_FLAG Added MariaDB 10.1.8 .
CLIENT_PROTOCOL_41 Added MariaDB 10.1.8 .
PROTOCOL_TYPE Added MariaDB 10.1.8 .
MORE_RESULTS_EXISTS Added MariaDB 10.1.8 .
IN_TRANS Added MariaDB 10.1.8 .
AUTOCOMMIT Added MariaDB 10.1.8 .
PACKET_NUMBER Added MariaDB 10.1.8 .
HITS Incremented each time the query cache is hit. Added MariaDB 10.3.2.

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 |
...
+------------------+-----------------+---------------------+--------------------+----------------------
---

1.1.1.2.9.1.1.36 Information Schema


QUERY_RESPONSE_TIME Table
Description
The Information Schema QUERY_RESPONSE_TIME table contains information about queries that take a long time to
execute . It is only available if the QUERY_RESPONSE_TIME 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 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 as an alternative for retrieving the data.

Example

360/3812
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 |
+----------------+-------+----------------+

1.1.1.2.9.1.1.37 Information Schema


REFERENTIAL_CONSTRAINTS Table
The Information Schema REFERENTIAL_CONSTRAINTS table contains information about foreign keys. The single columns
are listed in the KEY_COLUMN_USAGE 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 .
Database name, together with UNIQUE_CONSTRAINT_NAME and
UNIQUE_CONSTRAINT_SCHEMA
REFERENCED_TABLE_NAME identifies the referenced key.

Referenced key name, together with UNIQUE_CONSTRAINT_SCHEMA and


UNIQUE_CONSTRAINT_NAME
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 key table name, together with UNIQUE_CONSTRAINT_SCHEMA and
REFERENCED_TABLE_NAME
UNIQUE_CONSTRAINT_NAME identifies the referenced key.

1.1.1.2.9.1.1.38 Information Schema


ROUTINES Table
The Information Schema ROUTINES table stores information about stored procedures and stored functions.
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 (for stored functions).

361/3812
CHARACTER_MAXIMUM_LENGTH Maximum length.
CHARACTER_OCTET_LENGTH Same as the CHARACTER_MAXIMUM_LENGTH except for multi-byte character sets.
For numeric types, the precision (number of significant digits) for the column. NULL if
NUMERIC_PRECISION
not a numeric field.
For numeric types, the scale (significant digits to the right of the decimal point). NULL if
NUMERIC_SCALE
not a numeric field.
DATETIME_PRECISION Fractional-seconds precision, or NULL if not a time data type.
CHARACTER_SET_NAME Character set if a non-binary string data type, otherwise NULL .
COLLATION_NAME Collation if a non-binary string data type, otherwise NULL.
DATA_TYPE The column's data type.
ROUTINE_BODY Always SQL .
ROUTINE_DEFINITION Definition of the routine.
EXTERNAL_NAME Always NULL .
EXTERNAL_LANGUAGE Always SQL .
PARAMETER_STYLE Always SQL .
Whether the routine is deterministic (can produce only one result for a given list of
IS_DETERMINISTIC
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 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 used by the client that created the routine.
COLLATION_CONNECTION The collation (and character set) used by the connection that created the routine.
The default collation (and character set) for the database, at the time the routine was
DATABASE_COLLATION
created.

It provides information similar to, but more complete, than the SHOW PROCEDURE STATUS and SHOW FUNCTION STATUS
statements.
For information about the parameters accepted by the routine, you can query the information_schema.PARAMETERS
table.

See also
Stored Function Overview
Stored Procedure Overview

1.1.1.2.9.1.1.39 Information Schema


SCHEMA_PRIVILEGES Table
The Information Schema SCHEMA_PRIVILEGES table contains information about 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.

362/3812
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 table.

1.1.1.2.9.1.1.40 Information Schema


SCHEMATA Table
The Information Schema 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 for the database.
DEFAULT_COLLATION_NAME Default collation.
SQL_PATH Always NULL .
SCHEMA_COMMENT Database comment. From MariaDB 10.5.0.

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:

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
ALTER DATABASE
DROP DATABASE
363/3812
SHOW CREATE DATABASE
SHOW DATABASES
Character Sets and Collations

1.1.1.2.9.1.1.41 Information Schema


SPATIAL_REF_SYS Table
MariaDB starting with 10.1.2
The SPATIAL_REF_SYS table was introduced in MariaDB 10.1.2

Description
The Information Schema SPATIAL_REF_SYS table stores information on each spatial reference system used in the
database.
It contains the following columns:

Column Type Null Description


An integer value that uniquely identifies each Spatial Reference System within a
SRID smallint(5) NO
database.
The name of the standard or standards body that is being cited for this reference
AUTH_NAME varchar(512) NO
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 of the Spatial Reference System.

Note: See MDEV-7540 .

See also
information_schema.GEOMETRY_COLUMNS table.

1.1.1.2.9.1.1.42 Information Schema


SPIDER_ALLOC_MEM Table
The Information Schema SPIDER_ALLOC_MEM table is installed along with the Spider 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

1.1.1.2.9.1.1.43 Information Schema


SPIDER_WRAPPER_PROTOCOLS Table
MariaDB starting with 10.5.4
The Information Schema SPIDER_WRAPPER_PROTOCOLS table is installed along with the Spider storage engine from
MariaDB 10.5.4.
364/3812
It contains the following columns:

Column Type Description


WRAPPER_NAME varchar(64)
WRAPPER_VERSION varchar(20)
WRAPPER_DESCRIPTION longtext
WRAPPER_MATURITY varchar(12)

1.1.1.2.9.1.1.44 Information Schema


SQL_FUNCTIONS Table
MariaDB starting with 10.6.3
The SQL_FUNCTIONS table was added in MariaDB 10.6.3.

Description
The Information Schema SQL_FUNCTIONS table contains the list of MariaDB functions.
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 |
365/3812
| 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 |
366/3812
| 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 | 367/3812
| 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

1.1.1.2.9.1.1.45 Information Schema


STATISTICS Table
The Information Schema 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.

Estimate of the number of unique values stored in the index based on statistics stored as integers.
CARDINALITY Higher cardinalities usually mean a greater chance of the index being used in a join. Updated by the
ANALYZE TABLE statement or myisamchk -a.
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.

368/3812
COMMENT Index comments from the CREATE INDEX statement.
Whether or not an index will be ignored by the optimizer. See Ignored Indexes. From MariaDB
IGNORED
10.6.0.

The SHOW 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:
...

1.1.1.2.9.1.1.46 Information Schema


SYSTEM_VARIABLES Table
MariaDB starting with 10.1.1
The information_schema.SYSTEM_VARIABLES table was introduced in MariaDB 10.1.1

The Information Schema SYSTEM_VARIABLES table shows current values and various metadata of all system variables.
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.
How the global value was set — a compile-time default, auto-configured by the server,
GLOBAL_VALUE_ORIGIN
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.
Whether a variable can be set with the SQL statement. Note that many "read only"
READ_ONLY
variables can still be set on the command line.
Whether an argument is required when setting the variable on the command line. NULL
COMMAND_LINE_ARGUMENT
when a variable can not be set on the command line.
Which config file the variable got its value from. NULL if not set in any config file. Added in
GLOBAL_VALUE_PATH
MariaDB 10.5.0.
369/3812
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

1.1.1.2.9.1.1.47 Information Schema


TABLE_CONSTRAINTS Table
The Information Schema TABLE_CONSTRAINTS table contains information about tables that have constraints.
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 table has more information about foreign keys.

1.1.1.2.9.1.1.48 Information Schema


TABLE_PRIVILEGES Table
The Information Schema TABLE_PRIVILEGES table contains table privilege information derived from the
mysql.tables_priv 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 for this privilege.

Similar information can be accessed with the SHOW GRANTS statement. See the GRANT article for more about privileges.
For a description of the privileges that are shown in this table, see table privileges.

1.1.1.2.9.1.1.49 Information Schema


TABLE_STATISTICS Table
The Information Schema TABLE_STATISTICS table shows statistics on table usage.
370/3812
This is part of the User Statistics 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.
The number of rows changed in the table, multiplied by the number of
ROWS_CHANGED_X_INDEXES int(21)
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 |
+--------------+------------+-----------+--------------+------------------------+

1.1.1.2.9.1.1.50 Information Schema TABLES


Table
Contents
1. Examples
1. View Tables in Order of Size
2. See Also

The Information Schema table shows information about the various non- TEMPORARY tables (except tables from the
Information Schema database) and views on the server.
It contains the following columns:

Column Description
TABLE_CATALOG Always def .
TABLE_SCHEMA Database name.
TABLE_NAME Table name.
One of BASE TABLE for a regular table, VIEW for a view, SYSTEM VIEW for Information Schema
TABLE_TYPE
tables, SYSTEM VERSIONED for system-versioned tables or SEQUENCE for sequences.
ENGINE Storage Engine.
VERSION Version number from the table's .frm file
ROW_FORMAT Row format (see InnoDB, Aria and MyISAM row formats).
TABLE_ROWS Number of rows in the table. Some engines, such as XtraDB and InnoDB may store an estimate.
AVG_ROW_LENGTH Average row length in the table.
For InnoDB/XtraDB, the index size, in pages, multiplied by the page size. For Aria and MyISAM,
DATA_LENGTH
length of the data file, in bytes. For MEMORY, the approximate allocated memory.
Maximum length of the data file, ie the total number of bytes that could be stored in the table. Not
MAX_DATA_LENGTH
used in XtraDB and InnoDB.
INDEX_LENGTH Length of the index file.
Bytes allocated but unused. For InnoDB tables in a shared tablespace, the free space of the
DATA_FREE shared tablespace with small safety margin. An estimate in the case of partitioned tables - see
the PARTITIONS table.

AUTO_INCREMENT Next AUTO_INCREMENT value.


Time the table was created. Some engines just return the ctime information from the file system
CREATE_TIME 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.
371/3812
Time the table was last updated. On Windows, the timestamp is not updated on update, so
MyISAM values will be inaccurate. In InnoDB, if shared tablespaces are used, will be NULL,
UPDATE_TIME
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.
CHECKSUM Live checksum value, if any.
CREATE_OPTIONS Extra CREATE TABLE 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.
Placeholder to signal that a table is a temporary table. Currently always "N", except "Y" for
TEMPORARY
generated information_schema tables and NULL for views. Added in MariaDB 10.3.5.

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 lists all tables in a database.

Examples
From MariaDB 10.3.5:

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
...

372/3812
Example with temporary = 'y', from MariaDB 10.3.5:

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 |
...

See Also
mysqlshow
SHOW TABLE STATUS
Finding Tables Without Primary Keys

1.1.1.2.9.1.1.51 Information Schema


TABLESPACES Table
The Information Schema 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

373/3812
MAXIMUM_SIZE

NODEGROUP_ID

TABLESPACE_COMMENT

1.1.1.2.9.1.1.52 Information Schema


THREAD_POOL_GROUPS Table
MariaDB starting with 10.5
The Information Schema THREAD_POOL_GROUPS table was introduced in MariaDB 10.5.0.

The table provides information about thread pool groups, and contains the following columns:

Column Description
GROUP_ID

CONNECTIONS

THREADS

ACTIVE_THREADS

STANDBY_THREADS

QUEUE_LENGTH

HAS_LISTENER

IS_STALLED

Setting 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.

1.1.1.2.9.1.1.53 Information Schema


THREAD_POOL_QUEUES Table
MariaDB starting with 10.5
The Information Schema THREAD_POOL_QUEUES table was introduced in MariaDB 10.5.0.

The table provides information about thread pool queues, and contains the following columns:

Column Description
POSITION

PRIORITY

CONNECTION_ID

QUEUEING_TIME_MICROSECONDS

Setting thread_poll_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 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.

1.1.1.2.9.1.1.54 Information Schema


THREAD_POOL_STATS Table
MariaDB starting with 10.5
The Information Schema THREAD_POOL_STATS table was introduced in MariaDB 10.5.0.

374/3812
The table provides performance counter information for the thread pool, and contains the following columns:

Column Description
GROUP_ID

THREAD_CREATIONS

THREAD_CREATIONS_DUE_TO_STALL

WAKES

WAKES_DUE_TO_STALL

THROTTLES

STALLS

POLLS_BY_LISTENER

POLLS_BY_WORKER

DEQUEUES_BY_LISTENER

DEQUEUES_BY_WORKER

1.1.1.2.9.1.1.55 Information Schema


THREAD_POOL_WAITS Table
MariaDB starting with 10.5
The Information Schema THREAD_POOL_WAITS table was introduced in MariaDB 10.5.0.

The table provides wait counters for the thread pool, and contains the following columns:

Column Description
REASON

COUNT

1.1.1.2.9.1.1.56 Information Schema


TRIGGERS Table
Contents
1. See also

The Information Schema TRIGGERS table contains information about triggers.


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.
Indicates the order that the action will be performed in (of the list of a table's triggers
ACTION_ORDER with identical EVENT_MANIPULATION and ACTION_TIMING values). Before MariaDB
10.2.3 introduced the FOLLOWS and PRECEDES clauses, always 0
ACTION_CONDITION NULL

ACTION_STATEMENT Trigger body, UTF-8 encoded.


ACTION_ORIENTATION Always ROW .

375/3812
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 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
The client character set when the trigger was created, from the session value of the
CHARACTER_SET_CLIENT
character_set_client system variable.

The client collation when the trigger was created, from the session value of the
COLLATION_CONNECTION
collation_connection system variable.
DATABASE_COLLATION Collation of the associated database.

Queries to the TRIGGERS table will return information only for databases and tables for which you have the TRIGGER
privilege. Similar information is returned by the SHOW TRIGGERS statement.

See also
Trigger Overview
CREATE TRIGGER
DROP TRIGGER
SHOW TRIGGERS
SHOW CREATE TRIGGER
Trigger Limitations

1.1.1.2.9.1.1.57 Information Schema


USER_PRIVILEGES Table
The Information Schema USER_PRIVILEGES table contains global user privilege information derived from the
mysql.user 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 for this privilege.

Similar information can be accessed with the SHOW GRANTS statement. See the GRANT article for more about privileges.
This information is also stored in the user table, in the mysql system database.

1.1.1.2.9.1.1.58 Information Schema


USER_STATISTICS Table
The Information Schema USER_STATISTICS table holds statistics about user activity. This is part of the User Statistics
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


The username. The value '#mysql_system_user#' appears when
USER varchar(48)
there is no username (such as for the slave SQL thread).
TOTAL_CONNECTIONS int(21) The number of connections created for this user.

376/3812
CONCURRENT_CONNECTIONS int(21) The number of concurrent connections for this user.
The cumulative number of seconds elapsed while there were
CONNECTED_TIME int(21)
connections from this user.
The cumulative number of seconds there was activity on
BUSY_TIME double
connections from this user.
The cumulative CPU time elapsed while servicing this user's
CPU_TIME double
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.
The number of bytes written to the binary log from this user's
BINLOG_BYTES_WRITTEN int(21)
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.
The number of SELECT commands executed from this user's
SELECT_COMMANDS int(21)
connections.
The number of UPDATE commands executed from this user's
UPDATE_COMMANDS int(21)
connections.
The number of other commands executed from this user's
OTHER_COMMANDS int(21)
connections.
The number of COMMIT commands issued by this user's
COMMIT_TRANSACTIONS int(21)
connections.
The number of ROLLBACK commands issued by this user's
ROLLBACK_TRANSACTIONS int(21)
connections.
DENIED_CONNECTIONS int(21) The number of connections denied to this user.
The number of this user's connections that were terminated
LOST_CONNECTIONS int(21)
uncleanly.
The number of times this user's connections issued commands that
ACCESS_DENIED int(21)
were denied.
The number of times this user's connections sent empty queries to
EMPTY_QUERIES int(21)
the server.
The number of TLS connections created for this user. (>= MariaDB
TOTAL_SSL_CONNECTIONS int(21)
10.1.1 )
The number of times a statement was aborted, because it was
MAX_STATEMENT_TIME_EXCEEDED int(21) executed longer than its MAX_STATEMENT_TIME threshold. (>=
MariaDB 10.1.1 )

Example

377/3812
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

1.1.1.2.9.1.1.59 Information Schema


USER_VARIABLES Table
MariaDB 10.2.0
The USER_VARIABLES table was introduced in MariaDB 10.2.0 as part of the user_variables plugin.

Description
The USER_VARIABLES table is created when the user_variables plugin is enabled, and contains information about user-
defined variables.
The table contains the following columns:

Column Description
VARIABLE_NAME Variable name.
VARIABLE_VALUE Variable value.
VARIABLE_TYPE Variable type.
CHARACTER_SET_NAME Character set.

User variables are reset and the table emptied with the FLUSH USER_VARIABLES 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
Performance Schema user_variables_by_thread Table

1.1.1.2.9.1.1.60 Information Schema VIEWS


378/3812
Table
The Information Schema VIEWS table contains information about views. The SHOW VIEW privilege 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 .

The client character set when the view was created, from the session value of the
CHARACTER_SET_CLIENT
character_set_client system variable.
The client collation when the view was created, from the session value of the
COLLATION_CONNECTION
collation_connection system variable.
ALGORITHM The algorithm used in the view. See View Algorithms.

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
ALTER VIEW
DROP VIEW
SHOW CREATE VIEWS

1.1.1.2.9.1.1.61 Information Schema


WSREP_MEMBERSHIP Table
The WSREP_STATUS table makes Galera node cluster membership information available through the Information
Schema. The same information can be returned using the SHOW WSREP_MEMBERSHIP statement. Only users with
the SUPER can access information from this table.
The WSREP_MEMBERSHIP table is part of the WSREP_INFO plugin.

Example

379/3812
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 |
+-------+--------------------------------------+-------+-----------------+

1.1.1.2.9.1.1.62 Information Schema


WSREP_STATUS Table
The WSREP_STATUS table makes Galera node cluster status information available through the Information Schema.
The same information can be returned using the SHOW WSREP_STATUS statement. Only users with the SUPER
privilege can access information from this table.
The WSREP_STATUS table is part of the WSREP_INFO plugin.

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

1.1.1.2.9.1.2 Extended SHOW


1.1.1.2.9.1.3 TIME_MS column in
INFORMATION_SCHEMA.PROCESSLIST
In MariaDB, an extra column TIME_MS has been added to the INFORMATION_SCHEMA.PROCESSLIST 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.
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. This means that it can be reliably used also for threads that change @TIMESTAMP (such
as the replication SQL thread). See also MySQL Bug #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.
The addition of the TIME_MS column is based on the microsec_process patch, developed by Percona .

1.1.1.2.9.2 Performance Schema


380/3812
The MariaDB Performance Schema is a feature for monitoring the performance of your MariaDB server.
Performance Schema Tables
Tables making up the MariaDB Performance Schema.

Performance Schema Overview


Quick overview of the Performance Schema.

Performance Schema Status Variables


Performance Schema status variables.

Performance Schema System Variables


Performance Schema system variables.

Performance Schema Digests


Normalized statements with data values removed

PERFORMANCE_SCHEMA Storage Engine


2 PERFORMANCE_SCHEMA storage engine, a mechanism for implementing the feature.

There are 4 related questions .

1.1.1.2.9.2.1 Performance Schema Tables


Tables that are part of the MariaDB Performance Schema, a feature for monitoring the performance of MariaDB server.
List of Performance Schema Tables
List and short description of all performance_schema tables.

Performance Schema accounts Table


Account connection information.

Performance Schema cond_instances Table


List of instrumented condition objects.

Performance Schema events_stages_current Table


Current stage events.

Performance Schema events_stages_history Table


Most recent stage events per thread.

Performance Schema events_stages_history_long Table


Most recent completed stage events.

Performance Schema events_stages_summary_by_account_by_event_name


Table
Stage events, summarized by account and event name.

Performance Schema events_stages_summary_by_host_by_event_name Table


Stage events summarized by host and event name.

Performance Schema events_stages_summary_by_thread_by_event_name


Table
Stage events summarized by thread and event name.

Performance Schema events_stages_summary_by_user_by_event_name Table


Stage events summarized by user and event name.

Performance Schema events_stages_summary_global_by_event_name Table


Event summaries.

Performance Schema events_statements_current Table


Current statement events.

Performance Schema events_statements_history Table


Most recent statement events per thread

381/3812
Performance Schema events_statements_history_long Table
Most recent statement events.

Performance Schema
events_statements_summary_by_account_by_event_name Table
Statement events summarized by account and event name.

Performance Schema events_statements_summary_by_digest Table


Statement events summarized by schema and digest.

Performance Schema events_statements_summary_by_host_by_event_name


Table
Statement events summarized by host and event name.

Performance Schema events_statements_summary_by_program Table


Summarizes events for a particular stored program.

Performance Schema events_statements_summary_by_thread_by_event_name


Table
Statement events summarized by thread and event name.

Performance Schema events_statements_summary_by_user_by_event_name


Table
Statement events summarized by user and event name.

Performance Schema events_statements_summary_global_by_event_name


Table
Statement events summarized by event name.

Performance Schema events_transactions_current Table


Current transaction events for each thread.

Performance Schema events_transactions_history Table


Most recent completed transaction events for each thread.

Performance Schema events_transactions_history_long Table


Most recent completed transaction events that have ended globally.

Performance Schema
events_transactions_summary_by_account_by_event_name Table
Transaction events aggregated by account and event name.

Performance Schema events_transactions_summary_by_host_by_event_name


Table
Transaction events aggregated by host and event name.

Performance Schema
events_transactions_summary_by_thread_by_event_name Table
Transaction events aggregated by thread and event name.

Performance Schema events_transactions_summary_by_user_by_event_name


Table
Transaction events aggregated by user and event name.

Performance Schema events_transactions_summary_global_by_event_name


Table
Transaction events aggregated by event name.

Performance Schema events_waits_current Table


Current wait events

Performance Schema events_waits_history Table


Most recent wait events per thread

Performance Schema events_waits_history_long Table


Most recent completed wait events

Performance Schema events_waits_summary_by_account_by_event_name


Table
Wait events summarized by account and event name.
382/3812
Performance Schema events_waits_summary_by_host_by_event_name Table
Wait events summarized by host and event name.

Performance Schema events_waits_summary_by_instance Table


Wait events summarized by instance

Performance Schema events_waits_summary_by_thread_by_event_name Table


Wait events summarized by thread and event name.

Performance Schema events_waits_summary_by_user_by_event_name Table


Wait events summarized by user and event name.

Performance Schema events_waits_summary_global_by_event_name Table


Wait events summarized by event name.

Performance Schema file_instances Table


List of file instruments.

Performance Schema file_summary_by_event_name Table


File events summarized by event name.

Performance Schema file_summary_by_instance Table


File events summarized by instance.

Performance Schema global_status Table


Status variables and their global values.

Performance Schema hosts Table


Hosts used to connect to the server.

Performance Schema host_cache Table


Host_cache information.

Performance Schema memory_summary_by_account_by_event_name Table


Memory usage statistics aggregated by account and event.

Performance Schema memory_summary_by_host_by_event_name Table


Memory usage statistics aggregated by host and event.

Performance Schema memory_summary_by_thread_by_event_name Table


Memory usage statistics aggregated by thread and event.

Performance Schema memory_summary_by_user_by_event_name Table


Memory usage statistics aggregated by user and event.

Performance Schema memory_summary_global_by_event_name Table


Memory usage statistics aggregated by event and event.

Performance Schema metadata_locks Table


Metadata lock information.

Performance Schema mutex_instances Table


Seen mutexes

Performance Schema objects_summary_global_by_type Table


Aggregates object wait events.

Performance Schema performance_timers Table


Available event timers

Performance Schema prepared_statements_instances Table


Aggregated statistics of prepared statements.

Performance Schema replication_applier_configuration Table


Configuration settings affecting replica transactions.

Performance Schema replication_applier_status Table


Information about the general transaction execution status on the slave.

383/3812
Performance Schema replication_applier_status_by_coordinator Table
Coordinator thread status used in multi-threaded replicas to manage multiple workers.

Performance Schema replication_applier_status_by_worker Table


Slave worker thread specific information.

Performance Schema replication_connection_configuration Table


Replica configuration settings used for connecting to the primary.

Performance Schema rwlock_instances Table


Seen read-write locks

Performance Schema session_account_connect_attrs Table


Connection attributes for the current session.

Performance Schema session_connect_attrs Table


Connection attributes for all sessions.

Performance Schema session_status Table


Status variables and their session values.

Performance Schema setup_actors Table


Determines whether monitoring is enabled for host/user combinations.

Performance Schema setup_consumers Table


Lists the types of consumers for which event information is available.

Performance Schema setup_instruments Table


List of instrumented object classes

Performance Schema setup_objects Table


Which objects are monitored.

Performance Schema setup_timers Table


Currently selected event timers

Performance Schema socket_instances Table


Active server connections.

Performance Schema socket_summary_by_event_name Table


Aggregates timer and byte count statistics for all socket I/O operations by socket instrument.

Performance Schema socket_summary_by_instance Table


Aggregates timer and byte count statistics for all socket I/O operations by socket instance.

Performance Schema status_by_account Table


Status variable information by user/host account.

Performance Schema status_by_host Table


Status variable information by host.

Performance Schema status_by_thread Table


Status variable information about active foreground threads.

Performance Schema status_by_user Table


Status variable information by user.

Performance Schema table_handles Table


Table lock information.

Performance Schema table_io_waits_summary_by_index_usage Table


Table I/O waits by index.

Performance Schema table_io_waits_summary_by_table Table


Table I/O waits by table.

Performance Schema table_lock_waits_summary_by_table Table


Table lock waits by table.

384/3812
Performance Schema threads Table
Each server thread is represented as a row in the threads table.

Performance Schema users Table


User connection information.

Performance Schema user_variables_by_thread Table


User-defined variables and the threads that defined them.

1.1.1.2.9.2.1.1 List of Performance Schema


Tables
Below is a list of all Performance Schema tables as well as a brief description of each of them.

Table Description
accounts Client account connection statistics.
cond_instances Synchronization object instances.
events_stages_current Current stage events.
events_stages_history Ten most recent stage events per thread.
events_stages_history_long Ten thousand most recent stage events.
events_stages_summary_by_account_by_event_name Summarized stage events per account and event name.
events_stages_summary_by_host_by_event_name Summarized stage events per host and event name.
events_stages_summary_by_thread_by_event_name Summarized stage events per thread and event name.
Summarized stage events per user name and event
events_stages_summary_by_user_by_event_name
name.
events_stages_summary_global_by_event_name Summarized stage events per event name.
events_statements_current Current statement events.
events_statements_history Ten most recent events per thread.
events_statements_history_long Ten thousand most recent stage events.
Summarized statement events per account and event
events_statements_summary_by_account_by_event_name
name.
events_statements_summary_by_digest Summarized statement events by scheme and digest.
events_statements_summary_by_host_by_event_name Summarized statement events by host and event name.
events_statements_summary_by_program Events for a particular stored program.
Summarized statement events by thread and event
events_statements_summary_by_thread_by_event_name
name.
events_statements_summary_by_user_by_event_name Summarized statement events by user and event name.
events_statements_summary_global_by_event_name Summarized statement events by event name.
events_transactions_current Current transaction events for each thread.
Most recent completed transaction events for each
events_transactions_history
thread.
Most recent completed transaction events that have
events_transactions_history_long
ended globally.
events_transactions_summary_by_account_by_event_name Transaction events aggregated by account and event.
events_transactions_summary_by_host_by_event_name Transaction events aggregated by host and event..

events_transactions_summary_by_thread_by_event_name Transaction events aggregated by thread and event..


events_transactions_summary_by_user_by_event_name Transaction events aggregated by user and event..
events_transactions_summary_global_by_event_name Transaction events aggregated by event name.
events_waits_current Current wait events.
events_waits_history Ten most recent wait events per thread.

385/3812
events_waits_history_long Ten thousand most recent wait events per thread.
events_waits_summary_by_account_by_event_name Summarized wait events by account and event name.
events_waits_summary_by_host_by_event_name Summarized wait events by host and event name.
events_waits_summary_by_instance Summarized wait events by instance.
events_waits_summary_by_thread_by_event_name Summarized wait events by thread and event name.
events_waits_summary_by_user_by_event_name Summarized wait events by user and event name.
events_waits_summary_global_by_event_name Summarized wait events by event name.
file_instances Seen files.
file_summary_by_event_name File events summarized by event name.
file_summary_by_instance File events summarized by instance.
global_status Global status variables and values.
host_cache Host and IP information.
hosts Connections by host.
Memory usage statistics aggregated by account and
memory_summary_by_account_by_event_name
event.
Memory usage statistics aggregated by host. and
memory_summary_by_host_by_event_name
event.
Memory usage statistics aggregated by thread and
memory_summary_by_thread_by_event_name
event..
Memory usage statistics aggregated by user and
memory_summary_by_user_by_event_name
event..
memory_summary_global_by_event_name Memory usage statistics aggregated by event.
metadata_locks Metadata locks.
mutex_instances Seen mutexes.
objects_summary_global_by_type Object wait events.
performance_timers Available event timers.
prepared_statements_instances Aggregate statistics of prepared statements.
replication_applier_configuration Configuration settings affecting replica transactions.
replication_applier_status General transaction execution status on the replica.
replication_applier_status_by_coordinator Coordinator thread specific information.
replication_applier_status_by_worker Replica worker thread specific information.
Rreplica's configuration settings used for connecting to
replication_connection_configuration
the primary.
rwlock_instances Seen read-write locks.
session_account_connect_attrs Current session connection attributes.
session_connect_attrs All session connection attributes.
session_status Session status variables and values.
setup_actors Details on foreground thread monitoring.
setup_consumers Consumers for which event information is stored.
setup_instruments Instrumented objects for which events are collected.
setup_objects Objects to be monitored.
setup_timers Currently selected event timers.
socket_instances Active connections.
socket_summary_by_event_name Timer and byte count statistics by socket instrument.
socket_summary_by_instance Timer and byte count statistics by socket instance.
status_by_account Status variable info by host/user account.

386/3812
status_by_host Status variable info by host.
status_by_thread Status variable info about active foreground threads.
status_by_user Status variable info by user.
table_handles Table lock information.
table_io_waits_summary_by_index_usage Aggregate table I/O wait events by index.
table_io_waits_summary_by_table Aggregate table I/O wait events by table.
table_lock_waits_summary_by_table Aggregate table lock wait events by table.
threads Server thread information.
user_variables_by_thread User-defined variables by thread.
users Connection statistics by user.

1.1.1.2.9.2.1.2 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 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 |
+------------------+-----------+---------------------+-------------------+

1.1.1.2.9.2.1.3 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 system variable.

Column Description
NAME Client user name for the connection, or NULL if an internal thread.

387/3812
OBJECT_INSTANCE_BEGIN Address in memory of the instrumented condition.

1.1.1.2.9.2.1.4 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.
Thread's current event number at the start of the event. Together with THREAD_ID uniquely
EVENT_ID
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
Name and line number of the source file containing the instrumented code that produced the
SOURCE
event.
TIMER_START Value in picoseconds when the event timing started or NULL if timing is not collected.
Value in picoseconds when the event timing ended, or NULL if the event has not ended or
TIMER_END
timing is not collected.
Value in picoseconds of the event's duration or NULL if the event has not ended or timing is
TIMER_WAIT
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 and events_stages_history_long derive their values from the current events.

1.1.1.2.9.2.1.5 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 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.
Thread's current event number at the start of the event. Together with THREAD_ID uniquely
EVENT_ID
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
Name and line number of the source file containing the instrumented code that produced the
SOURCE
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 and events_stages_history_long are related tables.

388/3812
1.1.1.2.9.2.1.6 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 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.
Thread's current event number at the start of the event. Together with THREAD_ID uniquely
EVENT_ID
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
Name and line number of the source file containing the instrumented code that produced the
SOURCE
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 and events_stages_history are related tables.

1.1.1.2.9.2.1.7 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

389/3812
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

1.1.1.2.9.2.1.8 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

390/3812
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

1.1.1.2.9.2.1.9 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

391/3812
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

1.1.1.2.9.2.1.10 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

392/3812
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

1.1.1.2.9.2.1.11 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

393/3812
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

1.1.1.2.9.2.1.12 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.
Thread's current event number at the start of the event. Together with THREAD_ID
EVENT_ID
uniquely identifies the row.
NULL when the event starts, set to the thread's current event number at the end of the
END_EVENT_ID
event.
EVENT_NAME Event instrument name and a NAME from the setup_instruments table
Name and line number of the source file containing the instrumented code that produced
SOURCE
the event.
TIMER_START Value in picoseconds when the event timing started or NULL if timing is not collected.
Value in picoseconds when the event timing ended, or NULL if the event has not ended
TIMER_END
or timing is not collected.
Value in picoseconds of the event's duration or NULL if the event has not ended or
TIMER_WAIT
timing is not collected.
Time in picoseconds spent waiting for locks. The time is calculated in microseconds but
LOCK_TIME
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.
DIGEST_TEXT Statement digest 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

394/3812
OBJECT_INSTANCE_BEGIN Address in memory of the statement object.
MYSQL_ERRNO Error code. See MariaDB Error Codes for a full list.
RETURNED_SQLSTATE The SQLSTATE value.
MESSAGE_TEXT Statement error message. See MariaDB Error Codes.
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.
Number of joins without keys performed by the statement that check for key usage after
SELECT_RANGE_CHECK
each row.
SELECT_SCAN Number of joins performed by the statement which used a full scan of the first table.
Number of merge passes by the sort algorithm performed by the statement. If too high,
SORT_MERGE_PASSES
you may need to increase the 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.

0 if a good index was found for the statement, 1 if no good index was found. See the
NO_GOOD_INDEX_USED
Range checked for each record description in the EXPLAIN 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 and events_statements_history_long derive their values from the current
events table.

1.1.1.2.9.2.1.13 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 system variable
when the server starts up.
The table structure is identical to the events_statements_current 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.
Thread's current event number at the start of the event. Together with THREAD_ID
EVENT_ID
uniquely identifies the row.
NULL when the event starts, set to the thread's current event number at the end of the
END_EVENT_ID
event.
EVENT_NAME Event instrument name and a NAME from the setup_instruments table

Name and line number of the source file containing the instrumented code that produced
SOURCE
the event.

395/3812
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.
Time in picoseconds spent waiting for locks. The time is calculated in microseconds but
LOCK_TIME
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.
DIGEST_TEXT Statement digest 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 for a full list.
RETURNED_SQLSTATE The SQLSTATE value.
MESSAGE_TEXT Statement error message. See MariaDB Error Codes.
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.
Number of joins without keys performed by the statement that check for key usage after
SELECT_RANGE_CHECK
each row.
SELECT_SCAN Number of joins performed by the statement which used a full scan of the first table.
Number of merge passes by the sort algorithm performed by the statement. If too high,
SORT_MERGE_PASSES
you may need to increase the 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.

0 if a good index was found for the statement, 1 if no good index was found. See the
NO_GOOD_INDEX_USED
Range checked for each record description in the EXPLAIN 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 and events_statements_history_long are related tables.

1.1.1.2.9.2.1.14 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

396/3812
system variable when the server starts up.
The table structure is identical to the events_statements_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.
Thread's current event number at the start of the event. Together with THREAD_ID
EVENT_ID
uniquely identifies the row.
NULL when the event starts, set to the thread's current event number at the end of the
END_EVENT_ID
event.
EVENT_NAME Event instrument name and a NAME from the setup_instruments table
Name and line number of the source file containing the instrumented code that produced
SOURCE
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.
Time in picoseconds spent waiting for locks. The time is calculated in microseconds but
LOCK_TIME
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.
DIGEST_TEXT Statement digest 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 for a full list.
RETURNED_SQLSTATE The SQLSTATE value.
MESSAGE_TEXT Statement error message. See MariaDB Error Codes.
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.
Number of joins without keys performed by the statement that check for key usage after
SELECT_RANGE_CHECK
each row.
SELECT_SCAN Number of joins performed by the statement which used a full scan of the first table.
Number of merge passes by the sort algorithm performed by the statement. If too high,
SORT_MERGE_PASSES
you may need to increase the 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.

397/3812
0 if a good index was found for the statement, 1 if no good index was found. See the
NO_GOOD_INDEX_USED
Range checked for each record description in the EXPLAIN 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 and events_statements_history are related tables.

1.1.1.2.9.2.1.15 Performance Schema


events_statements_summary_by_account_by_event_nam
Table
The Performance Schema 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 of the CREATED_TMP_DISK_TABLES column in the events_statements_current
SUM_CREATED_TMP_DISK_TABLES
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 of the SELECT_FULL_RANGE_JOIN column in the events_statements_current
SUM_SELECT_FULL_RANGE_JOIN
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
398/3812
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

1.1.1.2.9.2.1.16 Performance Schema


events_statements_summary_by_digest Table
The Performance Schema digest 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 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. Records are summarised together with SCHEMA NAME .
DIGEST TEXT The unhashed form of the digest.

COUNT_STAR Number of summarized events


399/3812
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 of the CREATED_TMP_DISK_TABLES column in the events_statements_current
SUM_CREATED_TMP_DISK_TABLES
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 of the SELECT_FULL_RANGE_JOIN column in the events_statements_current
SUM_SELECT_FULL_RANGE_JOIN
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 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.

1.1.1.2.9.2.1.17 Performance Schema


events_statements_summary_by_host_by_event_name
Table
The Performance Schema 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.

400/3812
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 of the CREATED_TMP_DISK_TABLES column in the events_statements_current
SUM_CREATED_TMP_DISK_TABLES
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 of the SELECT_FULL_RANGE_JOINW column in the events_statements_current
SUM_SELECT_FULL_RANGE_JOIN
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

401/3812
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

1.1.1.2.9.2.1.18 Performance Schema


events_statements_summary_by_program
Table
MariaDB starting with 10.5.2
The events_statements_summary_by_program table, along with many other new Performance Schema tables, was
added in MariaDB 10.5.2.

Each row in the the Performance Schema 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

402/3812
enum('EVENT',
'FUNCTION',
OBJECT_TYPE 'PROCEDURE', YES Object type for which the summary is generated.
'TABLE',
'TRIGGER')

The schema of the object for which the summary is


OBJECT_SCHEMA varchar(64) NO
generated.
The name of the object for which the summary is
OBJECT_NAME varchar(64) NO
generated.
The number of summarized events (from
bigint(20)
COUNT_STAR NO events_statements_current). This value includes all
unsigned
events, whether timed or nontimed.
The number of summarized events (from
bigint(20)
SUM_TIMER_WAIT NO events_statements_current). This value includes all
unsigned
events, whether timed or nontimed.
bigint(20) The minimum wait time of the summarized timed
MIN_TIMER_WAIT NO
unsigned events.
bigint(20) The average wait time of the summarized timed
AVG_TIMER_WAIT NO
unsigned events.
bigint(20) The maximum wait time of the summarized timed
MAX_TIMER_WAIT NO
unsigned events.
bigint(20) Total number of nested statements invoked during
COUNT_STATEMENTS NO
unsigned stored program execution.
The total wait time of the summarized timed
statements. This value is calculated only for timed
bigint(20)
SUM_STATEMENTS_WAIT NO statements because nontimed statements have a
unsigned
wait time of NULL. The same is true for the other
xxx_STATEMENT_WAIT values.
bigint(20) The minimum wait time of the summarized timed
MIN_STATEMENTS_WAIT NO
unsigned statements.
bigint(20) The average wait time of the summarized timed
AVG_STATEMENTS_WAIT NO
unsigned statements.
bigint(20) The maximum wait time of the summarized timed
MAX_STATEMENTS_WAIT NO
unsigned statements.
bigint(20) The total time spent (in picoseconds) waiting for
SUM_LOCK_TIME NO
unsigned table locks for the summarized statements.
bigint(20) The total number of errors that occurend for the
SUM_ERRORS NO
unsigned summarized statements.

bigint(20) The total number of warnings that occurend for the


SUM_WARNINGS unsigned NO summarized statements.

bigint(20) The total number of affected rows by the


SUM_ROWS_AFFECTED NO
unsigned summarized statements.
bigint(20) The total number of rows returned by the
SUM_ROWS_SENT NO
unsigned summarized statements.
The total number of rows examined by the
bigint(20)
SUM_ROWS_EXAMINED NO summarized statements.The total number of
unsigned
affected rows by the summarized statements.
bigint(20) The total number of on-disk temporary tables
SUM_CREATED_TMP_DISK_TABLES NO
unsigned created by the summarized statements.
bigint(20) The total number of in-memory temporary tables
SUM_CREATED_TMP_TABLES NO
unsigned created by the summarized statements.
bigint(20) The total number of full joins executed by the
SUM_SELECT_FULL_JOIN NO
unsigned summarized statements.
bigint(20) The total number of range search joins executed by
SUM_SELECT_FULL_RANGE_JOIN NO
unsigned the summarized statements.

403/3812
bigint(20) The total number of joins that used ranges on the
SUM_SELECT_RANGE NO
unsigned first table executed by the summarized statements.
The total number of joins that check for key usage
bigint(20)
SUM_SELECT_RANGE_CHECK NO after each row executed by the summarized
unsigned
statements.
bigint(20) The total number of joins that did a full scan of the
SUM_SELECT_SCAN NO
unsigned first table executed by the summarized statements.
The total number of merge passes that the sort
bigint(20)
SUM_SORT_MERGE_PASSES NO algorithm has had to do for the summarized
unsigned
statements.
bigint(20) The total number of sorts that were done using
SUM_SORT_RANGE NO
unsigned ranges for the summarized statements.
bigint(20) The total number of sorted rows that were sorted by
SUM_SORT_ROWS NO
unsigned the summarized statements.
bigint(20) The total number of sorts that were done by
SUM_SORT_SCAN NO
unsigned scanning the table by the summarized statements.
bigint(20) The total number of statements that performed a
SUM_NO_INDEX_USED NO
unsigned table scan without using an index.
bigint(20) The total number of statements where no good
SUM_NO_GOOD_INDEX_USED NO
unsigned index was found.

1.1.1.2.9.2.1.19 Performance Schema


events_statements_summary_by_thread_by_event_name
Table
The Performance Schema 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 associated with the event. Together with EVENT_NAME uniquely identifies the
THREAD_ID
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 of the CREATED_TMP_DISK_TABLES column in the events_statements_current
SUM_CREATED_TMP_DISK_TABLES
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 of the SELECT_FULL_RANGE_JOIN column in the events_statements_current
SUM_SELECT_FULL_RANGE_JOIN
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.

404/3812
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

1.1.1.2.9.2.1.20 Performance Schema


405/3812
events_statements_summary_by_user_by_event_name
Table
The Performance Schema 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 of the CREATED_TMP_DISK_TABLES column in the events_statements_current
SUM_CREATED_TMP_DISK_TABLES
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 of the SELECT_FULL_RANGE_JOIN column in the events_statements_current
SUM_SELECT_FULL_RANGE_JOIN
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

406/3812
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

1.1.1.2.9.2.1.21 Performance Schema


events_statements_summary_global_by_event_name
Table
The Performance Schema 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.

407/3812
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 of the CREATED_TMP_DISK_TABLES column in the events_statements_current
SUM_CREATED_TMP_DISK_TABLES
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 of the SELECT_FULL_RANGE_JOIN column in the events_statements_current
SUM_SELECT_FULL_RANGE_JOIN
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

408/3812
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

1.1.1.2.9.2.1.22 Performance Schema


events_transactions_current Table
MariaDB starting with 10.5.2
The events_transactions_current table was introduced in MariaDB 10.5.2.

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.

409/3812
This column is set to NULL when the event
END_EVENT_ID bigint(20) unsigned starts and updated to the thread current
event number when the event ends.
The name of the instrument from which the
EVENT_NAME varchar(128) event was collected. This is a NAME value
from the setup_instruments table.
The current transaction state. The value is
enum('ACTIVE',
ACTIVE (after START TRANSACTION or
STATE 'COMMITTED',
BEGIN), COMMITTED (after COMMIT), or
'ROLLED BACK')
ROLLED BACK (after ROLLBACK).
TRX_ID bigint(20) unsigned Unused.
Transaction GTID, using the format
GTID varchar(64)
DOMAIN-SERVER_ID-SEQUENCE_NO.
XA transaction format ID for GTRID and
XID_FORMAT_ID int(11)
BQUAL values.
XID_GTRID varchar(130) XA global transaction ID.
XID_BQUAL varchar(130) XA transaction branch qualifier.
The state of the XA transaction. The value
is ACTIVE (after XA START), IDLE (after XA
XA_STATE varchar(64) END), PREPARED (after XA PREPARE),
ROLLED BACK (after XA ROLLBACK), or
COMMITTED (after XA COMMIT).
The name of the source file containing the
instrumented code that produced the event
SOURCE varchar(64)
and the line number in the file at which the
instrumentation occurs.
The unit is picoseconds. When event timing
TIMER_START bigint(20) unsigned started. NULL if event has no timing
information.
The unit is picoseconds. When event timing
TIMER_END bigint(20) unsigned ended. NULL if event has no timing
information.
The unit is picoseconds. Event duration.
TIMER_WAIT bigint(20) unsigned
NULL if event has not timing information.
enum('READ ONLY',
ACCESS_MODE Transaction access mode.
'READ WRITE')
Transaction isolation level. One of:
ISOLATION_LEVEL varchar(64) REPEATABLE READ, READ COMMITTED,
READ UNCOMMITTED, or SERIALIZABLE.
Whether autcommit mode was enabled
AUTOCOMMIT enum('YES','NO')
when the transaction started.

The number of SAVEPOINT statements


NUMBER_OF_SAVEPOINTS bigint(20) unsigned
issued during the transaction.
The number of
NUMBER_OF_ROLLBACK_TO_SAVEPOINT bigint(20) unsigned ROLLBACK_TO_SAVEPOINT statements
issued during the transaction.
The number of RELEASE_SAVEPOINT
NUMBER_OF_RELEASE_SAVEPOINT bigint(20) unsigned
statements issued during the transaction.
OBJECT_INSTANCE_BEGIN bigint(20) unsigned Unused.
The EVENT_ID value of the event within
NESTING_EVENT_ID bigint(20) unsigned
which this event is nested.
enum('TRANSACTION',
NESTING_EVENT_TYPE 'STATEMENT', The nesting event type.
'STAGE', 'WAIT')

1.1.1.2.9.2.1.23 Performance Schema


410/3812
events_transactions_history Table
MariaDB starting with 10.5.2
The events_transactions_history table was introduced in MariaDB 10.5.2.

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 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.
This column is set to NULL when the event
END_EVENT_ID bigint(20) unsigned starts and updated to the thread current
event number when the event ends.
The name of the instrument from which the
EVENT_NAME varchar(128) event was collected. This is a NAME value
from the setup_instruments table.
The current transaction state. The value is
enum('ACTIVE',
ACTIVE (after START TRANSACTION or
STATE 'COMMITTED','
BEGIN), COMMITTED (after COMMIT), or
ROLLED BACK')
ROLLED BACK (after ROLLBACK).
TRX_ID bigint(20) unsigned Unused.
Transaction GTID, using the format
GTID varchar(64)
DOMAIN-SERVER_ID-SEQUENCE_NO.
XA transaction format ID for GTRID and
XID_FORMAT_ID int(11)
BQUAL values.
XID_GTRID varchar(130) XA global transaction ID.
XID_BQUAL varchar(130) XA transaction branch qualifier.
The state of the XA transaction. The value
is ACTIVE (after XA START), IDLE (after XA
XA_STATE varchar(64) END), PREPARED (after XA PREPARE),
ROLLED BACK (after XA ROLLBACK), or
COMMITTED (after XA COMMIT).
The name of the source file containing the
instrumented code that produced the event
SOURCE varchar(64) and the line number in the file at which the
instrumentation occurs.

The unit is picoseconds. When event timing


TIMER_START bigint(20) unsigned started. NULL if event has no timing
information.
The unit is picoseconds. When event timing
TIMER_END bigint(20) unsigned ended. NULL if event has no timing
information.
The unit is picoseconds. Event duration.
TIMER_WAIT bigint(20) unsigned
NULL if event has not timing information.
enum('READ ONLY',
ACCESS_MODE Transaction access mode.
'READ WRITE')
Transaction isolation level. One of:
REPEATABLE READ, READ
ISOLATION_LEVEL varchar(64)
COMMITTED, READ UNCOMMITTED, or
SERIALIZABLE.
AUTOCOMMIT enum('YES', 'NO') NO
411/3812
The number of SAVEPOINT statements
NUMBER_OF_SAVEPOINTS bigint(20) unsigned
issued during the transaction.
The number of
NUMBER_OF_ROLLBACK_TO_SAVEPOINT bigint(20) unsigned ROLLBACK_TO_SAVEPOINT statements
issued during the transaction.
The number of RELEASE_SAVEPOINT
NUMBER_OF_RELEASE_SAVEPOINT bigint(20) unsigned
statements issued during the transaction.
OBJECT_INSTANCE_BEGIN bigint(20) unsigned Unused.
The EVENT_ID value of the event within
NESTING_EVENT_ID bigint(20) unsigned
which this event is nested.
enum('TRANSACTION','
NESTING_EVENT_TYPE STATEMENT', The nesting event type.
'STAGE', 'WAIT')

1.1.1.2.9.2.1.24 Performance Schema


events_transactions_history_long Table
MariaDB starting with 10.5.2
The events_transactions_history_long table was introduced in MariaDB 10.5.2.

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 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.
This column is set to NULL when the event
END_EVENT_ID bigint(20) unsigned starts and updated to the thread current
event number when the event ends.
The name of the instrument from which the
EVENT_NAME varchar(128) event was collected. This is a NAME value
from the setup_instruments table.
The current transaction state. The value is
enum('ACTIVE',
ACTIVE (after START TRANSACTION or
STATE 'COMMITTED','
BEGIN), COMMITTED (after COMMIT), or
ROLLED BACK')
ROLLED BACK (after ROLLBACK).
TRX_ID bigint(20) unsigned Unused.
Transaction GTID, using the format
GTID varchar(64)
DOMAIN-SERVER_ID-SEQUENCE_NO.
XA transaction format ID for GTRID and
XID_FORMAT_ID int(11)
BQUAL values.
XID_GTRID varchar(130) XA global transaction ID.

XID_BQUAL varchar(130) XA transaction branch qualifier.

The state of the XA transaction. The value


is ACTIVE (after XA START), IDLE (after XA
XA_STATE varchar(64) END), PREPARED (after XA PREPARE),
ROLLED BACK (after XA ROLLBACK), or
COMMITTED (after XA COMMIT).

412/3812
The name of the source file containing the
instrumented code that produced the event
SOURCE varchar(64)
and the line number in the file at which the
instrumentation occurs.
The unit is picoseconds. When event timing
TIMER_START bigint(20) unsigned started. NULL if event has no timing
information.
The unit is picoseconds. When event timing
TIMER_END bigint(20) unsigned ended. NULL if event has no timing
information.
The unit is picoseconds. Event duration.
TIMER_WAIT bigint(20) unsigned
NULL if event has not timing information.
enum('READ ONLY',
ACCESS_MODE Transaction access mode.
'READ WRITE')
Transaction isolation level. One of:
REPEATABLE READ, READ
ISOLATION_LEVEL varchar(64)
COMMITTED, READ UNCOMMITTED, or
SERIALIZABLE.
AUTOCOMMIT enum('YES', 'NO') NO
The number of SAVEPOINT statements
NUMBER_OF_SAVEPOINTS bigint(20) unsigned
issued during the transaction.
The number of
NUMBER_OF_ROLLBACK_TO_SAVEPOINT bigint(20) unsigned ROLLBACK_TO_SAVEPOINT statements
issued during the transaction.
The number of RELEASE_SAVEPOINT
NUMBER_OF_RELEASE_SAVEPOINT bigint(20) unsigned
statements issued during the transaction.
OBJECT_INSTANCE_BEGIN bigint(20) unsigned Unused.
The EVENT_ID value of the event within
NESTING_EVENT_ID bigint(20) unsigned
which this event is nested.
enum('TRANSACTION','
NESTING_EVENT_TYPE STATEMENT', The nesting event type.
'STAGE', 'WAIT')

1.1.1.2.9.2.1.25 Performance Schema


events_transactions_summary_by_account_by_event_na
Table
MariaDB starting with 10.5.2
The events_transactions_summary_by_account_by_event_name table was introduced in MariaDB 10.5.2.

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) The number of summarized events. This value includes all events,
unsigned whether timed or nontimed.

The total wait time of the summarized timed events. This value is
bigint(20)
SUM_TIMER_WAIT calculated only for timed events because nontimed events have a wait
unsigned
time of NULL. The same is true for the other xxx_TIMER_WAIT values.

413/3812
bigint(20)
MIN_TIMER_WAIT The minimum wait time of the summarized timed events.
unsigned
bigint(20)
AVG_TIMER_WAIT The average wait time of the summarized timed events.
unsigned
bigint(20)
MAX_TIMER_WAIT The maximum wait time of the summarized timed events.
unsigned
bigint(20)
COUNT_READ_WRITE The total number of only READ/WRITE transaction events.
unsigned
bigint(20)
SUM_TIMER_READ_WRITE The total wait time of only READ/WRITE transaction events.
unsigned
bigint(20)
MIN_TIMER_READ_WRITE The minimum wait time of only READ/WRITE transaction events.
unsigned
bigint(20)
AVG_TIMER_READ_WRITE The average wait time of only READ/WRITE transaction events.
unsigned
bigint(20)
MAX_TIMER_READ_WRITE The maximum wait time of only READ/WRITE transaction events.
unsigned
bigint(20)
COUNT_READ_ONLY The total number of only READ ONLY transaction events.
unsigned
bigint(20)
SUM_TIMER_READ_ONLY The total wait time of only READ ONLY transaction events.
unsigned
bigint(20)
MIN_TIMER_READ_ONLY The minimum wait time of only READ ONLY transaction events.
unsigned
bigint(20)
AVG_TIMER_READ_ONLY The average wait time of only READ ONLY transaction events.
unsigned
bigint(20)
MAX_TIMER_READ_ONLY The maximum wait time of only READ ONLY transaction events.
unsigned

1.1.1.2.9.2.1.26 Performance Schema


events_transactions_summary_by_host_by_event_name
Table
MariaDB starting with 10.5.2
The events_transactions_summary_by_host_by_event_name table was introduced in MariaDB 10.5.2.

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.
bigint(20) The number of summarized events. This value includes all events,
COUNT_STAR
unsigned whether timed or nontimed.
The total wait time of the summarized timed events. This value is
bigint(20)
SUM_TIMER_WAIT calculated only for timed events because nontimed events have a wait
unsigned
time of NULL. The same is true for the other xxx_TIMER_WAIT values.
bigint(20)
MIN_TIMER_WAIT The minimum wait time of the summarized timed events.
unsigned
bigint(20)
AVG_TIMER_WAIT The average wait time of the summarized timed events.
unsigned
bigint(20)
MAX_TIMER_WAIT The maximum wait time of the summarized timed events.
unsigned
bigint(20)
COUNT_READ_WRITE The total number of only READ/WRITE transaction events.
unsigned
414/3812
bigint(20)
SUM_TIMER_READ_WRITE The total wait time of only READ/WRITE transaction events.
unsigned
bigint(20)
MIN_TIMER_READ_WRITE The minimum wait time of only READ/WRITE transaction events.
unsigned
bigint(20)
AVG_TIMER_READ_WRITE The average wait time of only READ/WRITE transaction events.
unsigned
bigint(20)
MAX_TIMER_READ_WRITE The maximum wait time of only READ/WRITE transaction events.
unsigned
bigint(20)
COUNT_READ_ONLY The total number of only READ ONLY transaction events.
unsigned
bigint(20)
SUM_TIMER_READ_ONLY The total wait time of only READ ONLY transaction events.
unsigned
bigint(20)
MIN_TIMER_READ_ONLY The minimum wait time of only READ ONLY transaction events.
unsigned
bigint(20)
AVG_TIMER_READ_ONLY The average wait time of only READ ONLY transaction events.
unsigned
bigint(20)
MAX_TIMER_READ_ONLY The maximum wait time of only READ ONLY transaction events.
unsigned

1.1.1.2.9.2.1.27 Performance Schema


events_transactions_summary_by_thread_by_event_nam
Table
MariaDB starting with 10.5.2
The events_transactions_summary_by_thread_by_event_name table was introduced in MariaDB 10.5.2.

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 | |
+----------------------+---------------------+------+-----+---------+-------+

1.1.1.2.9.2.1.28 Performance Schema


events_transactions_summary_by_user_by_event_name
Table
MariaDB starting with 10.5.2
The events_transactions_summary_by_user_by_event_name table was introduced in MariaDB 10.5.2.

415/3812
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 | |
+----------------------+---------------------+------+-----+---------+-------+

1.1.1.2.9.2.1.29 Performance Schema


events_transactions_summary_global_by_event_name
Table
MariaDB starting with 10.5.2
The events_transactions_summary_global_by_event_name table was introduced in MariaDB 10.5.2.

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 | |
+----------------------+---------------------+------+-----+---------+-------+

1.1.1.2.9.2.1.30 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

416/3812
THREAD_ID Thread associated with the event. Together with EVENT_ID uniquely identifies the row.

Thread's current event number at the start of the event. Together with THREAD_ID uniquely
EVENT_ID
identifies the row.
NULL when the event starts, set to the thread's current event number at the end of the
END_EVENT_ID
event.
EVENT_NAME Event instrument name and a NAME from the setup_instruments table
Name and line number of the source file containing the instrumented code that produced
SOURCE
the event.
TIMER_START Value in picoseconds when the event timing started or NULL if timing is not collected.
Value in picoseconds when the event timing ended, or NULL if the event has not ended or
TIMER_END
timing is not collected.
Value in picoseconds of the event's duration or NULL if the event has not ended or timing
TIMER_WAIT
is not collected.
Number of spin rounds for a mutex, or NULL if spin rounds are not used, or spinning is not
SPINS
instrumented.
Name of the schema that contains the table for table I/O objects, otherwise NULL for file
OBJECT_SCHEMA
I/O and synchronization objects.
File name for file I/O objects, table name for table I/O objects, the socket's IP:PORT value
OBJECT_NAME
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.
FILE for a file object, TABLE or TEMPORARY TABLE for a table object, or NULL for a
OBJECT_TYPE
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 and events_waits_history_long derive their values from the current events.

1.1.1.2.9.2.1.31 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 system variable when the
server starts up.
The table structure is identical to the events_waits_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.
Thread's current event number at the start of the event. Together with THREAD_ID uniquely
EVENT_ID
identifies the row.
NULL when the event starts, set to the thread's current event number at the end of the
END_EVENT_ID
event.
EVENT_NAME Event instrument name and a NAME from the setup_instruments table
Name and line number of the source file containing the instrumented code that produced
SOURCE
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.

417/3812
Number of spin rounds for a mutex, or NULL if spin rounds are not used, or spinning is not
SPINS
instrumented.
Name of the schema that contains the table for table I/O objects, otherwise NULL for file
OBJECT_SCHEMA
I/O and synchronization objects.
File name for file I/O objects, table name for table I/O objects, the socket's IP:PORT value
OBJECT_NAME
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.
FILE for a file object, TABLE or TEMPORARY TABLE for a table object, or NULL for a
OBJECT_TYPE
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_long are related tables.

1.1.1.2.9.2.1.32 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 system variable when the
server starts up.
The table structure is identical to the events_waits_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.
Thread's current event number at the start of the event. Together with THREAD_ID uniquely
EVENT_ID
identifies the row.
NULL when the event starts, set to the thread's current event number at the end of the
END_EVENT_ID
event.
EVENT_NAME Event instrument name and a NAME from the setup_instruments table
Name and line number of the source file containing the instrumented code that produced
SOURCE
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.
Number of spin rounds for a mutex, or NULL if spin rounds are not used, or spinning is not
SPINS
instrumented.
Name of the schema that contains the table for table I/O objects, otherwise NULL for file
OBJECT_SCHEMA
I/O and synchronization objects.
File name for file I/O objects, table name for table I/O objects, the socket's IP:PORT value
OBJECT_NAME 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.
FILE for a file object, TABLE or TEMPORARY TABLE for a table object, or NULL for a
OBJECT_TYPE
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 .

418/3812
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.

1.1.1.2.9.2.1.33 Performance Schema


events_waits_summary_by_account_by_event_name
Table
The Performance Schema 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

419/3812
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

1.1.1.2.9.2.1.34 Performance Schema


events_waits_summary_by_host_by_event_name
Table
The Performance Schema 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

420/3812
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

1.1.1.2.9.2.1.35 Performance Schema


events_waits_summary_by_instance Table
The Performance Schema 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.
If an instrument creates multiple instances, each instance has a unique
OBJECT_INSTANCE_BEGIN
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

421/3812
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

1.1.1.2.9.2.1.36 Performance Schema


events_waits_summary_by_thread_by_event_name
Table
The Performance Schema 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

422/3812
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

1.1.1.2.9.2.1.37 Performance Schema


events_waits_summary_by_user_by_event_name
Table
The Performance Schema 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

423/3812
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

1.1.1.2.9.2.1.38 Performance Schema


events_waits_summary_global_by_event_name
Table
The Performance Schema 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

424/3812
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

1.1.1.2.9.2.1.39 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 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

425/3812
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 |
...

1.1.1.2.9.2.1.40 Performance Schema


file_summary_by_event_name Table
The Performance Schema 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.
Number of all write operations, including FPUTS , FPUTC , FPRINTF , VFPRINTF ,
COUNT_WRITE
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.
Number of all miscellaneous operations not counted above, including CREATE ,
COUNT_MISC 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.

426/3812
I/O operations can be avoided by caching, in which case they will not be recorded in this table.
You can TRUNCATE 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

1.1.1.2.9.2.1.41 Performance Schema


file_summary_by_instance Table
The Performance Schema 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.
Address in memory. Together with FILE_NAME and EVENT_NAME uniquely identifies a
OBJECT_INSTANCE_BEGIN
row.
COUNT_STAR Number of summarized events
SUM_TIMER_WAIT Total wait time of the summarized events that are timed.

427/3812
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.
Number of all write operations, including FPUTS , FPUTC , FPRINTF , VFPRINTF ,
COUNT_WRITE
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.
Number of all miscellaneous operations not counted above, including CREATE ,
COUNT_MISC 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 the table, which will reset all counters to zero.

Example

428/3812
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

1.1.1.2.9.2.1.42 Performance Schema


global_status Table
MariaDB starting with 10.5.2
The global_status table was added in MariaDB 10.5.2.

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 resets global status variables, including thread, account, host, and user status, but not those that
are never reset by the server.

429/3812
1.1.1.2.9.2.1.43 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 system variable, which, if set to zero, will disable
connection statistics in the hosts table.
It contains the following columns:

Column Description
Host name used by the client to connect, NULL for internal threads or user sessions that
HOST
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 |
+-----------+---------------------+-------------------+

1.1.1.2.9.2.1.44 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.
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
HOST_VALIDATED
which case DNS lookup is performed for each connect until either
successful or a permanent error.
Number of connection errors. Counts only protocol handshake
SUM_CONNECT_ERRORS errors for hosts that passed validation. These errors count towards
max_connect_errors.
Number of blocked connections because SUM_CONNECT_ERRORS
COUNT_HOST_BLOCKED_ERRORS exceeded the 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.
Number of host name format errors, for example a numeric host
COUNT_FORMAT_ERRORS
column.
COUNT_ADDRINFO_TRANSIENT_ERRORS Number of transient errors during host-to-IP reverse DNS lookups.
Number of permanent errors during host-to-IP reverse DNS
COUNT_ADDRINFO_PERMANENT_ERRORS
lookups.

430/3812
Number of forward-confirmed reverse DNS errors, which occur
COUNT_FCRDNS_ERRORS when IP-to-host DNS lookup does not match the originating IP
address.
Number of errors occurring because no user from the host is
permitted to log in. These attempts return error code 1130
COUNT_HOST_ACL_ERRORS
ER_HOST_NOT_PRIVILEGED and do not proceed to username and
password authentication.
Number of errors due to requesting an authentication plugin that
COUNT_NO_AUTH_PLUGIN_ERRORS was not available. This can be due to the plugin never having been
loaded, or the load attempt failing.
Number of errors reported by an authentication plugin. Plugins can
increment COUNT_AUTHENTICATION_ERRORS or
COUNT_AUTH_PLUGIN_ERRORS
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.
Number of errors detected when a proxy user is proxied to a user
COUNT_PROXY_USER_ERRORS
that does not exist.
Number of errors detected when a proxy user is proxied to a user
COUNT_PROXY_USER_ACL_ERRORS
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.

Number of errors due to the user not having permission to access


COUNT_DEFAULT_DATABASE_ERRORS
the specified default database, or it not existing.
Number of errors due to statements in the init_connect system
COUNT_INIT_CONNECT_ERRORS
variable.
Number of local server errors, such as out-of-memory errors,
COUNT_LOCAL_ERRORS
unrelated to network, authentication, or authorization.
Number of unknown errors that cannot be allocated to another
COUNT_UNKNOWN_ERRORS
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, TRUNCATE TABLE host_cache
or by setting the host_cache_size system variable at runtime.

1.1.1.2.9.2.1.45 Performance Schema


memory_summary_by_account_by_event_name
Table
MariaDB starting with 10.5.2
The memory_summary_by_account_by_event_name table was introduced in MariaDB 10.5.2.

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
memory_summary_by_thread_by_event_name
memory_summary_by_user_by_event_name
memory_global_by_event_name
The memory_summary_by_account_by_event_name table contains memory usage statistics aggregated by account and

431/3812
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.
bigint(20)
COUNT_ALLOC NO NULL Total number of allocations to memory.
unsigned
bigint(20) Total number of attempts to free the
COUNT_FREE NO NULL
unsigned allocated memory.
bigint(20)
SUM_NUMBER_OF_BYTES_ALLOC NO NULL Total number of bytes allocated.
unsigned
bigint(20)
SUM_NUMBER_OF_BYTES_FREE NO NULL Total number of bytes freed
unsigned
Lowest number of allocated blocks
LOW_COUNT_USED bigint(20) NO NULL (lowest value of
CURRENT_COUNT_USED).
Currently allocated blocks that have not
CURRENT_COUNT_USED bigint(20) NO NULL been freed (COUNT_ALLOC minus
COUNT_FREE).
Highest number of allocated blocks
HIGH_COUNT_USED bigint(20) NO NULL (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 (total
CURRENT_NUMBER_OF_BYTES_USED bigint(20) NO NULL
allocated minus total freed).
HIGH_NUMBER_OF_BYTES_USED bigint(20) NO NULL Highest number of bytes used.

1.1.1.2.9.2.1.46 Performance Schema


memory_summary_by_host_by_event_name
Table
MariaDB starting with 10.5.2
The memory_summary_by_host_by_event_name table was introduced in MariaDB 10.5.2.

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
memory_summary_by_thread_by_event_name
memory_summary_by_user_by_event_name
memory_global_by_event_name
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.
bigint(20)
COUNT_ALLOC NO NULL Total number of allocations to memory.
unsigned
bigint(20) Total number of attempts to free the
COUNT_FREE NO NULL
unsigned allocated memory.

432/3812
bigint(20)
SUM_NUMBER_OF_BYTES_ALLOC unsigned NO NULL Total number of bytes allocated.

bigint(20)
SUM_NUMBER_OF_BYTES_FREE NO NULL Total number of bytes freed
unsigned
Lowest number of allocated blocks
LOW_COUNT_USED bigint(20) NO NULL (lowest value of
CURRENT_COUNT_USED).
Currently allocated blocks that have not
CURRENT_COUNT_USED bigint(20) NO NULL been freed (COUNT_ALLOC minus
COUNT_FREE).
Highest number of allocated blocks
HIGH_COUNT_USED bigint(20) NO NULL (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 (total
CURRENT_NUMBER_OF_BYTES_USED bigint(20) NO NULL
allocated minus total freed).
HIGH_NUMBER_OF_BYTES_USED bigint(20) NO NULL Highest number of bytes used.

1.1.1.2.9.2.1.47 Performance Schema


memory_summary_by_thread_by_event_name
Table
MariaDB starting with 10.5.2
The memory_summary_by_thread_by_event_name table was introduced in MariaDB 10.5.2.

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
memory_summary_by_thread_by_event_name
memory_summary_by_user_by_event_name
memory_global_by_event_name
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


bigint(20)
THREAD_ID NO NULL Thread id.
unsigned
EVENT_NAME varchar(128) NO NULL Event name.
bigint(20)
COUNT_ALLOC NO NULL Total number of allocations to memory.
unsigned
bigint(20) Total number of attempts to free the
COUNT_FREE NO NULL
unsigned allocated memory.
bigint(20)
SUM_NUMBER_OF_BYTES_ALLOC NO NULL Total number of bytes allocated.
unsigned
bigint(20)
SUM_NUMBER_OF_BYTES_FREE NO NULL Total number of bytes freed
unsigned
Lowest number of allocated blocks (lowest
LOW_COUNT_USED bigint(20) NO NULL
value of CURRENT_COUNT_USED).
Currently allocated blocks that have not
CURRENT_COUNT_USED bigint(20) NO NULL been freed (COUNT_ALLOC minus
COUNT_FREE).

433/3812
Highest number of allocated blocks
HIGH_COUNT_USED bigint(20) NO NULL (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 (total
CURRENT_NUMBER_OF_BYTES_USED bigint(20) NO NULL
allocated minus total freed).
HIGH_NUMBER_OF_BYTES_USED bigint(20) NO NULL Highest number of bytes used.

1.1.1.2.9.2.1.48 Performance Schema


memory_summary_by_user_by_event_name
Table
MariaDB starting with 10.5.2
The memory_summary_by_user_by_event_name table was introduced in MariaDB 10.5.2.

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
memory_summary_by_thread_by_event_name
memory_summary_by_user_by_event_name
memory_global_by_event_name
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.
bigint(20)
COUNT_ALLOC NO NULL Total number of allocations to memory.
unsigned
bigint(20) Total number of attempts to free the
COUNT_FREE NO NULL
unsigned allocated memory.
bigint(20)
SUM_NUMBER_OF_BYTES_ALLOC NO NULL Total number of bytes allocated.
unsigned
bigint(20)
SUM_NUMBER_OF_BYTES_FREE NO NULL Total number of bytes freed
unsigned
Lowest number of allocated blocks
LOW_COUNT_USED bigint(20) NO NULL (lowest value of
CURRENT_COUNT_USED).
Currently allocated blocks that have not
CURRENT_COUNT_USED bigint(20) NO NULL been freed (COUNT_ALLOC minus
COUNT_FREE).
Highest number of allocated blocks
HIGH_COUNT_USED bigint(20) NO NULL (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 (total
CURRENT_NUMBER_OF_BYTES_USED bigint(20) NO NULL
allocated minus total freed).
HIGH_NUMBER_OF_BYTES_USED bigint(20) NO NULL Highest number of bytes used.

1.1.1.2.9.2.1.49 Performance Schema


memory_summary_global_by_event_name
434/3812
Table
MariaDB starting with 10.5.2
The memory_summary_global_by_event_name table was introduced in MariaDB 10.5.2.

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
memory_summary_by_thread_by_event_name
memory_summary_by_user_by_event_name
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.
bigint(20)
COUNT_ALLOC NO NULL Total number of allocations to memory.
unsigned
bigint(20) Total number of attempts to free the
COUNT_FREE NO NULL
unsigned allocated memory.
bigint(20)
SUM_NUMBER_OF_BYTES_ALLOC NO NULL Total number of bytes allocated.
unsigned
bigint(20)
SUM_NUMBER_OF_BYTES_FREE NO NULL Total number of bytes freed
unsigned
Lowest number of allocated blocks (lowest
LOW_COUNT_USED bigint(20) NO NULL
value of CURRENT_COUNT_USED).
Currently allocated blocks that have not
CURRENT_COUNT_USED bigint(20) NO NULL been freed (COUNT_ALLOC minus
COUNT_FREE).
Highest number of allocated blocks
HIGH_COUNT_USED bigint(20) NO NULL (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 (total
CURRENT_NUMBER_OF_BYTES_USED bigint(20) NO NULL
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

1.1.1.2.9.2.1.50 Performance Schema


metadata_locks Table
435/3812
MariaDB starting with 10.5.2
The metadata_locks table was introduced in MariaDB 10.5.2.

The metadata_locks table contains metadata lock 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:

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
system variabe.
The table is read-only, and TRUNCATE TABLE cannot be used to empty the table.
The table contains the following columns:

Field Type Null Default Description


Object type. One of BACKUP , COMMIT , EVENT ,
FUNCTION , GLOBAL , LOCKING SERVICE , PROCEDURE ,
OBJECT_TYPE varchar(64) NO NULL
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.
bigint(20)
OBJECT_INSTANCE_BEGIN NO NULL Address in memory of the instrumented object.
unsigned
Lock type. One of BACKUP_FTWRL1 , BACKUP_START ,
BACKUP_TRANS_DML , EXCLUSIVE ,
LOCK_TYPE varchar(32) NO NULL INTENTION_EXCLUSIVE , SHARED , SHARED_HIGH_PRIO ,
SHARED_NO_READ_WRITE , SHARED_NO_WRITE ,
SHARED_READ , SHARED_UPGRADABLE or SHARED_WRITE .

Lock duration. One of EXPLICIT (locks released by


explicit action, for example a global lock acquired with
FLUSH TABLES WITH READ LOCK) , STATEMENT
LOCK_DURATION varchar(32) NO NULL
(locks implicitly released at statement end) or
TRANSACTION (locks implicitly released at transaction
end).
Lock status. One of GRANTED , KILLED , PENDING ,
LOCK_STATUS varchar(32) NO NULL POST_RELEASE_NOTIFY , PRE_ACQUIRE_NOTIFY , TIMEOUT
or VICTIM .
Source file containing the instrumented code that
produced the event, as well as the line number where
SOURCE varchar(64) YES NULL
the instrumentation occurred. This allows one to
examine the source code involved.
bigint(20)
OWNER_THREAD_ID YES NULL Thread that requested the lock.
unsigned
bigint(20)
OWNER_EVENT_ID YES NULL Event that requested the lock.
unsigned

1.1.1.2.9.2.1.51 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.
436/3812
The 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 .

1.1.1.2.9.2.1.52 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 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

1.1.1.2.9.2.1.53 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 table.

437/3812
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.
Minimum timer overhead, determined during initialization by calling the timer 20 times and
TIMER_OVERHEAD 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 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 |
+-------------+-----------------+------------------+---------------------+

1.1.1.2.9.2.1.54 Performance Schema


prepared_statements_instances Table
MariaDB starting with 10.5.2
The prepared_statements_instances table was introduced in MariaDB 10.5.2.

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 system variable, which is by default autosized on startup.
The table contains the following columns:

438/3812
+-----------------------------+--------------------------------------------------------+------+-----+--
-------+-------+
| 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 | |
+-----------------------------+--------------------------------------------------------+------+-----+--
-------+-------+

439/3812
1.1.1.2.9.2.1.55 Performance Schema
replication_applier_configuration Table
MariaDB starting with 10.5.2
The replication_applier_configuration table, along with many other new Performance Schema tables, was
added in MariaDB 10.5.2.

The Performance Schema 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.

1.1.1.2.9.2.1.56 Performance Schema


replication_applier_status Table
MariaDB starting with 10.5.2
The replication_applier_status table, along with many other new Performance Schema tables, was added in
MariaDB 10.5.2.

The Performance Schema 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.
Shows ON when the replication channel's applier
SERVICE_STATE enum('ON','OFF') NO threads are active or idle, OFF means that the
applier threads are not active.
Seconds the replica needs to wait to reach the
REMAINING_DELAY int(10) unsigned YES
desired delay from master.
bigint(20) The number of retries that were made because the
COUNT_TRANSACTIONS_RETRIES NO
unsigned replication SQL thread failed to apply a transaction.

1.1.1.2.9.2.1.57 Performance Schema


replication_applier_status_by_coordinator
Table
MariaDB starting with 10.5.2
The replication_applier_status_by_coordinator table was added in MariaDB 10.5.2.

The Performance Schema 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.
bigint(20)
THREAD_ID YES The SQL/coordinator thread ID.
unsigned
ON (thread exists and is active or idle) or OFF (thread no
SERVICE_STATE enum('ON','OFF') NO
longer exists).

440/3812
Last error number that caused the SQL/coordinator
LAST_ERROR_NUMBER int(11) NO
thread to stop.
Last error message that caused the SQL/coordinator
LAST_ERROR_MESSAGE varchar(1024) NO
thread to stop.
Timestamp that shows when the most recent
LAST_ERROR_TIMESTAMP timestamp NO
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.

1.1.1.2.9.2.1.58 Performance Schema


replication_applier_status_by_worker Table
MariaDB starting with 10.6.0
The replication_applier_status_by_worker table was added in MariaDB 10.6.0.

The Performance Schema 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 as displayed in the performance_schema.threads table for thread with
THREAD_ID 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.
Total idle time in seconds that the worker thread has spent waiting for work from
WORKER_IDLE_TIME
SQL thread.
LAST_TRANS_RETRY_COUNT Total number of retries attempted by last transaction.

1.1.1.2.9.2.1.59 Performance Schema


replication_connection_configuration Table
MariaDB starting with 10.5.2
The replication_connection_configuration table was added in MariaDB 10.6.0.

The Performance Schema 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.
The host name of the source that the replica is
HOST char(60) NO
connected to.
PORT int(11) NO The port used to connect to the source.
The user name of the replication user account
USER char(32) NO
used to connect to the source.

441/3812
enum('NO',
USING_GTID 'CURRENT_POS', NO Whether replication is using GTIDs or not.
'SLAVE_POS')
enum('YES', 'NO', Whether SSL is allowed for the replica
SSL_ALLOWED NO
'IGNORED') connection.
Path to the file that contains one or more
SSL_CA_FILE varchar(512) NO certificates for trusted Certificate Authorities (CA)
to use for TLS.
Path to a directory that contains one or more
SSL_CA_PATH varchar(512) NO PEM files that contain X509 certificates for a
trusted Certificate Authority (CA) to use for TLS.
Path to the certificate used to authenticate the
SSL_CERTIFICATE varchar(512) NO
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.
Whether the server certificate is verified as part
SSL_VERIFY_SERVER_CERTIFICATE enum('YES','NO') NO
of the SSL connection.
Path to the PEM file containing one or more
SSL_CRL_FILE varchar(255) NO
revoked X.509 certificates.
PATH to a folder containing PEM files containing
SSL_CRL_PATH varchar(255) NO
one or more revoked X.509 certificates.
CONNECTION_RETRY_INTERVAL int(11) NO The number of seconds between connect retries.
The number of times the replica can attempt to
bigint(20)
CONNECTION_RETRY_COUNT NO reconnect to the source in the event of a lost
unsigned
connection.
double(10,3) Number of seconds after which a heartbeat will
HEARTBEAT_INTERVAL NO
unsigned 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.

1.1.1.2.9.2.1.60 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 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

1.1.1.2.9.2.1.61 Performance Schema


session_account_connect_attrs Table
Description
The session_account_connect_attrs table shows connection attributes for the current session.
442/3812
Applications can pass key/value connection attributes to the server when a connection is made. The
session_connect_attrs 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() and mysql_optionsv() 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 |
+----------------+-----------------+------------------+------------------+

1.1.1.2.9.2.1.62 Performance Schema


session_connect_attrs Table
Description
The session_connect_attrs table shows connection attributes for all sessions.
Applications can pass key/value connection attributes to the server when a connection is made. The
session_connect_attrs 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() and mysql_optionsv() 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 |
+----------------+-----------------+------------------+------------------+

443/3812
1.1.1.2.9.2.1.63 Performance Schema
session_status Table
MariaDB starting with 10.5.2
The session_status table was added in MariaDB 10.5.2.

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.

1.1.1.2.9.2.1.64 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 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 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 |
+------+------+------+
| % | % | % |
+------+------+------+

1.1.1.2.9.2.1.65 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
YES or NO for whether or not the consumer is enabled. You can modify this column to ensure that event
ENABLED
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
444/3812
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

1.1.1.2.9.2.1.66 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, file_instances, mutex_instances, rwlock_instances or
socket_instance 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.
Whether or not the instrument is timed. It can be set, but if disabled, events produced by the instrument will
TIMED
have NULL values for the corresponding TIMER_START , TIMER_END , and TIMER_WAIT values.

Example
From MariaDB 10.5.7, 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 |
445/3812
| 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 | 446/3812
| 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 |
447/3812
| 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 |
448/3812
| 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 | 449/3812
| 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 |
450/3812
| 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 |
451/3812
| 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 | 452/3812
| 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 |
453/3812
| 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 |
454/3812
| 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 | 455/3812
| 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 |
456/3812
| 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)

1.1.1.2.9.2.1.67 Performance Schema


457/3812
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 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.
Whether the object's events are instrumented or not. Can be disabled, in which case monitoring is
ENABLED
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.

1.1.1.2.9.2.1.68 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 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 |
+-----------+-------------+

1.1.1.2.9.2.1.69 Performance Schema


socket_instances Table
The socket_instances table lists active server connections, with each record being a Unix socket file or TCP/IP
458/3812
connection.
The socket_instances table contains the following columns:

Column Description
NAME from the setup_instruments table, and the name of the wait/io/socket/*
EVENT_NAME
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.
Client IP address. Blank for Unix socket file, otherwise an IPv4 or IPv6 address. Together
IP
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

1.1.1.2.9.2.1.70 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.


Number of all miscellaneous operations not counted above, including CONNECT ,
COUNT_MISC
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 the table, which will reset all counters to zero.

Example

459/3812
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
...

1.1.1.2.9.2.1.71 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.

460/3812
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.
Number of all miscellaneous operations not counted above, including CONNECT ,
COUNT_MISC
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 the table, which will reset all counters to zero.

1.1.1.2.9.2.1.72 Performance Schema


status_by_account Table
MariaDB starting with 10.5.2
The status_by_account table was added in MariaDB 10.5.2.

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 is run, will aggregate the status from terminated sessions to user and host status, then reset the
account status.
If 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.

1.1.1.2.9.2.1.73 Performance Schema


status_by_host Table
MariaDB starting with 10.5.2
The status_by_host table was added in MariaDB 10.5.2.

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.
461/3812
VARIABLE_NAME Status variable name.
VARIABLE_VALUE Aggregated status variable value

If TRUNCATE TABLE is run, will reset the aggregated host status from terminated sessions.
If 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.

1.1.1.2.9.2.1.74 Performance Schema


status_by_thread Table
MariaDB starting with 10.5.2
The session_status table was added in MariaDB 10.5.2.

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 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.

1.1.1.2.9.2.1.75 Performance Schema


status_by_user Table
MariaDB starting with 10.5.2
The status_by_account table was added in MariaDB 10.5.2.

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 is run, will reset the aggregated user status from terminated sessions.
If 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.

1.1.1.2.9.2.1.76 Performance Schema


table_handles Table
MariaDB starting with 10.5.2
The table_handles table was added in MariaDB 10.5.2.

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.
462/3812
The table is read-only, and TRUNCATE TABLE cannot be performed on the table.
The maximum number of opened table objects is determined by the 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.

1.1.1.2.9.2.1.77 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, or PRIMARY for the primary index, NULL for no index (inserts are counted in this
INDEX_NAME
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.
Number of all write operations, and the sum of the equivalent x_INSERT , x_UPDATE and
COUNT_WRITE
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.

463/3812
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 the table, which will reset all counters to zero. The table is also truncated if the
table_io_waits_summary_by_table table is truncated.
If a table's index structure is changed, index statistics recorded in this table may also be reset.

1.1.1.2.9.2.1.78 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.
Number of all write operations, and the sum of the equivalent x_INSERT , x_UPDATE and
COUNT_WRITE
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.
464/3812
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 the table, which will reset all counters to zero. Truncating this table will also truncate the
table_io_waits_summary_by_index_usage table.

1.1.1.2.9.2.1.79 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.
Number of summarized events and the sum of the x_READ and x_WRITE
COUNT_STAR
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.
Number of all read operations, and the sum of the equivalent
COUNT_READ 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.
Number of all write operations, and the sum of the equivalent
COUNT_WRITE 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.

465/3812
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.
466/3812
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 the table, which will reset all counters to zero.

1.1.1.2.9.2.1.80 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 associated with the server's thread instrumentation code, for example
NAME thread/sql/main for the server's main() function, and thread/sql/one_connection for a
user connection.
FOREGROUND or BACKGROUND , depending on the thread type. User connection threads are
TYPE
FOREGROUND , internal server threads are BACKGROUND .

The PROCESSLIST.ID value for threads displayed in the INFORMATION_SCHEMA.PROCESSLIST


PROCESSLIST_ID 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.
Type of command executed by the thread. These correspond to the the COM_xxx
PROCESSLIST_COMMAND client/server protocol commands, and the Com_xxx status variables. See Thread Command
Values.
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.

Statement being executed by the thread, or NULL if a statement is not being executed. If a
PROCESSLIST_INFO statement results in calling other statements, such as for a stored procedure, the innermost
statement from the stored procedure is shown here.
THREAD_ID of the parent thread, if any. Subthreads can for example be spawned as a result
PARENT_THREAD_ID
of INSERT DELAYED statements.
ROLE Unused.
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 table.
INSTRUMENTED 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 table must also be YES .

467/3812
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 table.
Subthreads are again matched, while for background threads, this will be set to YES by
HISTORY
default. To monitor events that the thread executes, INSTRUMENTED must be YES and the
thread_instrumentation consumer in the setup_consumers table must also be YES . Added in
MariaDB 10.5.
The protocol used to establish the connection. One of TCP/IP , SSL/TLS , Socket , Named
CONNECTION_TYPE
Pipe , Shared Memory , or NULL for background threads. Added in MariaDB 10.5.

The thread or task identifier as defined by the underlying operating system, if there is one.
THREAD_OS_ID
Added in MariaDB 10.5

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

1.1.1.2.9.2.1.81 Performance Schema


user_variables_by_thread Table
MariaDB starting with 10.5.2
The user_variables_by_thread table was added in MariaDB 10.5.2.

The user_variables_by_thread table contains information about user-defined variables and the threads that defined
them.
TRUNCATE TABLE 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
468/3812
SET @var = 0;

SELECT * FROM user_variables_by_thread;


+-----------+---------------+----------------+
| THREAD_ID | VARIABLE_NAME | VARIABLE_VALUE |
+-----------+---------------+----------------+
| 11 | var | 0 |
+-----------+---------------+----------------+

See Also
User-defined variables
Information Schema USER_VARIABLES Table

1.1.1.2.9.2.1.82 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 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 |
+------------------+---------------------+-------------------+

1.1.1.2.9.2.2 Performance Schema Overview


Contents
1. Introduction
2. Activating the Performance Schema
3. Enabling the Performance Schema
4. Listing Performance Schema Variables
5. Column Comments
6. See Also

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.

469/3812
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 for a full list and links to detailed descriptions of each table. From MariaDB
10.5, there are 80 Performance Schema tables, while until MariaDB 10.4, 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 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, all memory used by the Performance Schema is allocated at startup. From MariaDB 10.5, 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

470/3812
Listing Performance Schema Variables
SHOW VARIABLES LIKE "perf%";
+--------------------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------------------+-------+
| performance_schema | ON |
...
| performance_schema_users_size | 100 |
+--------------------------------------------------------+-------+

See Performance Schema System Variables 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.

Column Comments
MariaDB starting with 10.7.1
From MariaDB 10.7.1, 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
SHOW ENGINE STATUS
SHOW PROFILE
ANALYZE STATEMENT
Performance schema in MySQL 5.6 . All things here should also work for MariaDB.

1.1.1.2.9.2.3 Performance Schema Status


Variables

471/3812
Contents
1. Performance_schema_accounts_lost
2. Performance_schema_cond_classes_lost
3. Performance_schema_cond_instances_lost
4. Performance_schema_digest_lost
5. Performance_schema_file_classes_lost
6. Performance_schema_file_handles_lost
7. Performance_schema_file_instances_lost
8. Performance_schema_hosts_lost
9. Performance_schema_index_stat_lost
10. Performance_schema_locker_lost
11. Performance_schema_memory_classes_lost
12. Performance_schema_metadata_lock_lost
13. Performance_schema_mutex_classes_lost
14. Performance_schema_mutex_instances_lost
15. Performance_schema_nested_statement_lost
16. Performance_schema_prepared_statements_lost
17. Performance_schema_program_lost
18. Performance_schema_rwlock_classes_lost
19. Performance_schema_rwlock_instances_lost
20. Performance_schema_session_connect_attrs_lost
21. Performance_schema_socket_classes_lost
22. Performance_schema_socket_instances_lost
23. Performance_schema_stage_classes_lost
24. Performance_schema_statement_classes_lost
25. Performance_schema_table_handles_lost
26. Performance_schema_table_instances_lost
27. Performance_schema_table_lock_stat_lost
28. Performance_schema_thread_classes_lost
29. Performance_schema_thread_instances_lost
30. Performance_schema_users_lost

This page documents status variables related to the Performance Schema. See Server Status Variables for a complete
list of status variables that can be viewed with SHOW STATUS.
See also the Full list of MariaDB options, system and status variables.

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.
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.
Scope: Global, Session
Data Type: numeric

Performance_schema_digest_lost
Description: The global value can be flushed by FLUSH STATUS.
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
472/3812
STATUS.
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.
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.
Scope: Global, Session
Data Type: numeric

Performance_schema_index_stat_lost
Description:
Scope: Global, Session
Data Type: numeric
Introduced: MariaDB 10.5.2

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.
Scope: Global, Session
Data Type: numeric

Performance_schema_memory_classes_lost
Description:
Scope: Global, Session
Data Type: numeric
Introduced: MariaDB 10.5.2

Performance_schema_metadata_lock_lost
Description:
Scope: Global, Session
Data Type: numeric
Introduced: MariaDB 10.5.2

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.
Scope: Global, Session
Data Type: numeric

Performance_schema_nested_statement_lost

473/3812
Description:
Scope: Global, Session
Data Type: numeric
Introduced: MariaDB 10.5.2

Performance_schema_prepared_statements_lost
Description:
Scope: Global, Session
Data Type: numeric
Introduced: MariaDB 10.5.2

Performance_schema_program_lost
Description:
Scope: Global, Session
Data Type: numeric
Introduced: MariaDB 10.5.2

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.
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.
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.
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.
Scope: Global, Session
Data Type: numeric

Performance_schema_statement_classes_lost

474/3812
Description: Number of statement instruments that could not be loaded. The global value can be flushed by
FLUSH STATUS.
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.
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.
Scope: Global, Session
Data Type: numeric

Performance_schema_table_lock_stat_lost
Description:
Scope: Global, Session
Data Type: numeric
Introduced: MariaDB 10.5.2

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.
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.
Scope: Global, Session
Data Type: numeric

1.1.1.2.9.2.4 Performance Schema System


Variables

475/3812
Contents
1. performance_schema
2. performance_schema_accounts_size
3. performance_schema_digests_size
4. performance_schema_events_stages_history_long_size
5. performance_schema_events_stages_history_size
6. performance_schema_events_statements_history_long_size
7. performance_schema_events_statements_history_size
8. performance_schema_events_transactions_history_long_size
9. performance_schema_events_transactions_history_size
10. performance_schema_events_waits_history_long_size
11. performance_schema_events_waits_history_size
12. performance_schema_hosts_size
13. performance_schema_max_cond_classes
14. performance_schema_max_cond_instances
15. performance_schema_max_digest_length
16. performance_schema_max_file_classes
17. performance_schema_max_file_handles
18. performance_schema_max_file_instances
19. performance_schema_max_index_stat
20. performance_schema_max_memory_classes
21. performance_schema_max_metadata_locks
22. performance_schema_max_mutex_classes
23. performance_schema_max_mutex_instances
24. performance_schema_max_prepared_statement_instances
25. performance_schema_max_program_instances
26. performance_schema_max_rwlock_classes
27. performance_schema_max_rwlock_instances
28. performance_schema_max_socket_classes
29. performance_schema_max_socket_instances
30. performance_schema_max_sql_text_length
31. performance_schema_max_stage_classes
32. performance_schema_max_statement_classes
33. performance_schema_max_statement_stack
34. performance_schema_max_table_handles
35. performance_schema_max_table_instances
36. performance_schema_max_table_lock_stat
37. performance_schema_max_thread_classes
38. performance_schema_max_thread_instances
39. performance_schema_session_connect_attrs_size
40. performance_schema_setup_actors_size
41. performance_schema_setup_objects_size
42. performance_schema_users_size

The following variables are used with MariaDB's Performance Schema. See Performance Schema Options for
Performance Schema options that are not system variables. See Server System Variables for a complete list of system
variables and instructions on setting them.
See also the Full list of MariaDB options, system and status variables.

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 table. If set to 0, the Performance
Schema 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 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 200

476/3812
performance_schema_events_stages_history_long_size
Description: Number of rows in the events_stages_history_long 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 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 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 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 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

performance_schema_events_transactions_history_size
Description:Number of rows per thread in events_transactions_history. 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
477/3812
performance_schema_events_waits_history_long_size
Description: Number of rows contained in the events_waits_history_long 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 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 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), 80 (<= MariaDB 10.5.0)
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

478/3812
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), 50 (<= MariaDB 10.5.1)
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.
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

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

performance_schema_max_metadata_locks
Description: Maximum number of Performance Schema metadata locks. 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
479/3812
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), 200 (<= MariaDB 10.5.1)
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

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

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), 40 (<= MariaDB 10.5.1)
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

480/3812
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

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), 150 (<= MariaDB 10.3.2)
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

481/3812
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.
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

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 and
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
482/3812
performance_schema_setup_actors_size
Description: The maximum number of rows to store in the performance schema setup_actors table. -1 (from
MariaDB 10.5.2) denotes automated sizing.
Commandline: --performance-schema-setup-actors-size=#
Scope: Global
Dynamic: No
Data Type: numeric
Default Value: -1 (>= MariaDB 10.5.2), 100 (<= MariaDB 10.5.1)
Range: -1 to 1024 (>= MariaDB 10.5.2), 0 to 1024 (<= MariaDB 10.5.1)

performance_schema_setup_objects_size
Description: The maximum number of rows that can be stored in the performance schema setup_objects table.
-1 (from MariaDB 10.5.2) denotes automated sizing.
Commandline: --performance-schema-setup-objects-size=#
Scope: Global
Dynamic: No
Data Type: numeric
Default Value: -1 (>= MariaDB 10.5.2), 100 (<= MariaDB 10.5.1)
Range: -1 to 1048576 (>= MariaDB 10.5.2), 0 to 1048576 (<= MariaDB 10.5.1)

performance_schema_users_size
Description: Number of rows in the performance_schema.users table. If set to 0, the Performance Schema 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

1.1.1.2.9.2.5 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
events_statements_history
events_statements_history_long
483/3812
events_statements_summary_by_digest (a summary table by schema and digest)

1.1.1.2.9.2.6 PERFORMANCE_SCHEMA
Storage Engine
If you run SHOW ENGINES, 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 feature.
The 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 for more details.

1.1.1.2.9.3 The mysql Database Tables


MariaDB comes pre-installed with a system database called mysql containing many important tables storing, in
particular, grant and privilege information. Until MariaDB 10.4, system tables used the MyISAM storage engine. From
MariaDB 10.4, they use Aria.
mysql.column_stats Table
Column stats for engine-independent statistics.

mysql.columns_priv Table
Column-level privileges

mysql.db Table
Database-level access and privileges.

mysql.event Table
Information about MariaDB events.

mysql.func Table
User-defined function information

mysql.general_log Table
Contents of the general query log if written to table

mysql.global_priv Table
1 Global privileges.

mysql.gtid_slave_pos Table
2 For replicas to keep track of the GTID.

mysql.help_category Table
Help categories

mysql.help_keyword Table
Help keywords

mysql.help_relation Table
HELP command relations

mysql.help_topic Table
Help topics

mysql.index_stats Table
Index stats for engine-independent statistics.
484/3812
mysql.innodb_index_stats
1 Data related to particular persistent index statistics, multiple rows for each index.

mysql.innodb_table_stats
Data related to persistent indexes, one row per table.

mysql.password_reuse_check_history Table
Contains old passwords for purposes of preventing password reuse.

mysql.plugin Table
Plugins loaded with INSTALL SONAME, INSTALL PLUGIN or the mysql_plugin utility

mysql.proc Table
Information about stored routines.

mysql.procs_priv Table
Stored procedure and stored function privileges

mysql.proxies_priv Table
Proxy privileges.

mysql.roles_mapping Table
MariaDB roles information.

mysql.servers Table
MariaDB servers

mysql.slow_log Table
Contents of the slow query log if written to table.

mysql.tables_priv Table
1 Table-level privileges

mysql.table_stats Table
Table stats for engine-independent statistics.

mysql.time_zone Table
Time zone table in the mysql database.

mysql.time_zone_leap_second Table
Time zone leap second.

mysql.time_zone_name Table
Time zone name.

mysql.time_zone_transition Table
Time zone transition table.

mysql.time_zone_transition_type Table
Time zone transition type table.

mysql.transaction_registry Table
6 Used for transaction-precise versioning.

mysql.user Table
User access and global privileges.

Obsolete mysql Database Tables


Tables no longer present in the mysql system database.

Spider mysql Database Tables


System tables related to the Spider storage engine.

There are 2 related questions .

1.1.1.2.9.3.1 mysql.column_stats Table


485/3812
The mysql.column_stats table is one of three tables storing data used for Engine-independent table statistics. The
others are mysql.table_stats and mysql.index_stats.

Note that statistics for blob and text columns are not collected. If explicitly specified, a warning is returned.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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).
Fraction of NULL values (0- no NULL s, 0.5 -
nulls_ratio decimal(12,4) YES NULL half values are NULL s, 1 - all values are
NULL s).

Average length of column value, in bytes.


Counted as if one ran SELECT
avg_length decimal(12,4) YES NULL AVG(LENGTH(col)) . This doesn't count
NULL bytes, assumes endspace removal for
CHAR(n) , etc.

Average number of records with the same


avg_frequency decimal(12,4) YES NULL
value
Histogram size in bytes, from 0-255, or, from
hist_size tinyint(3) unsigned YES NULL MariaDB 10.7, number of buckets if the
histogram type is JSON_HB .
enum('SINGLE_PREC_HB',
'DOUBLE_PREC_HB') (>=
MariaDB 10.7) Histogram type. See the histogram_type
hist_type YES NULL
enum('SINGLE_PREC_HB', system variable.
'DOUBLE_PREC_HB','JSON_HB')
(<= MariaDB 10.6)
blob (>= MariaDB 10.7)
histogram varbinary(255) (<=MariaDB YES NULL
10.6)

It is possible to manually update the table. See Manual updates to statistics tables for details.

1.1.1.2.9.3.2 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 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 for a more complete view of the MariaDB privilege
system.
The INFORMATION_SCHEMA.COLUMN_PRIVILEGES table derives its contents from mysql.columns_priv .

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


486/3812
In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

The mysql.columns_priv table contains the following fields:

Field Type Null Key Default Description


Host (together with User , Db ,
Host char(60) NO PRI Table_name and Column_name makes
up the unique identifier for this record.
Database name (together with User ,
Host , Table_name and Column_name
Db char(64) NO PRI
makes up the unique identifier for this
record.
User (together with Host , Db ,
User char(80) NO PRI Table_name and Column_name makes
up the unique identifier for this record.
Table name (together with User , Db ,
Table_name char(64) NO PRI Host and Column_name makes up the
unique identifier for this record.
Column name (together with User , Db
Column_name char(64) NO PRI , Table_name and Host makes up the
unique identifier for this record.
Timestamp timestamp NO CURRENT_TIMESTAMP

set('Select',
The privilege type. See Column
Column_priv 'Insert', 'Update', NO
Privileges for details.
'References')

The Acl_column_grants status variable, added in MariaDB 10.1.4 , indicates how many rows the mysql.columns_priv
table contains.

1.1.1.2.9.3.3 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 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 for a more complete view of the MariaDB privilege
system.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

The mysql.db table contains the following fields:

Field Type Null Key Default Description Introduced


Host (together with User and Db
makes up the unique identifier for this
record. Until MariaDB 5.5, if the host
field was blank, the corresponding
Host char(60) NO PRI
record in the mysql.host table
would be examined. From MariaDB
10.0, a blank host field is the same
as the % wildcard.
Database (together with User and
Db char(64) NO PRI Host makes up the unique identifier
for this record.
User (together with Host and Db
User char(80) NO PRI makes up the unique identifier for this
record.
Select_priv enum('N','Y') NO N Can perform SELECT statements.
487/3812
Insert_priv enum('N','Y') NO N Can perform INSERT statements.
Update_priv enum('N','Y') NO N Can perform UPDATE statements.
Delete_priv enum('N','Y') NO N Can perform DELETE statements.
Create_priv enum('N','Y') NO N Can CREATE TABLE's.
Can DROP DATABASE's or DROP
Drop_priv enum('N','Y') NO N
TABLE's.
User can grant privileges they
Grant_priv enum('N','Y') NO N
possess.
References_priv enum('N','Y') NO N Unused
Can create an index on a table using
the CREATE INDEX statement.
Without the INDEX privilege, user
can still create indexes when creating
a table using the CREATE TABLE
Index_priv enum('N','Y') NO N
statement if the user has have the
CREATE privilege, and user can
create indexes using the ALTER
TABLE statement if they have the
ALTER privilege.

Can perform ALTER TABLE


Alter_priv enum('N','Y') NO N
statements.
Can create temporary tables with the
Create_tmp_table_priv enum('N','Y') NO N CREATE TEMPORARY TABLE
statement.
Acquire explicit locks using the LOCK
TABLES statement; user also needs
Lock_tables_priv enum('N','Y') NO N
to have the SELECT privilege on a
table in order to lock it.
Can create a view using the
Create_view_priv enum('N','Y') NO N
CREATE_VIEW statement.
Can show the CREATE VIEW
Show_view_priv enum('N','Y') NO N statement to create a view using the
SHOW CREATE VIEW statement.
Can create stored programs using
Create_routine_priv enum('N','Y') NO N the CREATE PROCEDURE and
CREATE FUNCTION statements.
Can change the characteristics of a
Alter_routine_priv enum('N','Y') NO N stored function using the ALTER
FUNCTION statement.
Can execute stored procedure or
Execute_priv enum('N','Y') NO N
functions.
Event_priv enum('N','Y') NO N Create, drop and alter events.
Can execute triggers associated with
tables the user updates, execute the
Trigger_priv enum('N','Y') NO N CREATE TRIGGER and DROP
TRIGGER statements.

Can delete rows created through MariaDB


Delete_history_priv enum('N','Y') NO N
system versioning. 10.3.5

The Acl_database_grants status variable, added in MariaDB 10.1.4 , indicates how many rows the mysql.db table
contains.

1.1.1.2.9.3.4 mysql.event Table


The mysql.event table contains information about MariaDB events. Similar information can be obtained by viewing the
INFORMATION_SCHEMA.EVENTS table, or with the SHOW EVENTS and SHOW CREATE EVENT statements.
The table is upgraded live, and there is no need to restart the server if the table has changed.

488/3812
MariaDB starting with 10.4
In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

enum('YEAR', 'QUARTER', 'MONTH',


'DAY', 'HOUR', 'MINUTE', 'WEEK',
'SECOND', 'MICROSECOND',
'YEAR_MONTH', 'DAY_HOUR',
'DAY_MINUTE', 'DAY_SECOND',
interval_field YES NULL
'HOUR_MINUTE', 'HOUR_SECOND',
'MINUTE_SECOND', 'DAY_MICROSECOND',
'HOUR_MICROSECOND',
'MINUTE_MICROSECOND',
'SECOND_MICROSECOND')

created timestamp NO CURRENT_TIMESTAMP

0000-00-00
modified timestamp NO
00:00:00
last_executed datetime YES NULL

starts datetime YES NULL

ends datetime YES NULL

Current
status of the
event, one
enum('ENABLED', 'DISABLED', of enabled,
status NO ENABLED
'SLAVESIDE_DISABLED') disabled, or
disabled on
the
slaveside.
on_completion enum('DROP','PRESERVE') NO DROP

489/3812
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',
The
'NO_FIELD_OPTIONS', 'MYSQL323',
SQL_MODE
'MYSQL40', 'ANSI',
at the time
sql_mode 'NO_AUTO_VALUE_ON_ZERO', NO
the event
'NO_BACKSLASH_ESCAPES',
was
'STRICT_TRANS_TABLES',
created.
'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')

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

1.1.1.2.9.3.5 mysql.func Table


The mysql.func table stores information about user-defined functions (UDFs) created with the CREATE FUNCTION
UDF statement.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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, either function or aggregate . Aggregate
type enum('function','aggregate') NO NULL functions are summary functions such as SUM() and
AVG().

Example

490/3812
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 |
+------------------------------+-----+--------------+-----------+

1.1.1.2.9.3.6 mysql.general_log Table


The mysql.general_log table stores the contents of the General Query Log if general logging is active and the output
is being written to table (see Writing logs into tables).
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
...

1.1.1.2.9.3.7 mysql.global_priv Table


MariaDB starting with 10.4.1
The mysql.global_priv table was introduced in MariaDB 10.4.1 to replace the mysql.user 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 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

491/3812
From MariaDB 10.5.2, 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 ).

Examples
select * from mysql.global_priv;
+-----------+-------------+----------------------------------------------------------------------------
-----------------------------------------------------------+
| Host | User | Priv
|
+-----------+-------------+----------------------------------------------------------------------------
-----------------------------------------------------------+
| localhost | root | {"access":
18446744073709551615,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E
74754DA6682D04747"} |
| 127.% | msandbox |
{"access":1073740799,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E
74754DA6682D04747"} |
| localhost | msandbox |
{"access":1073740799,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E
74754DA6682D04747"} |
| localhost | msandbox_rw |
{"access":487487,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E7475
4DA6682D04747"} |
| 127.% | msandbox_rw |
{"access":487487,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E7475
4DA6682D04747"} |
| 127.% | msandbox_ro |
{"access":262145,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E7475
4DA6682D04747"} |
| localhost | msandbox_ro |
{"access":262145,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E7475
4DA6682D04747"} |
| 127.% | rsandbox |
{"access":524288,"plugin":"mysql_native_password","authentication_string":"*B07EB15A2E7BD9620DAE47B194D
5B9DBA14377AD"} |
+-----------+-------------+----------------------------------------------------------------------------
-----------------------------------------------------------+

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:

492/3812
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
}

1.1.1.2.9.3.8 mysql.gtid_slave_pos Table


The mysql.gtid_slave_pos table is used in replication by replica servers to keep track of their current position (the
global transaction ID of the last transaction applied). Using the table allows the replica to maintain a consistent value for
the gtid_slave_pos system variable across server restarts. See Global Transaction ID.
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, multiple versions of this table are supported, each using a different storage engine. This
is selected with the gtid_pos_auto_engines option, 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, 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, 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


int(10)
domain_id NO PRI NULL Domain id (see Global Transaction ID domain ID.
unsigned

This field enables multiple parallel transactions within same


bigint(20) domain_id to update this table without contention. At any instant,
sub_id NO PRI NULL the replication state corresponds to records with largest sub_id for
unsigned
each domain_id .

int(10)
server_id NO NULL Server id.
unsigned

bigint(20) Sequence number, an integer that is monotonically increasing for


seq_no NO NULL
unsigned each new event group logged into the binlog.

From MariaDB 10.3.1, some status variables are available to monitor the use of the different gtid_slave_pos table
versions:
Transactions_gtid_foreign_engine
493/3812
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
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
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.

1.1.1.2.9.3.9 mysql.help_category Table


mysql.help_category is one of the four tables used by the HELP command. It is populated when the server is installed
by the fill_help_table.sql script. The other help tables are help_relation, help_topic and help_keyword.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage 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

494/3812
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 | |
+------------------+-----------------------------------------------+--------------------+-----+

1.1.1.2.9.3.10 mysql.help_keyword Table


mysql.help_keyword is one of the four tables used by the HELP command. It is populated when the server is installed
by the fill_help_table.sql script. The other help tables are help_relation, help_category and help_topic.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage 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

495/3812
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 |
...

1.1.1.2.9.3.11 mysql.help_relation Table


mysql.help_relation is one of the four tables used by the HELP command. It is populated when the server is installed
by the fill_help_table.sql script. The other help tables are help_topic, help_category and help_keyword.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage 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 |
+---------------+-----------------+

1.1.1.2.9.3.12 mysql.help_topic Table


mysql.help_topic is one of the four tables used by the HELP command. It is populated when the server is installed by
the fill_help_table.sql script. The other help tables are help_relation, help_category and help_keyword.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

496/3812
MariaDB until 10.3
In MariaDB 10.3 and before, this table uses the MyISAM storage 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/

1.1.1.2.9.3.13 mysql.index_stats Table


497/3812
The mysql.index_stats table is one of three tables storing data used for Engine-independent table statistics. The
others are mysql.column_stats and mysql.table_stats.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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
int(11) Index prefix length. 1 for the first keypart, 2 for the first two,
prefix_arity NO PRI NULL
unsigned and so on. InnoDB's extended keys are supported.
Average number of records one will find for given values of
avg_frequency decimal(12,4) YES NULL (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 for details.

1.1.1.2.9.3.14 mysql.innodb_index_stats
Contents
1. Example
2. See Also

The mysql.innodb_index_stats table stores data related to particular InnoDB Persistent Statistics, and contains
multiple rows for each index.
This table, along with the related mysql.innodb_table_stats 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 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.
bigint(20)
stat_value NO NULL Estimated statistic value.
unsigned

bigint(20) Number of pages sampled for the


sample_size YES NULL
unsigned estimated statistic value.
stat_description varchar(1024) NO NULL Statistic description.

Example

498/3812
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
mysql.innodb_table_stats
ANALYZE TABLE

1.1.1.2.9.3.15 mysql.innodb_table_stats
Contents
1. Example
2. See Also

The mysql.innodb_table_stats table stores data related to InnoDB Persistent Statistics, and contains one row per
table.
This table, along with the related mysql.innodb_index_stats 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 statements on the table will be by
499/3812
default..
It contains the following fields:

Field Type Null Key Default Description


database_name varchar(64) NO PRI NULL Database name.
Table, partition or
table_name varchar(64) NO PRI NULL
subpartition name.
Time that this row was last
last_update timestamp NO current_timestamp()
updated.
bigint(20)
n_rows NO NULL Number of rows in the table.
unsigned

bigint(20) Size, in pages, of the primary


clustered_index_size NO NULL
unsigned index.
bigint(20) Size, in pages, of non-
sum_of_other_index_sizes NO NULL
unsigned 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
mysql.innodb_index_stats
ANALYZE TABLE

1.1.1.2.9.3.16
mysql.password_reuse_check_history Table
MariaDB starting with 10.7.0
The mysql.password_reuse_check_history Table is installed as part of the password_reuse_check plugin, available
from MariaDB 10.7.0.

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()

1.1.1.2.9.3.17 mysql.plugin Table


The mysql.plugin 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:
500/3812
The INSTALL SONAME statement.
The INSTALL PLUGIN statement.
The mysql_plugin utility.
This table does not contain information about:
Built-in plugins.
Plugins loaded with the --plugin-load-add option.
Plugins loaded with the --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.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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 |
+---------------------------+------------------------+

1.1.1.2.9.3.18 mysql.proc Table


The mysql.proc table contains information about stored procedures and stored functions. It contains similar
information to that stored in the INFORMATION SCHEMA.ROUTINES table.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

The mysql.proc table contains the following fields:


Field Type Null Key Default Description
Database
db char(64) NO PRI
name.
name char(64) NO PRI Routine name.
Whether stored
procedure,
stored function
or, from
type enum('FUNCTION','PROCEDURE','PACKAGE', 'PACKAGE BODY') NO PRI NULL
MariaDB
10.3.5, a
package or
package body.
501/3812
specific_name char(64) NO
language enum('SQL') NO SQL Always SQL .
enum('CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA',
sql_data_access NO CONTAINS_SQL
'MODIFIES_SQL_DATA')

Whether the
routine is
deterministic
(can produce
is_deterministic enum('YES','NO') NO NO
only one result
for a given list
of parameters)
or not.
INVOKER or
DEFINER .
Indicates which
security_type enum('INVOKER','DEFINER') NO DEFINER
user's
privileges apply
to this routine.
List of
param_list blob NO NULL
parameters.
What the
returns longblob NO NULL
routine returns.
Definition of the
body longblob NO NULL
routine.
If the
security_type
is DEFINER ,
definer char(141) NO this value
indicates which
user defined
this routine.
Date and time
created timestamp NO CURRENT_TIMESTAMP the routine was
created.
Date and time
0000-00-00
modified timestamp NO the routine was
00:00:00
modified.
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',
The
'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS',
SQL_MODE at
'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI',
sql_mode NO the time the
'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES',
routine was
'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE',
created.
'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')

Comment
comment text NO NULL associated with
the routine.
The character
set used by the
character_set_client char(32) YES NULL client that
created the
routine.
The collation
(and character
set) used by
collation_connection char(32) YES NULL
the connection
that created the
routine.
The default
collation (and
character set)
for the
db_collation char(32) YES NULL
database, at
the time the
routine was
created.
Definition of the
body_utf8 longblob YES NULL
routine in utf8.
From MariaDB
aggregate enum('NONE', 'GROUP') NO NONE
10.3.3
Field Type Null Key Default Description

502/3812
See Also
Stored Procedure Internals
MySQL to MariaDB migration: handling privilege table differences when using mysqldump

1.1.1.2.9.3.19 mysql.procs_priv Table


The mysql.procs_priv table contains information about stored procedure and stored function privileges. See CREATE
PROCEDURE and CREATE FUNCTION on creating these.
The INFORMATION_SCHEMA.ROUTINES table derives its contents from mysql.procs_priv .

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

The mysql.procs_priv table contains the following fields:

Field Type Null Key Default Description


Host (together with Db , User ,
Routine_name and
Host char(60) NO PRI Routine_type makes up the
unique identifier for this
record).
Database (together with Host ,
User , Routine_name and
Db char(64) NO PRI Routine_type makes up the
unique identifier for this
record).
User (together with Host , Db ,
Routine_name and
User char(80) NO PRI Routine_type makes up the
unique identifier for this
record).
Routine_name (together with
Host , Db User and
Routine_name char(64) NO PRI Routine_type makes up the
unique identifier for this
record).
Whether the routine is a stored
enum('FUNCTION','PROCEDURE', procedure, stored function, or,
Routine_type NO PRI NULL
'PACKAGE', 'PACKAGE BODY') from MariaDB 10.3.5, a
package or package body.

Grantor char(141) NO MUL


The routine privilege. See
set('Execute','Alter Function Privileges and
Proc_priv NO
Routine','Grant') Procedure Privileges for
details.
Timestamp timestamp NO CURRENT_TIMESTAMP

The Acl_function_grants status variable, added in MariaDB 10.1.4 , indicates how many rows the
mysql.columns_priv table contains with the FUNCTION routine type.
The Acl_procedure_grants status variable, added in MariaDB 10.1.4 , indicates how many rows the
mysql.columns_priv table contains with the PROCEDURE routine type.

1.1.1.2.9.3.20 mysql.roles_mapping Table


The mysql.roles_mapping table contains information about mariaDB roles.

MariaDB starting with 10.4


503/3812
In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

The mysql.roles_mapping table contains the following fields:

Field Type Null Key Default Description


Host (together with User and Role makes up the unique
Host char(60) NO PRI
identifier for this record.
User (together with Host and Role makes up the unique
User char(80) NO PRI
identifier for this record.
Role (together with Host and User makes up the unique
Role char(80) NO PRI
identifier for this record.
Whether the role can be granted (see the CREATE ROLE
Admin_option enum('N','Y') NO N
WITH ADMIN clause).

The Acl_role_grants status variable, added in MariaDB 10.1.4 , indicates how many rows the mysql.roles_mapping
table contains.

1.1.1.2.9.3.21 mysql.servers Table


The mysql.servers table contains information about servers as used by the Spider, FEDERATED or FederatedX ,
Connect storage engines (see CREATE SERVER).

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

1.1.1.2.9.3.22 mysql.slow_log Table


The mysql.slow_log table stores the contents of the Slow Query Log if slow logging is active and the output is being
written to table (see Writing logs into tables).
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.
504/3812
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.
insert_id int(11) NO NULL Insert id.
int(10)
server_id NO NULL The server's id.
unsigned

sql_text mediumtext NO NULL Full query.


bigint(21)
thread_id NO NULL Thread id.
unsigned

Number of rows affected by an UPDATE or


rows_affected int(11) NO NULL
DELETE (from MariaDB 10.1.2 )

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
...

1.1.1.2.9.3.23 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 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 for a more complete view of the MariaDB privilege
system.
The INFORMATION_SCHEMA.TABLE_PRIVILEGES table derives its contents from mysql.tables_priv .

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

The mysql.tables_priv table contains the following fields:

Field Type Null Key Default Description


Host (together with
User , Db and
Table_name makes
Host char(60) NO PRI
up the unique
identifier for this
record.

505/3812
Database
(together with
User , Host and
Db char(64) NO PRI Table_name makes
up the unique
identifier for this
record.
User (together with
Host , Db and
Table_name makes
User char(80) NO PRI
up the unique
identifier for this
record.
Table name
(together with
User , Db and
Table_name char(64) NO PRI Table makes up
the unique
identifier for this
record.
Grantor char(141) NO MUL
Timestamp timestamp NO CURRENT_TIMESTAMP

set('Select', 'Insert', 'Update',


The table privilege
'Delete', 'Create', 'Drop', 'Grant',
type. See Table
Table_priv 'References', 'Index', 'Alter', 'Create NO
Privileges for
View', 'Show view', 'Trigger', 'Delete
details.
versioning rows')

The column
set('Select', 'Insert', 'Update', privilege type. See
Column_priv NO
'References') Column Privileges
for details.

The Acl_table_grants status variable, added in MariaDB 10.1.4 , indicates how many rows the mysql.tables_priv
table contains.

1.1.1.2.9.3.24 mysql.table_stats Table


The mysql.table_stats table is one of three tables storing data used for Engine-independent table statistics. The
others are mysql.column_stats and mysql.index_stats.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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 for details.

1.1.1.2.9.3.25 mysql.time_zone Table


The mysql.time_zone table is one of the mysql system tables that can contain time zone 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 mysql_tzinfo_to_sql utility. See Time Zones for details.

MariaDB starting with 10.4


506/3812
In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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
mysql.time_zone_name table
mysql.time_zone_transition table
mysql.time_zone_transition_type table

1.1.1.2.9.3.26 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 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 mysql_tzinfo_to_sql utility. See Time Zones for details.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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
mysql.time_zone_name table
mysql.time_zone_transition table
mysql.time_zone_transition_type table
507/3812
1.1.1.2.9.3.27 mysql.time_zone_name Table
The mysql.time_zone_name table is one of the mysql system tables that can contain time zone 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 mysql_tzinfo_to_sql utility. See Time Zones for details.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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
mysql.time_zone_leap_second table
mysql.time_zone_transition table
mysql.time_zone_transition_type table

1.1.1.2.9.3.28 mysql.time_zone_transition
Table
The mysql.time_zone_transition table is one of the mysql system tables that can contain time zone 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 mysql_tzinfo_to_sql utility. See Time Zones for details.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

508/3812
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
mysql.time_zone_leap_second table
mysql.time_zone_name table
mysql.time_zone_transition_type table

1.1.1.2.9.3.29 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
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 mysql_tzinfo_to_sql utility. See Time Zones for
details.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

509/3812
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
mysql.time_zone_leap_second table
mysql.time_zone_name table
mysql.time_zone_transition table

1.1.1.2.9.3.30 mysql.transaction_registry Table


MariaDB starting with 10.3.4
The mysql.transaction_registry table was introduced in MariaDB 10.3.4 as part of system-versioned tables.

The mysql.transaction_registry table 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
Timestamp when the
transaction began
0000-00-00
begin_timestamp timestamp(6) NO Multiple (BEGIN statement),
00:00:00.000000
however see MDEV-
16024 .
Timestamp when the
0000-00-00
commit timestamp(6) NO Multiple transaction was
00:00:00.000000
committed.
enum('READ-UNCOMMITTED','READ-
Transaction isolation
isolation_level COMMITTED','REPEATABLE- NO NULL
level.
READ','SERIALIZABLE')

1.1.1.2.9.3.31 mysql.user Table


MariaDB starting with 10.4
In MariaDB 10.4 and later, the mysql.global_priv table has replaced the mysql.user table, and mysql.user should
be considered obsolete. It is now a view 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, 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 ).

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 and
CREATE USER 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 for a more complete
view of the MariaDB privilege system.

510/3812
MariaDB until 10.3
In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

The mysql.user table contains the following fields:

Field Type Null Key Default Description Introduced


Host (together with User makes
Host char(60) NO PRI up the unique identifier for this
account.
User (together with Host makes
User char(80) NO PRI up the unique identifier for this
account.
longtext (>=
MariaDB
10.4.1), Hashed password, generated by
Password NO
char(41) (<= the PASSWORD() function.
MariaDB
10.4.0)
Select_priv enum('N','Y') NO N Can perform SELECT statements.
Insert_priv enum('N','Y') NO N Can perform INSERT statements.
Update_priv enum('N','Y') NO N Can perform UPDATE statements.
Delete_priv enum('N','Y') NO N Can perform DELETE statements.
Can CREATE DATABASE's or
Create_priv enum('N','Y') NO N
CREATE TABLE's.
Can DROP DATABASE's or
Drop_priv enum('N','Y') NO N
DROP TABLE's.
Can execute FLUSH statements
Reload_priv enum('N','Y') NO N or equivalent mysqladmin
commands.
Can shut down the server with
Shutdown_priv enum('N','Y') NO N SHUTDOWN or mysqladmin
shutdown.
Can show information about active
processes, via SHOW
Process_priv enum('N','Y') NO N
PROCESSLIST or mysqladmin
processlist.
Read and write files on the server,
using statements like LOAD DATA
INFILE or functions like
File_priv enum('N','Y') NO N LOAD_FILE(). Also needed to
create CONNECT outward tables.
MariaDB server must have
permission to access those files.
User can grant privileges they
Grant_priv enum('N','Y') NO N
possess.
References_priv enum('N','Y') NO N Unused
Can create an index on a table
using the CREATE INDEX
statement. Without the INDEX
privilege, user can still create
indexes when creating a table
Index_priv enum('N','Y') NO N using the CREATE TABLE
statement if the user has have the
CREATE privilege, and user can
create indexes using the ALTER
TABLE statement if they have the
ALTER privilege.

Can perform ALTER TABLE


Alter_priv enum('N','Y') NO N
statements.

511/3812
Can list all databases using the
SHOW DATABASES statement.
Without the SHOW DATABASES
privilege, user can still issue the
Show_db_priv enum('N','Y') NO N
SHOW DATABASES statement, but it
will only list databases containing
tables on which they have
privileges.
Can execute superuser
statements: CHANGE MASTER
TO, KILL (users who do not have
this privilege can only KILL their
own threads), PURGE LOGS,
SET global system variables, or
the mysqladmin debug command.
Also, this permission allows the
user to write data even if the
read_only startup option is set,
Super_priv enum('N','Y') NO N 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 mysqld option, that
command will not be executed
when a user with SUPER privileges
connects to the server.
Can create temporary tables with
Create_tmp_table_priv enum('N','Y') NO N the CREATE TEMPORARY
TABLE statement.
Acquire explicit locks using the
LOCK TABLES statement; user
Lock_tables_priv enum('N','Y') NO N also needs to have the SELECT
privilege on a table in order to lock
it.
Can execute stored procedure or
Execute_priv enum('N','Y') NO N
functions.
Accounts used by slave servers
on the master need this privilege.
Repl_slave_priv enum('N','Y') NO N
This is needed to get the updates
made on the master.
Can execute SHOW MASTER
Repl_client_priv enum('N','Y') NO N STATUS and SHOW SLAVE
STATUS statements.
Can create a view using the
Create_view_priv enum('N','Y') NO N
CREATE_VIEW statement.
Can show the CREATE VIEW
statement to create a view using
Show_view_priv enum('N','Y') NO N
the SHOW CREATE VIEW
statement.
Can create stored programs using
Create_routine_priv enum('N','Y') NO N the CREATE PROCEDURE and
CREATE FUNCTION statements.
Can change the characteristics of
Alter_routine_priv enum('N','Y') NO N a stored function using the ALTER
FUNCTION statement.
Can create a user using the
CREATE USER statement, or
Create_user_priv enum('N','Y') NO N
implicitly create a user with the
GRANT statement.

Event_priv enum('N','Y') NO N Create, drop and alter events.

512/3812
Can execute triggers associated
with tables the user updates,
Trigger_priv enum('N','Y') NO N
execute the CREATE TRIGGER
and DROP TRIGGER statements.
Create_tablespace_priv enum('N','Y') NO N
Can delete rows created through MariaDB
Delete_history_priv enum('N','Y') NO N
system versioning. 10.3.5
enum('',
ssl_type 'ANY', 'X509', NO TLS type - see TLS options.
'SPECIFIED')

ssl_cipher blob NO NULL TLS cipher - see TLS options.


x509_issuer blob NO NULL X509 cipher - see TLS options.
x509_subject blob NO NULL SSL subject - see TLS options.
Number of queries the user can
int(11) perform per hour. Zero is
max_questions NO 0
unsigned unlimited. See per-account
resource limits.
Number of updates the user can
int(11) perform per hour. Zero is
max_updates NO 0
unsigned unlimited. See per-account
resource limits.
Number of connections the
int(11) account can start per hour. Zero is
max_connections NO 0
unsigned unlimited. See per-account
resource limits.
Number of simultaneous
connections the account can
max_user_connections int(11) NO 0
have. Zero is unlimited. See per-
account resource limits.
Authentication plugin used on
plugin char(64) NO connection. If empty, uses the
default.
Authentication string for the
authentication_string text NO NULL
authentication plugin.
MySQL-compatibility option, not
password_expired enum('N','Y') NO N
implemented in MariaDB.
is_role enum('N','Y') NO N Whether the user is a role.
Role which will be enabled on
default_role char(80) NO N
user login automatically.
If non-zero, how long queries can
max_statement_time decimal(12,6) NO 0.000000 run before being killed
automatically.
Field Type Null Key Default Description Introduced

The Acl_roles status variable indicates how many rows the mysql.user table contains where is_role='Y' .
The 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 or the mysql_old_password 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 plugin. The mysql_old_password plugin is used with pre-4.1
password hashes, (which are 16 characters long).
MariaDB also supports the use of alternative authentication plugins. 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, ALTER USER, or GRANT statements.
513/3812
For example, the following statement would create an account that authenticates with the PAM authentication plugin:

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 accepts a service name that would
go into the authentication_string column for the account:

CREATE USER foo2@test IDENTIFIED VIA pam USING 'mariadb';

1.1.1.2.9.3.32 Spider mysql Database Tables


The Spider storage engine installs the following system tables in the mysql database.
mysql.spider_link_failed_log Table
The mysql.spider_link_failed_log table.

mysql.spider_link_mon_servers Table
The mysql.spider_link_mon_servers table.

mysql.spider_tables Table
The mysql.spider_tables table.

mysql.spider_table_crd Table
The mysql.spider_table_crd table.

mysql.spider_table_position_for_recovery Table
The mysql.spider_table_position_for_recovery table.

mysql.spider_table_sts Table
The mysql.spider_table_sts table.

mysql.spider_xa Table
The mysql.spider_xa table.

mysql.spider_xa_failed_log Table
The mysql.spider_xa_failed_log table.

mysql.spider_xa_member Table
The mysql.spider_xa_member table.

1.1.1.2.9.3.32.1 mysql.spider_link_failed_log
Table
The mysql.spider_link_failed_log table is installed by the Spider storage engine.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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()

514/3812
1.1.1.2.9.3.32.2
mysql.spider_link_mon_servers Table
The mysql.spider_link_mon_servers table is installed by the Spider storage engine.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

1.1.1.2.9.3.32.3 mysql.spider_tables Table


The mysql.spider_tables table is installed by the Spider storage engine.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

It contains the following fields:

Field Type Null Key Default Description

515/3812
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

1.1.1.2.9.3.32.4 mysql.spider_table_crd Table


The mysql.spider_table_crd table is installed by the Spider storage engine.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

516/3812
1.1.1.2.9.3.32.5
mysql.spider_table_position_for_recovery Table
The mysql.spider_table_position_for_recovery table is installed by the Spider storage engine.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

1.1.1.2.9.3.32.6 mysql.spider_table_sts Table


The mysql.spider_table_sts table is installed by the Spider storage engine.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

1.1.1.2.9.3.32.7 mysql.spider_xa Table


The mysql.spider_xa table is installed by the Spider storage engine.

MariaDB starting with 10.4


517/3812
In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

1.1.1.2.9.3.32.8 mysql.spider_xa_failed_log
Table
The mysql.spider_xa_failed_log table is installed by the Spider storage engine.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

518/3812
thread_id int(11) YES NULL
status char(8) NO
failed_time timestamp NO current_timestamp()

1.1.1.2.9.3.32.9 mysql.spider_xa_member
Table
The mysql.spider_xa_member table is installed by the Spider storage engine.

MariaDB starting with 10.4


In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3


In MariaDB 10.3 and before, this table uses the MyISAM 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

1.1.1.2.9.4 Sys Schema


MariaDB starting with 10.6.0
The sys_schema is a collection of views, functions and procedures to help administrators get insight into database
usage.

This article is currently incomplete.

519/3812
Sys Schema sys_config Table
1 Configuration options for the Sys Schema.

Sys Schema Stored Functions


Stored functions available in the Sys Schema.

Sys Schema Stored Procedures


Stored procedures available in the Sys Schema.

1.1.1.2.9.4.1 Sys Schema sys_config Table


MariaDB starting with 10.6.0
The Sys Schema sys_config table was added in MariaDB 10.6.0.

The sys_config table holds configuration options for the Sys Schema.
This is a persistent table (using the InnoDB storage engine), with the configuration persisting across upgrades (new
options are added with INSERT IGNORE).
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
Default
Variable Description
Value
Sets the size to truncate statements to, for the format_statement
statement_truncate_len 64
function.
The maximum number of rows to include for the views that does not
statement_performance_analyzer.limit 100 have a built-in limit (e.g. the 95th percentile view). If not set the limit
is 100.
Used together with the 'custom' view. If the value contains a space,
it is considered a query, otherwise it must be an existing view
statement_performance_analyzer.view NULL querying the
performance_schema.events_statements_summary_by_digest
table.
Specifies whether it is allowed to do table scan queries on
diagnostics.allow_i_s_tables OFF
information_schema.TABLES for the diagnostics procedure.
Set to 'ON' to include the raw data (e.g. the original output of
diagnostics.include_raw OFF
"SELECT * FROM sys.metrics") for the diagnostics procedure.
Sets the maximum output length for JSON object output by the
ps_thread_trx_info.max_length 65535
ps_thread_trx_info() function.

1.1.1.2.9.4.2 Sys Schema Stored Functions


The following stored functions are available in the Sys Schema.

520/3812
extract_schema_from_file_name
Returns the schema (database) name.

extract_table_from_file_name
Returns the table name from the provided path.

format_bytes
Returns a string consisting of a value and the units in a human-readable format.

format_path
Returns a modified path, replacing subpaths matching the values of various system variables.

format_statement
Returns a reduced length string.

format_time
Given a time in picoseconds, returns a human-readable time and unit.

list_add
Takes a list to be be modified and a value to be added to the list, returning the resulting value.

list_drop
Takes a list to be be modified and a value to be dropped, returning the resulting value.

ps_is_account_enabled
Whether or not Performance Schema instrumentation for a given account is enabled.

ps_is_consumer_enabled
Whether or not Performance Schema instrumentation for a given consumer is enabled.

ps_is_instrument_default_enabled
Whether or not a Performance Schema instrument is enabled by default.

ps_is_instrument_default_timed
Whether or not a Performance Schema instrument is timed by default.

ps_is_thread_instrumented
Whether or not instrumentation for a given connection_id is enabled.

ps_thread_account
Returns the account associated with the given thread_id.

ps_thread_id
Returns the thread_id associated with the given connection_id.

ps_thread_stack
Returns statements, stages, events within the Performance Schema for a given thread_id.

ps_thread_trx_info
Returns a JSON object with information about the thread specified by the given thread_id.

quote_identifier
Returns quoted, properly escaped identifier.

sys_get_config
Returns a configuration option value from the sys_config table.

version_major
Returns the MariaDB Server major release version.

version_minor
Returns the MariaDB Server minor release version.

version_patch
MariaDB Server patch release version.

1.1.1.2.9.4.2.1
521/3812
extract_schema_from_file_name
Syntax
sys.extract_schema_from_file_name(path)

Description
extract_schema_from_file_name is a stored function available with the Sys Schema.
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()

1.1.1.2.9.4.2.2 extract_table_from_file_name
Syntax
sys.extract_table_from_file_name(path)

Description
extract_table_from_file_name is a stored function available with the Sys Schema.
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()

1.1.1.2.9.4.2.3 format_bytes
Syntax
522/3812
sys.format_bytes(double)

Description
format_bytes is a stored function available with the Sys Schema.

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 |
+------------------------------------+------------------------------------+

1.1.1.2.9.4.2.4 format_path
Syntax
sys.format_path(path)

Description
format_path is a stored function available with the Sys Schema 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
tmpdir
slave_load_tmpdir
innodb_data_home_dir
innodb_log_group_home_dir
innodb_undo_directory
basedir
523/3812
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 |
+------------------------------------------------------------------+

1.1.1.2.9.4.2.5 format_statement
Syntax
sys.format_statement(statement)

Description
Returns a reduced length string. The length is specified by the statement_truncate_len configuration option (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 |
+---------------------------------------------------+

1.1.1.2.9.4.2.6 format_time
Syntax
sys.format_time(picoseconds)

Description
format_time is a stored function available with the Sys Schema. Given a time in picoseconds, returns a human-
524/3812
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

Examples
SELECT 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;
+---------+----------+-----------+---------+--------+--------+--------+---------+
| ns | us | ms | s | m | h | d | w |
+---------+----------+-----------+---------+--------+--------+--------+---------+
| 4.32 ns | 43.21 us | 432.11 ms | 43.21 s | 7.20 m | 1.20 h | 5.00 d | 71.45 w |
+---------+----------+-----------+---------+--------+--------+--------+---------+

1.1.1.2.9.4.2.7 list_add
Syntax
sys.list_add(list,value)

Description
list_add is a stored function available with the Sys Schema.

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.
The related function list_drop 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

525/3812
1.1.1.2.9.4.2.8 list_drop
Syntax
sys.list_drop(list,value)

Description
list_drop is a stored function available with the Sys Schema.

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.
The related function list_add 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

1.1.1.2.9.4.2.9 ps_is_account_enabled
Syntax
sys.ps_is_account_enabled(host,user)

Description
ps_is_account_enabled is a stored function available with the Sys Schema.
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 |
+------------------------------------------------+

1.1.1.2.9.4.2.10 ps_is_consumer_enabled
526/3812
Syntax
sys.ps_is_consumer_enabled(consumer)

Description
ps_is_consumer_enabled is a stored function available with the Sys Schema.
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

1.1.1.2.9.4.2.11
ps_is_instrument_default_enabled
Syntax
sys.ps_is_instrument_default_enabled(instrument)

Description
ps_is_instrument_default_enabled is a stored function available with the Sys Schema.
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

527/3812
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 |
+--------------------------------------------+

1.1.1.2.9.4.2.12
ps_is_instrument_default_timed
Syntax
sys.ps_is_instrument_default_timed(instrument)

Description
ps_is_instrument_default_timed is a stored function available with the Sys Schema.

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

528/3812
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 |
+------------------------------------------+

1.1.1.2.9.4.2.13 ps_is_thread_instrumented
Syntax
sys.ps_is_thread_instrumented(connection_id)

Description
ps_is_thread_instrumented is a stored function available with the Sys Schema 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 |
+-------------------------------------+

1.1.1.2.9.4.2.14 ps_thread_account
529/3812
Syntax
sys.ps_thread_account(thread_id)

Description
ps_thread_account is a stored function available with the Sys Schema 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 |
+-----------------------------------------------+

1.1.1.2.9.4.2.15 ps_thread_id
Syntax
sys.ps_thread_id(connection_id)

Description
ps_thread_id is a stored function available with the Sys Schema 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

530/3812
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 |
+------------------------+

1.1.1.2.9.4.2.16 ps_thread_stack
Syntax
sys.ps_thread_stack(thread_id, verbose)

Description
ps_thread_stack is a stored function available with the Sys Schema 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": []}

1.1.1.2.9.4.2.17 ps_thread_trx_info
Syntax
sys.ps_thread_trx_info(thread_id)

531/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
ps_thread_trx_info is a stored function available with the Sys Schema.

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 and the
Performance Schema events_statements_history Table (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 (by default 65535). If the returned value exceeds this length, a JSON object error is returned.

Examples

See Also
Sys Schema sys_config Table

1.1.1.2.9.4.2.18 quote_identifier
Syntax
sys.quote_identifier(str)

Description
quote_identifier is a stored function available with the Sys Schema.
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` |
+-----------------------------------------------------------+

1.1.1.2.9.4.2.19 sys_get_config
Syntax
sys.sys_get_config(name,default)

532/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
sys_get_config is a stored function available with the Sys Schema.
The function returns a configuration option value from the sys_config table. 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

1.1.1.2.9.4.2.20 version_major
Syntax
sys.version_major()

Description
version_major is a stored function available with the Sys Schema.

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_patch

1.1.1.2.9.4.2.21 version_minor
Syntax
533/3812
sys.version_minor()

Description
version_minor is a stored function available with the Sys Schema.
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_patch

1.1.1.2.9.4.2.22 version_patch
Syntax
sys.version_patch()

Description
version_patch is a stored function available with the Sys Schema.

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_minor

1.1.1.2.9.4.3 Sys Schema Stored Procedures


This article is currently incomplete.

The following stored procedures are available in the Sys Schema.


create_synonym_db
Takes a source db and create a synonym db with views that point to all of t...
534/3812
statement_performance_analyzer
Returns a report on running statements.

table_exists
Given a database and table name, returns the table type.

1.1.1.2.9.4.3.1 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 available with the Sys Schema.

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 or
information_schema 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 |
...

535/3812
1.1.1.2.9.4.3.2
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 available with the Sys Schema which returns a report on
running statements.
The following options from the sys_config 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.

1.1.1.2.9.4.3.3 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 available with the Sys Schema.
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 |
+-------------+

536/3812
1.1.1.2.9.5 mariadb_schema
Contents
1. History

mariadb_schema is a data type qualifier that allows one to create MariaDB native date types in an SQL_MODE that has
conflicting data type translations.
mariadb_schema was introduced in MariaDB 10.3.24, MariaDB 10.4.14 and MariaDB 10.5.5.
For example, in SQL_MODE=ORACLE, if one creates a table with the DATE type, it will actually create a DATETIME
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 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 is executed in SQL_MODE=ORACLE. The prefix
is not displayed when SHOW CREATE TABLE 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 type when running SHOW CREATE TABLE in Oracle mode.

History
When running with SQL_MODE=ORACLE, MariaDB server translates the data type DATE to DATETIME , for better
Oracle compatibility:

537/3812
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 and runs a SHOW CREATE
TABLE 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 ).
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
) |
+-------+--------------------------------------------------------------+

1.1.1.2.9.6 Writing Logs Into Tables


By default, all logs are disabled or written into files. The general query log and the slow query log 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 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 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 table, and the slow query log will be written into the slow_log 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:

538/3812
ERROR 1556 (HY000): You can't use locks with log tables.

To flush data to the tables, use FLUSH TABLES instead of FLUSH LOGS.
To empty the contents of the log tables, TRUNCATE TABLE can be used.
The log tables use the CSV 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 (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 and CHECKSUM TABLE are supported.


CREATE TABLE is supported. ALTER TABLE, RENAME TABLE and DROP TABLE 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 thus cannot be replicated.

1.1.1.2.10 BINLOG
Syntax
BINLOG 'str'

Description
BINLOG is an internal-use statement. It is generated by the mariadb-binlog/mysqlbinlog program as the printable
representation of certain events in binary log files. The 'str' value is a base 64-encoded string the that server
decodes to determine the data change indicated by the corresponding event. This statement requires the SUPER
privilege (<= MariaDB 10.5.1) or theBINLOG REPLAY privilege (>= MariaDB 10.5.2).

See also
MariaDB replication

1.1.1.2.11 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 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 option to enable binary logging.
To list the binary log files on the server, use SHOW BINARY LOGS. To see which files they are reading, use SHOW
SLAVE STATUS (or SHOW REPLICA STATUS from MariaDB 10.5.1). You can only delete the files that are older than
the oldest file that is used by the slaves.

539/3812
To delete all binary log files, use RESET MASTER. To move to a new log file (for example if you want to remove the
current log file), use FLUSH LOGS before you execute PURGE LOGS .
If the 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, the binlog_expire_logs_seconds variable allows more precise control over
binlog deletion, and takes precedence if both are non-zero.
Requires the SUPER privilege or, from MariaDB 10.5.2, the 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
FLUSH LOGS.

1.1.1.2.12 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 tables.
A default key cache exists and cannot be destroyed. To create more key caches, the 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 and include some CACHE INDEX (and optionally LOAD 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)
540/3812
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.

1.1.1.2.13 DESCRIBE
Syntax
{DESCRIBE | DESC} tbl_name [col_name | wild]

Contents
1. Syntax
2. Description
3. See Also

Description
DESCRIBE provides information about the columns in a table. It is a shortcut for SHOW COLUMNS FROM . These statements
also display information for views.
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 provides more information about the output columns.

See Also
SHOW COLUMNS
INFORMATION_SCHEMA.COLUMNS Table
mysqlshow

1.1.1.2.14 EXECUTE Statement


Syntax
EXECUTE stmt_name
[USING expression[, expression] ...]

Contents
1. Syntax
2. Description
3. Example
4. See Also

MariaDB starting with 10.2.3


EXECUTE with expression as parameters was introduced in MariaDB 10.2.3 . Before that one could only use
variables (@var_name) as parameters.

Description
541/3812
After preparing a statement with PREPARE , 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.

See Also
EXECUTE IMMEDIATE

1.1.1.2.15 HELP Command


Syntax
HELP search_string

Description
The HELP command can be used in any MariaDB client, such as the mysql 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 mysql 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:

542/3812
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, help_topic, help_category and help_keyword. These tables are populated by the mysql_install_db or
fill_help_table.sql scripts which, until MariaDB 10.4.7, contain data generated from an old version of MySQL.

1.1.1.2.16 KILL [CONNECTION | QUERY]


Syntax
KILL [HARD | SOFT] { {CONNECTION|QUERY} thread_id | QUERY ID query_id | USER user_name }

Contents
1. Syntax
2. Description
3. See Also

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.
If you have the PROCESS privilege, you can see all threads. If you have the SUPER privilege, or, from MariaDB 10.5.2,
the 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
and Aria tables (REPAIR TABLE, OPTIMIZE TABLE).
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
543/3812
CURRENT_USER or CURRENT_USER()
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() 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 statement or query the Information Schema
PROCESSLIST table.
Note: You cannot use KILL with the Embedded MySQL 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 mysqladmin kill thread_id [,thread_id...] to kill connections. To get a list of running
queries, use mysqladmin processlist . See mysqladmin.
Percona Toolkit contains a program, pt-kill 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
Aborting statements that exceed a certain time to execute
idle_transaction_timeout

1.1.1.2.17 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 statement, or into the default key cache otherwise. LOAD INDEX INTO CACHE is used only for
MyISAM or Aria tables.
The IGNORE LEAVES modifier causes only blocks for the nonleaf nodes of the index to be preloaded.

1.1.1.2.18 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 to
execute RESET .
544/3812
RESET acts as a stronger version of the FLUSH statement.
The different RESET options are:

Option Description
SLAVE
["connection_name"] Deletes all relay logs from the slave and reset the replication position in the master binary log.
[ALL]
Deletes all old binary logs, makes the binary index file (--log-bin-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
MASTER
want to just delete old, not used binary logs, you should use the PURGE BINARY LOGS
command.
QUERY CACHE Removes all queries from the query cache. See also FLUSH QUERY CACHE.

1.1.1.2.19 SHUTDOWN
Contents
1. Syntax
2. Description
3. WAIT FOR ALL SLAVES
4. Required Permissions
5. Shutdown for Upgrades
6. Example
7. Other Ways to Stop mysqld
8. See Also

Syntax
SHUTDOWN [WAIT FOR ALL { SLAVES | REPLICAS } ]

Description
The SHUTDOWN command shuts the server down.

WAIT FOR ALL SLAVES


MariaDB starting with 10.4.4
The WAIT FOR ALL SLAVES option was first added in MariaDB 10.4.4. WAIT FOR ALL REPLICAS has been a synonym
since MariaDB 10.5.1.

When a master server is shutdown and it goes through the normal shutdown process, the master kills client threads in
random order. By default, the master 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 master during a normal shutdown that won't be replicated. This is true even if semi-synchronous
replication is being used.
In MariaDB 10.4 and later, this problem can be solved by shutting down the server with the SHUTDOWN command and
by providing the WAIT FOR ALL SLAVES option to the command. For example:

SHUTDOWN WAIT FOR ALL SLAVES;

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 has been sent to all connected
replicas.
See Replication Threads: Binary Log Dump Threads and the Shutdown Process for more information.

Required Permissions
One must have a SHUTDOWN privilege (see GRANT) to use this command. It is the same privilege one needs to use the
mariadb-admin/mysqladmin shutdown command.

Shutdown for Upgrades


545/3812
If you are doing a shutdown to migrate to another major version of MariaDB, please ensure that the
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 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 mysqld


You can use the mariadb-admin/mysqladmin shutdown command to take down mysqld cleanly.
You can also use the system kill command on Unix with signal SIGTERM (15)

kill -SIGTERM pid-of-mysqld-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 mysqladmin shutdown .
On windows you should use:

NET STOP MySQL

See Also
mariadb-admin/mysqladmin shutdown.
InnoDB fast shutdown option

1.1.1.2.20 USE
Syntax
USE 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() function (SCHEMA() is a synonym) returns the default database.


Another way to set the default database is specifying its name at mysql command line client startup.

See Also
Identifier Qualifiers

1.1.1.3 Data Definition


SQL Commands for defining data, such as ALTER, CREATE, DROP, RENAME etc.

546/3812
CREATE
Articles on the various CREATE statements.

ALTER
The various ALTER statements in MariaDB.

DROP
Articles on various DROP commands.

Atomic DDL
Making DDL Atomic/Crash-safe.

CONSTRAINT
Define a CHECK or FOREIGN KEY constraint.

MERGE
Allows you to access a collection of identical MyISAM tables as one.

RENAME TABLE
1 Change a table's name.

TRUNCATE TABLE
DROP and re-CREATE a table.

There are 3 related questions .

1.1.1.3.1 CREATE
Articles on the various CREATE statements.
CREATE DATABASE
5 Create a database.

CREATE EVENT
Create and schedule a new event.

CREATE FUNCTION
2 Creates a stored function.

CREATE FUNCTION UDF


Create a user-defined function.

CREATE INDEX
Create an index on one or more columns.

CREATE LOGFILE GROUP


The CREATE LOGFILE GROUP statement is not supported by MariaDB. It was orig...

CREATE PACKAGE
2 Create a stored package, in Oracle-mode.

CREATE PACKAGE BODY


3 Creates the package body for a stored package.

CREATE PROCEDURE
1 Creates a stored procedure.

CREATE ROLE
Add new roles.

CREATE SEQUENCE
6 Creates a sequence that generates new values when called with NEXT VALUE FOR.

CREATE SERVER
Define a server.

547/3812
CREATE TABLE
7 Creates a new table.

CREATE TABLESPACE
CREATE TABLESPACE is not available in MariaDB.

CREATE TRIGGER
3 Create a new trigger.

CREATE USER
8 Create new MariaDB accounts.

CREATE VIEW
2 Create or replace a view.

Silent Column Changes


MariaDB silently changes column specifications in certain situations.

Generated (Virtual and Persistent/Stored) Columns


27 Generated (virtual and persistent/stored) columns.

Invisible Columns
Invisible columns are hidden in certain contexts.

There are 1 related questions .

1.1.1.3.1.1 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'

Contents
1. Syntax
2. Description
1. OR REPLACE
2. IF NOT EXISTS
3. COMMENT
3. Examples
4. See Also

Description
CREATE DATABASE creates a database with the given name. To use this statement, you need the CREATE privilege for
the database. CREATE SCHEMA is a synonym for CREATE DATABASE .
For valid identifiers to use as database names, see Identifier Names.

OR REPLACE

MariaDB starting with 10.1.3


The OR REPLACE clause was added in MariaDB 10.1.3

If the optional OR REPLACE clause is used, it acts as a shortcut for:

DROP DATABASE IF EXISTS db_name;


CREATE DATABASE db_name ...;

548/3812
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


From MariaDB 10.5.0, 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.

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. See Setting Character Sets and Collations for more details.

CREATE DATABASE czech_slovak_names


CHARACTER SET = 'keybcs2'
COLLATE = 'keybcs2_bin';

Comments, from MariaDB 10.5.0:

CREATE DATABASE presentations COMMENT 'Presentations for conferences';

See Also
Identifier Names
DROP DATABASE
SHOW CREATE DATABASE
ALTER DATABASE
SHOW DATABASES
Character Sets and Collations
Information Schema SCHEMATA Table

549/3812
1.1.1.3.1.2 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}

Contents
1. Syntax
2. Description
1. OR REPLACE
2. IF NOT EXISTS
3. ON SCHEDULE
4. AT
5. ON COMPLETION [NOT] PRESERVE
6. ENABLE/DISABLE/DISABLE ON
SLAVE
7. COMMENT
3. Examples
4. See Also

Description
This statement creates and schedules a new event. It requires the EVENT 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.
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.

OR REPLACE
550/3812
The OR REPLACE clause was included in MariaDB 10.1.4 . 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 , 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.
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.
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 . 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 (the column is named EVENT_COMMENT ).

551/3812
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
Identifier Names
Events Overview
SHOW CREATE EVENT
ALTER EVENT
DROP EVENT

552/3812
1.1.1.3.1.3 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

Contents
1. Syntax
2. Description
1. IN | OUT | INOUT | IN OUT
2. AGGREGATE
3. RETURNS
4. LANGUAGE SQL
5. OR REPLACE
6. IF NOT EXISTS
7. [NOT] DETERMINISTIC
8. MODIFIES SQL DATA
9. READS SQL DATA
10. CONTAINS SQL
11. NO SQL
12. Oracle Mode
3. Security
4. Character sets and collations
5. Examples
6. See Also

Description
Use the CREATE FUNCTION statement to create a new stored function. You must have the CREATE ROUTINE 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
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) for details.
You can use a SELECT 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 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.
553/3812
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.

IN | OUT | INOUT | IN OUT

MariaDB starting with 10.8.0


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

MariaDB starting with 10.3.3


From MariaDB 10.3.3, it is possible to create stored aggregate functions as well. See Stored Aggregate Functions 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 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.
554/3812
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() or
CURRENT_TIMESTAMP(). 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

MariaDB starting with 10.1.3


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 for the function are not dropped.

IF NOT EXISTS

MariaDB starting with 10.1.3


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, 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, UPDATE, INSERT, REPLACE 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 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 or DO.

NO SQL
NO SQL means nothing, because MariaDB does not currently support any language other than SQL.

Oracle Mode

MariaDB starting with 10.3


From MariaDB 10.3, a subset of Oracle's PL/SQL language has been supported in addition to the traditional
SQL/PSM-based MariaDB syntax. See Oracle mode from MariaDB 10.3 for details on changes when running Oracle

555/3812
mode.

Security
You must have the EXECUTE 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 privilege, or, from
MariaDB 10.5.2, the SET USER privilege, to use the DEFINER clause. See 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 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. 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 mysql client
for more.

556/3812
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
Stored Aggregate Functions
CREATE FUNCTION (UDF)
SHOW CREATE FUNCTION
ALTER FUNCTION
DROP FUNCTION
SHOW FUNCTION STATUS
Stored Routine Privileges
Information Schema ROUTINES Table

1.1.1.3.1.4 CREATE FUNCTION UDF


Syntax
CREATE [OR REPLACE] [AGGREGATE] FUNCTION [IF NOT EXISTS] function_name
RETURNS {STRING|INTEGER|REAL|DECIMAL}
SONAME shared_library_name

Contents
1. Syntax
2. Description
1. RETURNS
2. shared_library_name
3. AGGREGATE
4. OR REPLACE
5. IF NOT EXISTS
6. Upgrading a UDF
7. Examples
3. See Also

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() or CONCAT().
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 for the mysql database. This is necessary because CREATE
FUNCTION adds a row to the mysql.func system table that records the function's name, type, and shared library name. If
you do not have this table, you should run the mysql_upgrade 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.
For creating a stored function as opposed to a user-defined function, see CREATE FUNCTION.
For valid identifiers to use as function names, see Identifier Names.

557/3812
RETURNS
The RETURNS clause indicates the type of the function's return value, and can be one of STRING, INTEGER, REAL or
DECIMAL. DECIMAL functions currently return string values and should be written like STRING 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 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() and AVG().

MariaDB starting with 10.4


Aggregate UDF functions can be used as window functions.

OR REPLACE

MariaDB starting with 10.1.3


The OR REPLACE clause was added in MariaDB 10.1.3

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


The IF NOT EXISTS clause was added in MariaDB 10.1.3

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 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
558/3812
Identifier Names
DROP FUNCTION
CREATE FUNCTION

559/3812
1.1.1.3.1.5 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}

Contents
1. Syntax
2. Description
3. Privileges
4. Online DDL
5. CREATE OR REPLACE INDEX
6. CREATE INDEX IF NOT EXISTS
7. Index Definitions
8. WAIT/NOWAIT
9. ALGORITHM
10. LOCK
11. Progress Reporting
12. WITHOUT OVERLAPS
13. Examples
14. See Also

Description
CREATE INDEX is mapped to an ALTER TABLE statement to create indexes. See ALTER TABLE. CREATE INDEX
cannot be used to create a PRIMARY KEY; use ALTER TABLE instead.
If another connection is using the table, a metadata lock is active, and this statement will wait until the lock is released.
This is also true for non-transactional tables.
Another shortcut, DROP INDEX, allows the removal of an index.
For valid identifiers to use as index names, see Identifier Names.

Note that KEY_BLOCK_SIZE is currently ignored in CREATE INDEX, although it is included in the output of SHOW
CREATE TABLE.

Privileges
Executing the CREATE INDEX statement requires the INDEX privilege for the table or the database.

Online DDL
Online DDL is supported with the ALGORITHM and LOCK clauses.
560/3812
See InnoDB Online DDL Overview for more information on online DDL with InnoDB.

CREATE OR REPLACE INDEX


MariaDB starting with 10.1.4
The OR REPLACE clause was added in MariaDB 10.1.4 .

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 for information about index definitions.

WAIT/NOWAIT
MariaDB starting with 10.3.0
Set the lock wait timeout. See WAIT and NOWAIT.

ALGORITHM
See ALTER TABLE: ALGORITHM for more information.

LOCK
See ALTER TABLE: 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 mysql client, then the progress report might look like this::

CREATE INDEX 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 statement and in the contents of the
information_schema.PROCESSLIST table.

See Progress Reporting for more information.

WITHOUT OVERLAPS
MariaDB starting with 10.5.3
The WITHOUT OVERLAPS clause allows one to constrain a primary or unique index such that application-time
periods cannot overlap.

Examples
Creating a unique index:

CREATE UNIQUE INDEX HomePhone ON Employees(Home_Phone);

OR REPLACE and IF NOT EXISTS:

561/3812
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, creating a unique index for an application-time period table with a WITHOUT OVERLAPS
constraint:

CREATE UNIQUE INDEX u ON rooms (room_number, p WITHOUT OVERLAPS);

See Also
Identifier Names
Getting Started with Indexes
What is an Index?
ALTER TABLE
DROP INDEX
SHOW INDEX
SPATIAL INDEX
Full-text Indexes
WITHOUT OVERLAPS
Ignored Indexes

1.1.1.3.1.6 CREATE LOGFILE GROUP


The CREATE LOGFILE GROUP statement is not supported by MariaDB. It was originally inherited from MySQL NDB
Cluster. See MDEV-19295 for more information.

562/3812
1.1.1.3.1.7 CREATE PACKAGE
MariaDB starting with 10.3.5
Oracle-style packages were introduced in MariaDB 10.3.5.

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 }

Contents
1. Syntax
2. Description
3. Function parameter quantifiers IN | OUT
| INOUT | IN OUT
4. Examples
5. See Also

Description
The CREATE PACKAGE statement can be used when Oracle SQL_MODE 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
563/3812
CREATE PACKAGE BODY statement.

Function parameter quantifiers IN | OUT | INOUT | IN


OUT
MariaDB starting with 10.8.0
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
SHOW CREATE PACKAGE
DROP PACKAGE
Oracle SQL_MODE

564/3812
1.1.1.3.1.8 CREATE PACKAGE BODY
MariaDB starting with 10.3.5
Oracle-style packages were introduced in MariaDB 10.3.5.

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:
565/3812
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

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The CREATE PACKAGE BODY statement can be used when Oracle SQL_MODE 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 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

566/3812
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
SHOW CREATE PACKAGE BODY
DROP PACKAGE BODY
Oracle SQL_MODE

567/3812
1.1.1.3.1.9 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

Contents
1. Syntax
2. Description
1. Things to be Aware of With CREATE
OR REPLACE
3. CREATE PROCEDURE IF NOT EXISTS
1. IN/OUT/INOUT
2. DETERMINISTIC/NOT
DETERMINISTIC
3. CONTAINS SQL/NO SQL/READS
SQL DATA/MODIFIES SQL DATA
4. Invoking stored procedure from within
programs
5. OR REPLACE
6. sql_mode
7. Character Sets and Collations
8. Oracle Mode
4. Examples
5. See Also

Description
Creates a stored procedure. 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).
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.
The DEFINER and SQL SECURITY clauses specify the security context to be used when checking access privileges at
routine execution time, as described here. Requires the SUPER privilege, or, from MariaDB 10.5.2, the 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
568/3812
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.

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. 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, UPDATE, INSERT, REPLACE or DDL.
READS SQL DATA means that the function reads data stored in databases, but does not modify any data. This happens if
SELECT 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 or DO.
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 or
INSERT, or it can be a compound statement written using BEGIN and END. Compound statements can contain
declarations, loops, and other control structure statements. See Programmatic and Compound Statements for syntax
details.
MariaDB allows routines to contain DDL statements, such as CREATE and DROP. MariaDB also allows stored
procedures (but not stored functions) to contain SQL transaction statements such as COMMIT .
For additional information about statements that are not allowed in stored routines, see Stored Routine Limitations.

Invoking stored procedure from within programs


For information about invoking stored procedures from within programs written in a language that has a
MariaDB/MySQL interface, see CALL.

OR REPLACE
If the optional OR REPLACE clause is used, it acts as a shortcut for:

569/3812
DROP PROCEDURE IF EXISTS name;
CREATE PROCEDURE name ...;

with the exception that any existing privileges for the procedure are not dropped.

sql_mode
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.

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
MariaDB starting with 10.3
From MariaDB 10.3, a subset of Oracle's PL/SQL language has been supported in addition to the traditional
SQL/PSM-based MariaDB syntax. See Oracle mode from MariaDB 10.3 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 mysql client.

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:

570/3812
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
Stored Procedure Overview
ALTER PROCEDURE
DROP PROCEDURE
SHOW CREATE PROCEDURE
SHOW PROCEDURE STATUS
Stored Routine Privileges
Information Schema ROUTINES Table

1.1.1.3.1.10 CREATE ROLE


1.1.1.3.1.11 CREATE SEQUENCE
1.1.1.3.1.12 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 }

Contents
1. Syntax
2. Description
1. OR REPLACE
2. IF NOT EXISTS
3. Examples
4. See Also

571/3812
Description
This statement creates the definition of a server for use with the Spider, Connect, FEDERATED or FederatedX
storage engine. The CREATE SERVER statement creates a new row within the servers table within the mysql
database. This statement requires the SUPER privilege or, from MariaDB 10.5.2, the 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 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 table that can later be used with the CREATE
TABLE statement when creating a Spider, Connect, FederatedX or FEDERATED 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 removes a previously created server definition.
CREATE SERVER is not written to the binary log, irrespective of the binary log format being used. From MariaDB
10.1.13 , Galera replicates the CREATE SERVER, ALTER SERVER and DROP SERVER statements.
For valid identifiers to use as server names, see Identifier Names.

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 |
+-------+------+----------------------------------------------------------------+

572/3812
See Also
Identifier Names
ALTER SERVER
DROP SERVER
Spider Storage Engine
Connect Storage Engine

1.1.1.3.1.13 CREATE TABLE


1.1.1.3.1.14 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 for more information.

1.1.1.3.1.15 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;

Contents
1. Syntax
2. Description
1. OR REPLACE
2. DEFINER
3. IF NOT EXISTS
4. trigger_time
5. trigger_event
1. FOLLOWS/PRECEDES
other_trigger_name
6. Atomic DDL
3. Examples
4. See Also

Description
This statement creates a new trigger. 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 privilege for the table associated with the trigger.

MariaDB starting with 10.2.3


You can have multiple triggers for the same trigger_time and trigger_event .

For valid identifiers to use as trigger names, see Identifier Names.

OR REPLACE
MariaDB starting with 10.1.4
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.

573/3812
DEFINER
The DEFINER clause determines the security context to be used when checking access privileges at trigger activation
time. Usage requires the SUPER privilege, or, from MariaDB 10.5.2, the SET USER privilege.

IF NOT EXISTS
MariaDB starting with 10.1.4
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,
LOAD DATA, and REPLACE statements.
UPDATE : The trigger is activated whenever a row is modified; for example, through UPDATE statements.
DELETE : The trigger is activated whenever a row is deleted from the table; for example, through DELETE and
REPLACE 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

MariaDB starting with 10.2.3


The FOLLOWS other_trigger_name and PRECEDES other_trigger_name options were added in MariaDB 10.2.3 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/mysqldump and other backup methods will not change trigger order. You can verify
the trigger order from the ACTION_ORDER column in INFORMATION_SCHEMA.TRIGGERS table.
SELECT trigger_name, action_order FROM information_schema.triggers
WHERE event_object_table='t1';

Atomic DDL
MariaDB starting with 10.6.1
MariaDB 10.6.1 supports Atomic DDL 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

574/3812
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
Trigger Overview
DROP TRIGGER
Information Schema TRIGGERS Table
SHOW TRIGGERS
SHOW CREATE TRIGGER
Trigger Limitations

1.1.1.3.1.16 CREATE USER


1.1.1.3.1.17 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]

Contents
1. Syntax
2. Description
1. WITH CHECK OPTION
2. IF NOT EXISTS
3. Atomic DDL
3. Examples
4. See Also

Description
The CREATE VIEW statement creates a new view, 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.
The select_statement is a SELECT 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 shows that such queries are rewritten and column names are
575/3812
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 helps in finding this kind of problems.
The ALGORITHM clause 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, 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.
576/3812
You cannot associate a trigger with a view.
For valid identifiers to use as view names, see Identifier Names.
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 privilege, or, from MariaDB 10.5.2, the 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 privilege, or, from MariaDB 10.5.2, the 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
577/3812
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 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.

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.

IF NOT EXISTS
MariaDB starting with 10.1.3
The IF NOT EXISTS clause was added in MariaDB 10.1.3

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
MariaDB 10.6.1 supports Atomic DDL and CREATE VIEW is atomic.

Examples

578/3812
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
ALTER VIEW
DROP VIEW
SHOW CREATE VIEWS
INFORMATION SCHEMA VIEWS Table

1.1.1.3.1.18 Silent Column Changes


When a CREATE TABLE or ALTER TABLE command is issued, MariaDB will silently change a column specification in
the following cases:
PRIMARY KEY columns are always NOT NULL.
Any trailing spaces from SET and ENUM values are discarded.
TIMESTAMP columns are always NOT NULL, and display sizes are discarded
A row-size limit of 65535 bytes applies
If strict SQL mode is not enabled (it is enabled by default from MariaDB 10.2), a VARCHAR column longer than
65535 become TEXT, and a VARBINARY columns longer than 65535 becomes a BLOB. 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
BOOLEAN TINYINT
CHARACTER VARYING(M) VARCHAR(M)
FIXED DECIMAL
FLOAT4 FLOAT
FLOAT8 DOUBLE
INT1 TINYINT
579/3812
INT2 SMALLINT
INT3 MEDIUMINT
INT4 INT
INT8 BIGINT
LONG VARBINARY MEDIUMBLOB
LONG VARCHAR MEDIUMTEXT
LONG MEDIUMTEXT
MIDDLEINT MEDIUMINT
NUMERIC DECIMAL

Currently, all MySQL types are supported in MariaDB.


For type mapping between Cassandra and MariaDB, see Cassandra storage engine .

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 | |
+-------+-------------------+------+-----+---------+-------+

1.1.1.3.1.19 Generated (Virtual and


Persistent/Stored) Columns
Syntax
<type> [GENERATED ALWAYS] AS ( <expression> )
[VIRTUAL | PERSISTENT | STORED] [UNIQUE] [UNIQUE KEY] [COMMENT <text>]

580/3812
Contents
1. Syntax
2. Description
3. Supported Features
1. Storage Engine Support
2. Data Type Support
3. Index Support
4. Statement Support
5. Expression Support
6. Making Stored Values Consistent
7. MySQL Compatibility Support
4. Implementation Differences
1. Implementation Differences Compared
to Microsoft SQL Server
5. Development History
6. Examples
7. See Also

MariaDB's generated columns syntax is designed to be similar to the syntax for Microsoft SQL Server's computed
columns and Oracle Database's virtual columns . In MariaDB 10.2 and later, the syntax is also compatible with the
syntax for MySQL's generated columns .

Description
A generated column is a column in a table that cannot explicitly be set to a specific value in a DML query. 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 or user-defined functions
(UDFs).
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, Aria, MyISAM and CONNECT support generated columns.


A column in a MERGE 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 column option is supported when defining generated columns.

MariaDB starting with 10.2.6


In MariaDB 10.2.6 and later, the following statements apply to data types for generated columns:
Using the AUTO_INCREMENT column option is not supported when defining generated columns. Previously,
it was supported, but this support was removed, because it would not work correctly. See MDEV-11117 .

Index Support
Using a generated column as a table's primary key is not supported. See 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:

581/3812
ERROR 1903 (HY000): Primary key cannot be defined upon a computed column

Using PERSISTENT generated columns as part of a foreign key is supported.


Referencing PERSISTENT generated columns as part of a foreign key 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

MariaDB starting with 10.2.3


In MariaDB 10.2.3 and later, the following statements apply to indexes for generated columns:
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.

MariaDB until 10.2.2


In MariaDB 10.2.2 and before, the following statements apply to indexes for generated columns:
Defining indexes on VIRTUAL generated columns is not supported.
Defining indexes on 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 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 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 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 statement supports generated columns.
Generated columns can be referenced in the INSERT, UPDATE, and DELETE statements.
However, VIRTUAL or PERSISTENT generated columns cannot be explicitly set to any other values than
NULL or DEFAULT. If a generated column is explicitly set to any other value, then the outcome depends on
whether strict mode is enabled in sql_mode. 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 statement has limited support for generated columns.
It supports defining generated columns in a new table.
It supports using generated columns to partition tables.
It does not support using the versioning clauses with generated columns.
The ALTER TABLE 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 is not set to COPY .
See MDEV-15476 for more information.
It does not support the CHANGE clause for VIRTUAL generated columns if ALGORITHM is not set to COPY .
See MDEV-17035 for more information.
It does not support altering a table if ALGORITHM is not set to COPY if the table has a VIRTUAL generated
column that is indexed. See 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 is not set to COPY . See 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.
It does not support using the versioning clauses with generated columns.
The SHOW CREATE TABLE statement supports generated columns.
The DESCRIBE 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:

582/3812
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.
Stored procedures support generated columns.
The HANDLER 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 are supported in expressions for generated columns.
However, some built-in functions 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 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 are not supported in expressions for generated columns. See MDEV-17587 for more
information.

MariaDB starting with 10.2.1


In MariaDB 10.2.1 and later, the following statements apply to expressions for generated columns:
Non-deterministic built-in functions are supported in expressions for not indexed VIRTUAL generated columns.
Non-deterministic built-in functions are not supported in expressions for PERSISTENT or indexed VIRTUAL
generated columns.
User-defined functions (UDFs) 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));

MariaDB until 10.2.0


In MariaDB 10.2.0 and before, the following statements apply to expressions for generated columns:
Non-deterministic built-in functions are not supported in expressions for generated columns.
User-defined functions (UDFs) are not supported in expressions for generated columns.
Defining a generated column based on other generated columns defined in the table is not supported.
Otherwise, it would generate errors like this:

ERROR 1900 (HY000): A computed column cannot be based on a computed column

583/3812
Using an expression that exceeds 255 characters in length is not supported in expressions for generated
columns.
Using constant expressions is not supported in expressions for generated columns. Otherwise, it would
generate errors like this:

ERROR 1908 (HY000): Constant expression in computed column function is not allowed

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 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 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 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 flag. To make the value
consistent, use CAST() to ensure that each UNSIGNED operand is SIGNED before the subtraction.

MariaDB starting with 10.5


Beginning in MariaDB 10.5, there is a fatal error generated when trying to create a generated column whose value
can change depending on the SQL Mode 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, MariaDB 10.3.18, and MariaDB 10.2.27 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 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:

584/3812
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


MariaDB starting with 10.2.1
In MariaDB 10.2.1 and later, the following statements apply to MySQL compatibility for generated columns:
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 can be imported into
MariaDB without a dump and restore.

MariaDB until 10.2.0


In MariaDB 10.2.0 and before, the following statements apply to MySQL compatibility for generated columns:
The STORED keyword is not supported as an alias for the PERSISTENT keyword.
Tables created with MySQL 5.7 or later that contain MySQL's generated columns can not 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 implementation:
MariaDB allows server variables in generated column expressions, including those that change dynamically, such
as warning_count.
MariaDB allows the CONVERT_TZ() function to be called with a named time zone as an argument, even though
time zone names and time offsets are configurable.
MariaDB allows the CAST() function to be used with non-unicode character sets, even though character sets are
configurable and differ between binaries/versions.
MariaDB allows FLOAT 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 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. In MariaDB, if data is inserted without
ANSI_QUOTES set in sql_mode, then it will be processed and stored differently in a generated column that
contains quoted identifiers.
In MariaDB 10.2.0 and before, it does not allow user-defined functions (UDFs) to be used in expressions for
generated columns.
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, 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,
585/3812
then please be aware that the generated column expression might not be evaluated the same way as it previously was.
In MariaDB 5.2 , you will get a warning if you try to update a virtual column. In MariaDB 5.3 and later, this warning will
be converted to an error if strict mode is enabled in sql_mode.

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 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)

586/3812
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.

See Also
Putting Virtual Columns to good use on the mariadb.com blog.

1.1.1.3.1.20 Invisible Columns


MariaDB starting with 10.3.3
Invisible columns (sometimes also called hidden columns) first appeared in MariaDB 10.3.3.

Columns can be given an INVISIBLE attribute in a CREATE TABLE or ALTER TABLE statement. These columns will
then not be listed in the results of a SELECT * statement, nor do they need to be assigned a value in an INSERT
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

587/3812
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:

588/3812
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 |
+------+-------+

1.1.1.3.2 ALTER
1.1.1.3.2.1 ALTER TABLE
1.1.1.3.2.2 ALTER DATABASE
1.1.1.3.2.3 ALTER EVENT
1.1.1.3.2.4 ALTER FUNCTION
1.1.1.3.2.5 ALTER LOGFILE GROUP
1.1.1.3.2.6 ALTER PROCEDURE
1.1.1.3.2.7 ALTER SEQUENCE
1.1.1.3.2.8 ALTER SERVER
1.1.1.3.2.9 ALTER TABLESPACE
1.1.1.3.2.10 ALTER USER
1.1.1.3.2.11 ALTER VIEW
1.1.1.3.3 DROP
Articles on various DROP commands.
DROP DATABASE
Drop all tables and delete database.

589/3812
DROP EVENT
Removes an existing event.

DROP FUNCTION
Drop a stored function.

DROP FUNCTION UDF


Drop a user-defined function.

DROP INDEX
Drops an index from a table.

DROP LOGFILE GROUP


The DROP LOGFILE GROUP statement is not supported by MariaDB. It was origin...

DROP PACKAGE
Drops a stored package entirely.

DROP PACKAGE BODY


Drops a package body (i.e the implementation) previously created using the CREATE PACKAGE BODY.

DROP PROCEDURE
Drop stored procedure.

DROP ROLE
Drop a role.

DROP SEQUENCE
Deleting a SEQUENCE.

DROP SERVER
Dropping a server definition.

DROP TABLE
Removes definition and data from one or more tables.

DROP TABLESPACE
DROP TABLESPACE is not available in MariaDB.

DROP TRIGGER
1 Drops a trigger.

DROP USER
1 Remove one or more MariaDB accounts.

DROP VIEW
Removes one or more views.

There are 1 related questions .

1.1.1.3.3.1 DROP DATABASE


Syntax
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

Contents
1. Syntax
2. Description
1. IF EXISTS
2. Atomic DDL
3. Examples
4. See Also

590/3812
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 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.

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.

Atomic DDL
MariaDB starting with 10.6.1
MariaDB 10.6.1 supports Atomic DDL.
DROP DATABASE is implemented as

loop over all tables


DROP TABLE table

Each individual DROP TABLE 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
ALTER DATABASE
SHOW DATABASES
Information Schema SCHEMATA Table
SHOW CREATE DATABASE

1.1.1.3.3.2 DROP EVENT


Syntax
DROP EVENT [IF EXISTS] event_name

Description
This statement drops the event 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 .
This statement requires the EVENT privilege. In MySQL 5.1.11 and earlier, an event could be dropped only by its
definer, or by a user having the SUPER privilege.

591/3812
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
CREATE EVENT
SHOW CREATE EVENT
ALTER EVENT

1.1.1.3.3.3 DROP FUNCTION


Syntax
DROP FUNCTION [IF EXISTS] f_name

Contents
1. Syntax
2. Description
1. IF EXISTS
3. Examples
4. See Also

Description
The DROP FUNCTION statement is used to drop a stored function 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 for the routine in order to drop it. If the 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.

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.
For dropping a user-defined functions (UDF), see DROP FUNCTION UDF.

Examples

592/3812
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
Stored Function Overview
CREATE FUNCTION
CREATE FUNCTION UDF
ALTER FUNCTION
SHOW CREATE FUNCTION
SHOW FUNCTION STATUS
Stored Routine Privileges
INFORMATION_SCHEMA ROUTINES Table

1.1.1.3.3.4 DROP FUNCTION UDF


Syntax
DROP FUNCTION [IF EXISTS] function_name

Contents
1. Syntax
2. Description
1. Upgrading a UDF
3. Examples

Description
This statement drops the user-defined function (UDF) named function_name .
To drop a function, you must have the DELETE privilege for the mysql database. This is because DROP FUNCTION
removes the row from the mysql.func system table that records the function's name, type and shared library name.
For dropping a stored function, see DROP FUNCTION.

Upgrading a UDF
To upgrade the UDF's shared library, first run a DROP FUNCTION 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:

593/3812
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 |
+-------+------+------------------------------------------------+

1.1.1.3.3.5 DROP INDEX


Syntax
DROP INDEX [IF EXISTS] index_name ON tbl_name
[WAIT n |NOWAIT]

Contents
1. Syntax
2. Description
3. Privileges
4. Online DDL
5. DROP INDEX IF EXISTS ...
6. WAIT/NOWAIT
7. Progress Reporting
8. See Also

Description
DROP INDEX drops the 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 is active, and this statement will wait until the lock is released.
This is also true for non-transactional tables.
See ALTER TABLE .
Another shortcut, CREATE INDEX , allows the creation of an index.
To remove the primary key, `PRIMARY` must be specified as index_name. Note that the quotes are necessary, because
PRIMARY is a keyword.

Privileges
Executing the DROP INDEX statement requires the INDEX 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 for more information on online DDL with InnoDB.

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
MariaDB starting with 10.3.0
Set the lock wait timeout. See WAIT and NOWAIT.

594/3812
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 mysql client, then the progress report might look like this::

See Also
Getting Started with Indexes
CREATE INDEX
ALTER TABLE

1.1.1.3.3.6 DROP LOGFILE GROUP


The DROP LOGFILE GROUP statement is not supported by MariaDB. It was originally inherited from MySQL NDB
Cluster. See MDEV-19295 for more information.

1.1.1.3.3.7 DROP PACKAGE


MariaDB starting with 10.3.5
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
DROP PACKAGE [IF EXISTS] [ db_name . ] package_name

Contents
1. Syntax
2. Description
3. See Also

Description
The DROP PACKAGE statement can be used when Oracle SQL_MODE is set.
The DROP PACKAGE statement drops a stored package entirely:
Drops the package specification (earlier created using the CREATE PACKAGE statement).
Drops the package implementation, if the implementation was already created using the CREATE PACKAGE
BODY statement.

See Also
SHOW CREATE PACKAGE
CREATE PACKAGE
CREATE PACKAGE BODY
DROP PACKAGE BODY
Oracle SQL_MODE

1.1.1.3.3.8 DROP PACKAGE BODY


MariaDB starting with 10.3.5
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
DROP PACKAGE BODY [IF EXISTS] [ db_name . ] package_name

595/3812
Contents
1. Syntax
2. Description
3. See also

Description
The DROP PACKAGE BODY statement can be used when Oracle SQL_MODE is set.
The DROP PACKAGE BODY statement drops the package body (i.e the implementation), previously created using the
CREATE PACKAGE BODY statement.
Note, DROP PACKAGE BODY drops only the package implementation, but does not drop the package specification. Use
DROP PACKAGE to drop the package entirely (i.e. both implementation and specification).

See also
CREATE PACKAGE
SHOW CREATE PACKAGE
DROP PACKAGE
CREATE PACKAGE BODY
SHOW CREATE PACKAGE BODY
Oracle SQL_MODE

1.1.1.3.3.9 DROP PROCEDURE


Syntax
DROP PROCEDURE [IF EXISTS] sp_name

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
This statement is used to drop a stored procedure. That is, the specified routine is removed from the server along with
all privileges specific to the procedure. You must have the ALTER ROUTINE privilege for the routine. If the
automatic_sp_privileges server system variable is set, that privilege and EXECUTE are granted automatically to the
routine creator - see Stored Routine Privileges.
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 .
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 |
+-------+------+------------------------------------------+

596/3812
See Also
DROP FUNCTION
Stored Procedure Overview
CREATE PROCEDURE
ALTER PROCEDURE
SHOW CREATE PROCEDURE
SHOW PROCEDURE STATUS
Information Schema ROUTINES Table

1.1.1.3.3.10 DROP ROLE


1.1.1.3.3.11 DROP SEQUENCE
1.1.1.3.3.12 DROP SERVER
Syntax
DROP SERVER [ IF EXISTS ] server_name

Contents
1. Syntax
2. Description
1. IF EXISTS
3. Examples
4. See Also

Description
Drops the server definition for the server named server_name. The corresponding row within the mysql.servers table
will be deleted. This statement requires the SUPER privilege or, from MariaDB 10.5.2, the FEDERATED ADMIN
privilege.
Dropping a server for a table does not affect any FederatedX , FEDERATED , Connect or Spider tables that used
this connection information when they were created.
DROP SERVER is not written to the binary log, irrespective of the binary log format being used. From MariaDB 10.1.13
, Galera replicates the CREATE SERVER, ALTER SERVER 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 .

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
ALTER SERVER
Spider Storage Engine
FederatedX Storage Engine

597/3812
Connect Storage Engine

1.1.1.3.3.13 DROP TABLE


1.1.1.3.3.14 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 for more information.

1.1.1.3.3.15 DROP TRIGGER


Syntax
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name

Contents
1. Syntax
2. Description
1. Atomic DDL
3. Examples
4. See Also

Description
This statement drops a trigger. 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.
Note: Triggers for a table are also dropped if you drop the table.

Atomic DDL
MariaDB starting with 10.6.1
MariaDB 10.6.1 supports Atomic DDL 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
CREATE TRIGGER
Information Schema TRIGGERS Table
SHOW TRIGGERS
598/3812
SHOW CREATE TRIGGER
Trigger Limitations

1.1.1.3.3.16 DROP USER


1.1.1.3.3.17 DROP VIEW
Syntax
DROP VIEW [IF EXISTS]
view_name [, view_name] ...
[RESTRICT | CASCADE]

Contents
1. Syntax
2. Description
1. Atomic DDL
3. Examples
4. See Also

Description
DROP VIEW removes one or more views. 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.
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 for details.
The DROP privilege 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.


Note that it is not necessary to use DROP VIEW to replace an existing view, because CREATE VIEW has an OR REPLACE
clause.

Atomic DDL
MariaDB starting with 10.6.1
MariaDB 10.6.1 supports Atomic DDL 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'

599/3812
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
ALTER VIEW
SHOW CREATE VIEWS
INFORMATION SCHEMA VIEWS Table

1.1.1.3.4 Atomic DDL


From MariaDB 10.6.1, 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 ) allows it to work with all storage engines.

Definitions
Atomic means that either the operation succeeds (and is logged to the binary log 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, except when used with CREATE OR REPLACE, which is only crash safe.
RENAME TABLE and RENAME TABLES.
CREATE VIEW
CREATE SEQUENCE
CREATE TRIGGER
DROP TRIGGER
DROP TABLE and DROP VIEW. Dropping multiple tables is only crash safe.
ALTER TABLE
ALTER SEQUENCE 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 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 is implemented as:

600/3812
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 is implemented as:

loop over all tables


DROP TABLE table

Each DROP TABLE is atomic, but in case of a crash, things will work the same way as DROP TABLE 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.
The partitioning engine. 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 ( 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 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 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.

See Also
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.

601/3812
1.1.1.3.5 CONSTRAINT
MariaDB supports the implementation of constraints at the table-level using either CREATE TABLE or ALTER TABLE
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

Contents
1. Syntax
2. Description
1. FOREIGN KEY Constraints
2. CHECK Constraints
3. Replication
4. Auto_increment
3. Examples
4. See Also

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 contains information about tables that have constraints.

FOREIGN KEY Constraints


InnoDB supports foreign key constraints. The syntax for a foreign key constraint definition in InnoDB looks like this:

602/3812
[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 table has more information about foreign keys.

CHECK Constraints
MariaDB starting with 10.2.1
From MariaDB 10.2.1 , constraints are enforced. Before MariaDB 10.2.1 constraint expressions were accepted in
the syntax but ignored.

In MariaDB 10.2.1 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.

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.
One can disable all constraint expression checks by setting the 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 replication, only the master checks constraints, and failed statements will not be replicated. In statement-
based replication, the slaves will also check constraints. Constraints should therefore be identical, as well as
deterministic, in a replication environment.

Auto_increment
MariaDB starting with 10.2.6
From MariaDB 10.2.6 , auto_increment columns are no longer permitted in check constraints. Previously they
were permitted, but would not work correctly. See 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;

MariaDB starting with 10.2.1

603/3812
The following examples will work from MariaDB 10.2.1 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

1.1.1.3.6 MERGE
1.1.1.3.7 RENAME TABLE
1.1.1.3.8 TRUNCATE TABLE
604/3812
1.1.1.4 Data Manipulation
SQL commands for querying and manipulating data, such as SELECT, UPDATE, DELETE etc.
Selecting Data
Documentation on the SELECT statement and related clauses.

Inserting & Loading Data


Documentation on the INSERT statement and related clauses.

Changing & Deleting Data


Documentation on the UPDATE, REPLACE, and DELETE Statements.

There are 3 related questions .

1.1.1.4.1 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.
SELECT
6 SQL statement used primarily for retrieving data from a MariaDB database.

Joins & Subqueries


Documentation on the JOIN, UNION, EXCEPT and INTERSECT clauses, and on subqueries.

LIMIT
1 Documentation of the LIMIT clause.

ORDER BY
1 Order the results returned from a resultset.

GROUP BY
Aggregate data in a SELECT statement with the GROUP BY clause.

Common Table Expressions


Common table expressions are temporary named result sets

SELECT WITH ROLLUP


2 Adds extra rows to the resultset that represent super-aggregate summaries

SELECT INTO OUTFILE


Write the resultset to a formatted file

SELECT INTO DUMPFILE


Write a binary string into file

FOR UPDATE
1 Acquires a lock on the rows

LOCK IN SHARE MODE


Acquires a write lock.

Optimizer Hints
Optimizer hints There are some options available in SELECT to affect the ex...

PROCEDURE
The PROCEDURE Clause of the SELECT Statement.

HANDLER
Direct access to reading rows from the storage engine.

DUAL
Dummy table name

SELECT ... OFFSET ... FETCH


Allows one to specify an offset, a number of rows to be returned, and wheth...
605/3812
There are 1 related questions .

606/3812
1.1.1.4.1.1 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]

Contents
1. Syntax
2. Description
1. Select Expressions
2. DISTINCT
3. INTO
4. LIMIT
5. LOCK IN SHARE MODE/FOR
UPDATE
6. OFFSET ... FETCH
7. ORDER BY
8. PARTITION
9. PROCEDURE
10. SKIP LOCKED
11. SQL_CALC_FOUND_ROWS
12. max_statement_time clause
13. WAIT/NOWAIT
3. Examples
4. See Also

Description
SELECT is used to retrieve rows selected from one or more tables, and can include UNION statements and subqueries.

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 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 for details. If no table is involved, FROM DUAL can be specified.
Each table can also be specified as db_name . tabl_name . Each column can also be specified as

607/3812
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 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 and Functions and Modifiers for use with
GROUP BY (aggregate).
Use the ORDER BY clause to order the results.
Use the LIMIT clause allows you to restrict the results to only a certain number of rows, optionally with an offset.
Use the GROUP BY 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.
* 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 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 and
SELECT UNIQUE in Oracle mode.

INTO
The INTO clause is used to specify that the query results should be written to a file or variable.
SELECT INTO OUTFILE - formatting and writing the result to an external file.
SELECT INTO DUMPFILE - binary-safe writing of the unformatted results to an external file.
SELECT INTO Variable - selecting and setting variables.
The reverse of SELECT INTO OUTFILE is LOAD DATA.

LIMIT
Restricts the number of returned rows. See LIMIT and LIMIT ROWS EXAMINED for details.

LOCK IN SHARE MODE/FOR UPDATE


See LOCK IN SHARE MODE and FOR UPDATE for details on the respective locking clauses.

OFFSET ... FETCH


MariaDB starting with 10.6
See SELECT ... OFFSET ... FETCH.

ORDER BY
608/3812
Order a resultset. See ORDER BY 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 for details.

PROCEDURE
Passes the whole result set to a C Procedure. See PROCEDURE and PROCEDURE ANALYSE (the only built-in
procedure not requiring the server to be recompiled).

SKIP LOCKED
MariaDB starting with 10.6
The SKIP LOCKED clause was introduced in MariaDB 10.6.0.
This causes those rows that couldn't be locked (LOCK IN SHARE MODE or FOR UPDATE) to be excluded from the
result set. An explicit NOWAIT is implied here. This is only implemented on InnoDB 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 clause. The result can be found by calling the function FOUND_ROWS() in your next sql
statement.

max_statement_time clause
By using max_statement_time in conjunction with SET STATEMENT, 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.

Examples
SELECT f1,f2 FROM t1 WHERE (f3<=10) AND (f4='y');

See Getting Data from MariaDB (Beginner tutorial), or the various sub-articles, for more examples.

See Also
Getting Data from MariaDB (Beginner tutorial)
Joins and Subqueries
LIMIT
ORDER BY
GROUP BY
Common Table Expressions
SELECT WITH ROLLUP
SELECT INTO OUTFILE
SELECT INTO DUMPFILE
FOR UPDATE
LOCK IN SHARE MODE
Optimizer Hints
Oracle mode from MariaDB 10.3

1.1.1.4.1.2 Joins & Subqueries


Documentation on the JOIN, UNION, EXCEPT and INTERSECT clauses, and on subqueries.
609/3812
Joins
Querying from multiple tables.

Subqueries
Queries within queries.

UNION
Combine the results from multiple SELECT statements into a single result set.

EXCEPT
1 Subtraction of two result sets.

INTERSECT
Records that are present in both result sets will be included in the result of the operation.

Precedence Control in Table Operations


Controlling order of execution in SELECT, UNION, EXCEPT, and INTERSECT.

MINUS
Synonym for EXCEPT.

1.1.1.4.1.2.1 Joins
Articles about joins in MariaDB.
Joining Tables with JOIN Clauses
An introductory tutorial on using the JOIN clause.

More Advanced Joins


A more advanced tutorial on JOINs.

JOIN Syntax
1 Description MariaDB supports the following JOIN syntaxes for the table_refe...

Comma vs JOIN
A query to grab the list of phone numbers for clients who ordered in the la...

There are 1 related questions .

1.1.1.4.1.2.1.1 Joining Tables with JOIN


Clauses
1.1.1.4.1.2.1.2 More Advanced Joins
Contents
1. The Employee Database
2. Working with the Employee Database
1. Filtering by Name
2. Filtering by Name, Date and Time
3. Displaying Total Work Hours per Day
3. See Also

This article is a follow up to the Introduction to JOINs 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:

610/3812
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":

611/3812
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):

612/3812
+----+------------+-----------+---------------------+---------------------+-------------+
| 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

The first version of this article was copied, with permission, from http://hashmysql.org/wiki/More_Advanced_Joins on 2012-10-05.

1.1.1.4.1.2.1.3 JOIN Syntax


Description
MariaDB supports the following JOIN syntaxes for the table_references part of SELECT statements and multiple-
table DELETE and UPDATE statements:

613/3812
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 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 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.
614/3812
Examples
SELECT left_tbl.*
FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
WHERE right_tbl.id IS NULL;

1.1.1.4.1.2.1.4 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" — 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.

1.1.1.4.1.2.2 Subqueries
A subquery is a query nested in another query.
Scalar Subqueries
Subquery returning a single value.

Row Subqueries
Subquery returning a row.

Subqueries and ALL


Return true if the comparison returns true for each row, or the subquery returns no rows.

Subqueries and ANY


Return true if the comparison returns true for at least one row returned by the subquery.

615/3812
Subqueries and EXISTS
Returns true if the subquery returns any rows.

Subqueries in a FROM Clause


1 Subqueries are more commonly placed in a WHERE clause, but can also form part of the FROM clause.

Subquery Optimizations
Articles about subquery optimizations in MariaDB.

Subqueries and JOINs


Rewriting subqueries as JOINs, and using subqueries instead of JOINs.

Subquery Limitations
There are a number of limitations regarding subqueries.

There are 1 related questions .

1.1.1.4.1.2.2.1 Scalar Subqueries


A scalar subquery is a subquery 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 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 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:

616/3812
SELECT * FROM sq1 WHERE num = (SELECT MAX(num)/10 FROM sq2);
+------+
| num |
+------+
| 1 |
+------+

1.1.1.4.1.2.2.2 Row Subqueries


A row subquery is a subquery returning a single row, as opposed to a scalar subquery, 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 |
+----------+------+

1.1.1.4.1.2.2.3 Subqueries and ALL


Contents
1. Syntax
2. Examples

Subqueries 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
617/3812
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);

1.1.1.4.1.2.2.4 Subqueries and ANY


Contents
1. Syntax
2. Examples

Subqueries 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>

618/3812
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 |
+------+

1.1.1.4.1.2.2.5 Subqueries and EXISTS


619/3812
Syntax
SELECT ... WHERE EXISTS <Table subquery>

Description
Subqueries 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 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)

1.1.1.4.1.2.2.6 Subqueries in a FROM Clause


Although subqueries 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
From MariaDB 10.6.0, anonymous subqueries in a FROM clause (no AS clause) are permitted in ORACLE mode.

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:
620/3812
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 in ORACLE mode, the following is permitted:

SELECT * FROM (SELECT 1 FROM DUAL), (SELECT 2 FROM DUAL);

1.1.1.4.1.2.2.7 Subquery Optimizations


1.1.1.4.1.2.2.7.1 Subquery Optimizations Map
1.1.1.4.1.2.2.7.2 Semi-join Subquery
Optimizations
1.1.1.4.1.2.2.7.3 Table Pullout Optimization
1.1.1.4.1.2.2.7.4 Non-semi-join Subquery
Optimizations
1.1.1.4.1.2.2.7.5 Subquery Cache
1.1.1.4.1.2.2.7.6 Condition Pushdown Into IN
subqueries
1.1.1.4.1.2.2.7.7 Conversion of Big IN
Predicates Into Subqueries
1.1.1.4.1.2.2.7.8 EXISTS-to-IN Optimization
1.1.1.4.1.2.2.7.9 Optimizing GROUP BY and
DISTINCE Clauses in Subqueries
1.1.1.4.1.2.2.8 Subqueries and JOINs
A subquery can quite often, but not in all cases, be rewritten as a JOIN.

Contents
1. Rewriting Subqueries as JOINS
2. Using Subqueries instead of JOINS

Rewriting Subqueries as JOINS


A subquery using IN can be rewritten with the DISTINCT keyword, for example:

621/3812
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:

622/3812
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).

1.1.1.4.1.2.2.9 Subquery Limitations


Contents
1. ORDER BY and LIMIT
2. Modifying and Selecting from the Same
Table
3. Row Comparison Operations
4. Correlated Subqueries
5. Stored Functions

There are a number of limitations regarding subqueries, 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 or limit LIMIT in subqueries 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:

623/3812
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 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, as there could be different results
on the master and the slave.

1.1.1.4.1.2.3 UNION
UNION is used to combine the results from multiple SELECT 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}]

624/3812
Contents
1. Syntax
2. Description
1. ALL/DISTINCT
2. ORDER BY and LIMIT
3. HIGH_PRIORITY
4. SELECT ... INTO ...
5. Parentheses
3. Examples
4. See Also

Description
UNION is used to combine the results from multiple SELECT 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 - see
MDEV-12325 .
Table names can be specified as db_name . tbl_name . This permits writing UNION s which involve multiple databases.
See Identifier Qualifiers for syntax details.
UNION queries cannot be used with aggregate functions.
EXCEPT and UNION have the same operation precedence and INTERSECT has a higher precedence, unless running in
Oracle mode, 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


Until MariaDB 10.1.1 , all UNION ALL statements required the server to create a temporary table. Since MariaDB
10.1.1 , the server can in most cases execute UNION ALL without creating a temporary table, improving
performance (see MDEV-334 ).

ORDER BY and LIMIT


Individual SELECTs can contain their own ORDER BY and LIMIT 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 and LIMIT 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 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 or INTO OUTFILE. 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 can also be used.

MariaDB starting with 10.4.0


625/3812
Parentheses
From MariaDB 10.4.0, 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, '[email protected]' 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 and INTERSECT. INTERSECT ALL and EXCEPT ALL are available from MariaDB
10.5.0.

626/3812
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

627/3812
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
EXCEPT
INTERSECT
Recursive Common Table Expressions Overview
Get Set for Set Theory: UNION, INTERSECT and EXCEPT in SQL (video tutorial)

1.1.1.4.1.2.4 EXCEPT
MariaDB starting with 10.3.0
EXCEPT was introduced in MariaDB 10.3.0.

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, MINUS is a synonym.

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}]

Contents
1. Syntax
1. Description
1. Parentheses
2. ALL/DISTINCT
2. Examples
3. See Also

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 in addition to UNION since MariaDB 10.3.
All behavior for naming columns, ORDER BY and LIMIT is the same as for UNION .
628/3812
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, in which case all three have the same precedence.

MariaDB starting with 10.4.0

Parentheses
From MariaDB 10.4.0, parentheses can be used to specify precedence. Before this, a syntax error would be returned.

MariaDB starting with 10.5.0

ALL/DISTINCT
EXCEPT ALL and EXCEPT DISTINCT were introduced in MariaDB 10.5.0. 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.

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, EXCEPT and INTERSECT. INTERSECT ALL and EXCEPT ALL are available from MariaDB
10.5.0.

629/3812
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

630/3812
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 |
+------+

See Also
UNION
INTERSECT
Get Set for Set Theory: UNION, INTERSECT and EXCEPT in SQL (video tutorial)

1.1.1.4.1.2.5 INTERSECT
MariaDB starting with 10.3.0
INTERSECT was introduced in MariaDB 10.3.0.

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}]

Contents
1. Syntax
2. Description
1. Parentheses
2. ALL/DISTINCT
3. Examples
4. See Also

Description
MariaDB has supported INTERSECT (as well as EXCEPT) in addition to UNION since MariaDB 10.3.
All behavior for naming columns, ORDER BY and LIMIT is the same as for UNION.
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.

631/3812
INTERSECT has higher precedence than UNION and EXCEPT (unless running running in Oracle mode, 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

Parentheses
From MariaDB 10.4.0, parentheses can be used to specify precedence. Before this, a syntax error would be returned.

MariaDB starting with 10.5.0

ALL/DISTINCT
INTERSECT ALL and INTERSECT DISTINCT were introduced in MariaDB 10.5.0. 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.

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, EXCEPT and INTERSECT. INTERSECT ALL and EXCEPT ALL are available from MariaDB
10.5.0.

632/3812
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

633/3812
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
EXCEPT
Get Set for Set Theory: UNION, INTERSECT and EXCEPT in SQL (video tutorial)

1.1.1.4.1.2.6 Precedence Control in Table


Operations
MariaDB starting with 10.4.0
Beginning in MariaDB 10.4, 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}]

Contents
1. Syntax
2. Description
3. Example

Description
Using parentheses in your SQL allows you to control the order of execution for SELECT statements and Table Value
Constructor, including UNION , EXCEPT , and INTERSECT operations. MariaDB executes the parenthetical expression
before the rest of the statement. You can then use ORDER BY and LIMIT 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

634/3812
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 |
+------+

1.1.1.4.1.2.7 MINUS
MariaDB starting with 10.6.1
MINUS was introduced as a synonym for EXCEPT from MariaDB 10.6.1.

1.1.1.4.1.3 LIMIT
Contents
1. Description
1. Multi-Table Updates
2. GROUP_CONCAT
2. Examples
3. See Also

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 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 with the LIMIT clause is not safe for replication. LIMIT 0 is an exception to this rule (see
MDEV-6170 ).
There is a LIMIT ROWS EXAMINED optimization which provides the means to terminate the execution of SELECT
statements which examine too many rows, and thus use too many resources. See LIMIT ROWS EXAMINED.

Multi-Table Updates
MariaDB starting with 10.3.2
Until MariaDB 10.3.1, it was not possible to use LIMIT (or ORDER BY) in a multi-table UPDATE statement. This
restriction was lifted in MariaDB 10.3.2.

635/3812
GROUP_CONCAT
MariaDB starting with 10.3.2
Starting from MariaDB 10.3.3, it is possible to use LIMIT with GROUP_CONCAT().

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, LIMIT can be used in a multi-table update:

636/3812
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, LIMIT 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
ROWNUM() function
SELECT
UPDATE
DELETE
Joins and Subqueries
ORDER BY
GROUP BY
Common Table Expressions
SELECT WITH ROLLUP
SELECT INTO OUTFILE
SELECT INTO DUMPFILE
FOR UPDATE
LOCK IN SHARE MODE
Optimizer Hints
SELECT ... OFFSET ... FETCH

637/3812
1.1.1.4.1.4 ORDER BY
Contents
1. Description
2. Examples
3. See Also

Description
Use the ORDER BY clause to order a resultset, such as that are returned from a SELECT 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
nth column in the select expression.
When string values are compared, they are compared as if by the STRCMP function. STRCMP ignores trailing
whitespace and may normalize characters and ignore case, depending on the collation in use.
Duplicated entries in the ORDER BY clause are removed.
ORDER BY can also be used to order the activities of a DELETE or UPDATE statement (usually with the LIMIT clause).

MariaDB starting with 10.3.2


Until MariaDB 10.3.1, it was not possible to use ORDER BY (or LIMIT) in a multi-table UPDATE statement. This
restriction was lifted in MariaDB 10.3.2.

MariaDB starting with 10.5


From MariaDB 10.5, 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

638/3812
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 statement, in conjunction with LIMIT:

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, ORDER BY can be used in a multi-table update:

639/3812
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?
SELECT
UPDATE
DELETE
Improvements to ORDER BY Optimization
Joins and Subqueries
LIMIT
GROUP BY
Common Table Expressions
SELECT WITH ROLLUP
SELECT INTO OUTFILE
SELECT INTO DUMPFILE
FOR UPDATE
LOCK IN SHARE MODE
Optimizer Hints

1.1.1.4.1.5 GROUP BY
Contents
1. WITH ROLLUP
2. GROUP BY Examples
3. See Also

Use the GROUP BY clause in a SELECT 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 except grouping functions.
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 = operator. For string values, the = operator ignores
trailing whitespace and may normalize characters and ignore case, depending on the collation 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 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
nth column in the select expression.

640/3812
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. The
default is ASC .
If you want the rows to be sorted by another field, you can add an explicit ORDER BY. If you don't want the result to be
ordered, you can add ORDER BY NULL.

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.

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 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:

641/3812
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
Joins and Subqueries
LIMIT
ORDER BY
Common Table Expressions
SELECT WITH ROLLUP
SELECT INTO OUTFILE
SELECT INTO DUMPFILE
FOR UPDATE
LOCK IN SHARE MODE
Optimizer Hints

1.1.1.4.1.6 Common Table Expressions


MariaDB starting with 10.2.1
Common table expressions were introduced in MariaDB 10.2.1 .

WITH
4 Allows reference to subqueries as temporary tables within queries.

Non-Recursive Common Table Expressions Overview


1 Common Table Expressions (CTEs) are essentially Temporary Named Result Sets.

Recursive Common Table Expressions Overview


7 A recursive CTE will repeatedly execute subsets of the data until obtaining the complete results

There are 1 related questions .

1.1.1.4.1.6.1 WITH
MariaDB starting with 10.2.1
Common Table Expressions were introduced in MariaDB 10.2.1 .

Syntax
WITH [RECURSIVE] table_reference [(columns_list)] AS (
SELECT ...
)
[CYCLE cycle_column_list RESTRICT]
SELECT ...

Contents
1. Syntax
2. Description
1. CYCLE ... RESTRICT
3. Examples
4. See Also

Description
642/3812
The WITH keyword signifies a Common Table Expression (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
Recursive (signified by the RECURSIVE keyword, supported since MariaDB 10.2.2 )
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 and SELECT.
Poorly-formed recursive CTEs can in theory cause infinite loops. The max_recursive_iterations system variable limits
the number of recursions.

CYCLE ... RESTRICT

MariaDB starting with 10.5.2


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,

643/3812
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 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) 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
Recursive Common Table Expressions Overview

1.1.1.4.1.6.2 Non-Recursive Common Table


Expressions Overview

644/3812
Contents
1. Non-Recursive CTEs
1. A CTE referencing Another CTE
2. Multiple Uses of a CTE

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.

MariaDB starting with 10.2.1


Common table expressions were introduced in MariaDB 10.2.1 .

Non-Recursive CTEs
The WITH keyword signifies a CTE. It is given a name, followed by a body (the main query) as follows:

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. 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:

645/3812
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)

1.1.1.4.1.6.3 Recursive Common Table


Expressions Overview
MariaDB starting with 10.2.2
Recursive Common Table Expressions have been supported since MariaDB 10.2.2 .

Contents
1. Syntax example
2. Computation
3. Summary so far
4. CAST to avoid truncating data
5. Examples
1. Transitive closure - determining bus
destinations
2. Computing paths - determining bus
routes
3. CAST to avoid data truncation

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
Recursive, which this article covers.
SQL is generally poor at recursive structures.

646/3812
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 avoids infinite loops.

Syntax example
WITH RECURSIVE signifies a recursive CTE. It is given a name, followed by a body (the main query) as follows:

Computation
Given the following structure:

First execute the anchor part of the query:

647/3812
Next, execute the recursive part of the query:

648/3812
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 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 . See the examples below.

Examples
Transitive closure - determining bus destinations
Sample data:

649/3812
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:

650/3812
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 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 |
+---------------------+

651/3812
1.1.1.4.1.7 SELECT WITH ROLLUP
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Syntax
See SELECT 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 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. 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:

652/3812
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
653/3812
Joins and Subqueries
LIMIT
ORDER BY
GROUP BY
Common Table Expressions
SELECT INTO OUTFILE
SELECT INTO DUMPFILE
FOR UPDATE
LOCK IN SHARE MODE
Optimizer Hints

1.1.1.4.1.8 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']
]

Contents
1. Syntax
2. Description
1. Character-sets
3. Example
4. See Also

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 privilege to run this statement. Also, MariaDB
needs permission to write files in the specified location. If the 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 statement complements SELECT INTO OUTFILE .

Character-sets
The CHARACTER SET clause specifies the character set 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
statement.

Example
The following example produces a file in the CSV format:

SELECT customer_id, firstname, surname INTO OUTFILE '/exportdata/customers.txt'


FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM customers;

654/3812
See Also
SELECT
LOAD_DATA() function
LOAD DATA INFILE
SELECT INTO Variable
SELECT INTO DUMPFILE

1.1.1.4.1.9 SELECT INTO DUMPFILE


Contents
1. Syntax
2. Description
3. Example
4. See Also

Syntax
SELECT ... INTO DUMPFILE 'file_path'

Description
SELECT ... INTO DUMPFILE is a SELECT 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, 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 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 privilege to run this statement. Also, MariaDB
needs permission to write files in the specified location. If the 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, the 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
LOAD_FILE()
SELECT INTO Variable
SELECT INTO OUTFILE

1.1.1.4.1.10 FOR UPDATE


InnoDB supports row-level locking. Selected rows can be locked using LOCK IN SHARE MODE 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 applies only when 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 ).
If autocommit is set to 1, the LOCK IN SHARE MODE and FOR UPDATE clauses have no effect.
655/3812
If the isolation level is set to 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
LOCK IN SHARE MODE
InnoDB Lock Modes

1.1.1.4.1.11 LOCK IN SHARE MODE


InnoDB supports row-level locking. Selected rows can be locked using LOCK IN SHARE MODE 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.
When LOCK IN SHARE MODE is specified in a SELECT 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 is set to 1, the LOCK IN SHARE MODE and FOR UPDATE clauses have no effect.

See Also
SELECT
FOR UPDATE
InnoDB Lock Modes

1.1.1.4.1.12 Optimizer Hints


Optimizer hints
There are some options available in SELECT 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 for
details.

SQL_CACHE / SQL_NO_CACHE
If the 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 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

656/3812
STRAIGHT_JOIN applies to the JOIN 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().

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.

1.1.1.4.1.13 PROCEDURE
The PROCEDURE clause of SELECT passes the whole result set to a Procedure which will process it. These Procedures
are not Stored Procedures, and can only be written in the C language, so it is necessary to recompile the server.
Currently, the only available procedure is ANALYSE, 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's definition.

See Also
SELECT
Stored Procedures

1.1.1.4.1.14 HANDLER
1.1.1.4.1.15 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 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

1.1.1.4.1.16 SELECT ... OFFSET ... FETCH


MariaDB starting with 10.6.0
SELECT ... OFFSET ... FETCH was introduced in MariaDB 10.6.

657/3812
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 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 clause:

SELECT i FROM t1 ORDER BY i ASC LIMIT 3 OFFSET 1;


+------+
| i |
+------+
| 2 |
| 3 |
| 4 |
+------+

658/3812
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
SELECT

1.1.1.4.2 Inserting & Loading Data


The INSERT statement is the primary SQL statement for adding data into a table in MariaDB.
INSERT
2 Insert rows into a table.

INSERT DELAYED
Queue row to be inserted when thread is free.

INSERT SELECT
1 Insert the rows returned by a SELECT into a table

LOAD Data into Tables or Index


Loading data quickly into MariaDB

Concurrent Inserts
Under some circumstances, MyISAM allows INSERTs and SELECTs to be executed concurrently.

HIGH_PRIORITY and LOW_PRIORITY


Modifying statement priority in storage engines supporting table-level locks.

IGNORE
Suppress errors while trying to violate a UNIQUE constraint.

INSERT - Default & Duplicate Values


Default and duplicate values when inserting.

INSERT IGNORE
Convert errors to warnings, permitting inserts of additional rows to continue.

INSERT ON DUPLICATE KEY UPDATE


2 INSERT if no duplicate key is found, otherwise UPDATE.

INSERT...RETURNING
1 Returns a resultset of the inserted rows.

There are 3 related questions .

1.1.1.4.2.1 INSERT
Syntax

659/3812
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 ...]]

Contents
1. Syntax
2. INSERT DELAYED
3. HIGH PRIORITY and LOW PRIORITY
4. Defaults and Duplicate Values
5. INSERT IGNORE
6. INSERT ON DUPLICATE KEY UPDATE
7. Examples
8. INSERT ... RETURNING
1. Examples
9. See Also

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 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). This allows to use INSERT ... SELECT 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 for
details.

MariaDB starting with 10.5


The RETURNING clause was introduced in MariaDB 10.5.

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 cannot be used. See HIGH_PRIORITY and LOW_PRIORITY clauses for details.

660/3812
INSERT DELAYED
For more details on the DELAYED option, see INSERT DELAYED.

HIGH PRIORITY and LOW PRIORITY


See HIGH_PRIORITY and LOW_PRIORITY.

Defaults and Duplicate Values


See INSERT - Default & Duplicate Values for details..

INSERT IGNORE
See INSERT IGNORE.

INSERT ON DUPLICATE KEY UPDATE


See INSERT ON DUPLICATE KEY UPDATE.

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 and INSERT IGNORE 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


661/3812
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 SELECT
REPLACE Equivalent to DELETE + INSERT of conflicting row.
HIGH_PRIORITY and LOW_PRIORITY
Concurrent Inserts
INSERT - Default & Duplicate Values
INSERT IGNORE
INSERT ON DUPLICATE KEY UPDATE
How to quickly insert data into MariaDB

1.1.1.4.2.2 INSERT DELAYED


Syntax
INSERT DELAYED ...

Contents
1. Syntax
2. Description
1. Limitations
3. See Also

Description
The DELAYED option for the INSERT 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. 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

662/3812
subsequent statements (no error will be produced).

Limitations
There are some limitations on the use of DELAYED :
INSERT DELAYED works only with MyISAM, MEMORY, ARCHIVE, and BLACKHOLE 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() 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.
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.
INSERT DELAYED is not supported within stored programs.
INSERT DELAYED does not work with triggers.
INSERT DELAYED does not work if there is a check constraint in place.
INSERT DELAYED does not work if skip-new mode is active.

See Also
INSERT
INSERT SELECT
HIGH_PRIORITY and LOW_PRIORITY
Concurrent Inserts
INSERT - Default & Duplicate Values
INSERT IGNORE
INSERT ON DUPLICATE KEY UPDATE

1.1.1.4.2.3 INSERT SELECT


Syntax
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

Contents
1. Syntax
2. Description
3. See Also

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). This allows to copy rows
between different databases.
If the new table has a primary key or UNIQUE indexes, you can use IGNORE to handle duplicate key errors during the
663/3812
query. The newer values will not be inserted if an identical value already exists.
REPLACE 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.

See Also
INSERT
INSERT DELAYED
HIGH_PRIORITY and LOW_PRIORITY
Concurrent Inserts
INSERT - Default & Duplicate Values
INSERT IGNORE
INSERT ON DUPLICATE KEY UPDATE

1.1.1.4.2.4 LOAD Data into Tables or Index


Loading data quickly into MariaDB
LOAD DATA INFILE
14 Read rows from a text file into a table.

LOAD INDEX
Loads one or more indexes from one or more MyISAM/Aria tables into a key buffer.

LOAD XML
Load XML data into a table

LOAD_FILE
Returns file contents as a string.

There are 3 related questions .

664/3812
1.1.1.4.2.4.1 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]
[(col_name_or_user_var,...)]
[SET col_name = expr,...]

Contents
1. Syntax
2. Description
1. LOAD DATA LOCAL INFILE
2. REPLACE and IGNORE
3. Character-sets
4. Preprocessing Inputs
5. Priority and Concurrency
6. Progress Reporting
7. Using mariadb-import/mysqlimport
8. Indexing
3. Examples
4. See Also

Description
LOAD DATA INFILE is unsafe 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 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.
One must have the FILE privilege to be able to execute LOAD DATA. This is the ensure the normal users will not
attempt to read system files.
Note that MariaDB's systemd unit file restricts access to /home , /root , and /run/user by default. See 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. In 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.
In the event that you don't want to permit this operation (such as 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 system variable
to 0 .
The LOAD DATA LOCAL INFILE statement can be disabled on the client. If you are using MariaDB Connector/C ,
this can be done by unsetting the CLIENT_LOCAL_FILES capability flag with the mysql_real_connect function or
by unsetting the MYSQL_OPT_LOCAL_INFILE option with mysql_optionsv 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

665/3812
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 for more
information.
From MariaDB 10.5.2, 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


In cases where you load data from a file into a table that already contains data and has a 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. In cases where you want
MariaDB to overwrite duplicates, use the REPLACE keyword.
The REPLACE keyword works like the REPLACE 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. 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 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 statement
and by the 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 mysqldump -T or with the SELECT INTO OUTFILE statement with the mysql 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 and LOAD DATA
INFILE to ensure that MariaDB correctly interprets the escape sequences.

The 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 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, MEMORY and MERGE), using the LOW_PRIORITY
keyword, MariaDB delays insertions until no other clients are reading from the table. Alternatively, when using the
MyISAM storage engine, you can use the CONCURRENT keyword to perform concurrent insertion.

The LOW_PRIORITY and CONCURRENT keywords are mutually exclusive. They cannot be used in the same
statement.

666/3812
Progress Reporting
The LOAD DATA INFILE statement supports progress reporting. You may find this useful when dealing with long-running
operations. Using another client you can issue a SHOW PROCESSLIST query to check the progress of the data load.

Using mariadb-import/mysqlimport
MariaDB ships with a separate utility for loading data from files: mariadb-import (or mysqlimport before MariaDB 10.5).
It operates by sending LOAD DATA INFILE statements to the server.
Using mariadb-import/mysqlimport 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 statements (MyISAM and Aria), 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);


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
Character Sets and Collations
SELECT ... INTO OUTFILE
mariadb-import/mysqlimport

1.1.1.4.2.4.2 LOAD INDEX


667/3812
1.1.1.4.2.4.3 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 mysql client 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> mysql --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 mysqldump.


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 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 keyword is used, insertions are delayed until no other clients are reading from the table. The
CONCURRENT keyword allowes the use of concurrent inserts. These clauses cannot be specified together.
This statement activates INSERT triggers.

See also
668/3812
The CONNECT storage engine has an XML table type.

1.1.1.4.2.4.4 LOAD_FILE
Syntax
LOAD_FILE(file_name)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 system variable. If the 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, the 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. 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

1.1.1.4.2.5 Concurrent Inserts


Contents
1. Notes
2. See Also

The MyISAM storage engine supports concurrent inserts. This feature allows SELECT statements to be executed
during INSERT operations, reducing contention.
Whether concurrent inserts can be used or not depends on the value of the 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). 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 is used, CREATE TABLE ... SELECT and INSERT ... SELECT 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 (see binary log formats).
If an INSERT statement contain the HIGH_PRIORITY clause, concurrent inserts cannot be used. INSERT ... DELAYED
is usually unneeded if concurrent inserts are enabled.
LOAD DATA INFILE uses concurrent inserts if the CONCURRENT keyword is specified and concurrent_insert is not
NEVER . This makes the statement slower (even if no other sessions access the table) but reduces contention.
LOCK TABLES allows non-conflicting concurrent inserts if a READ LOCAL lock is used. Concurrent inserts are not
allowed if the LOCAL keyword is omitted.
669/3812
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 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 after setting the variable.

See Also
INSERT
INSERT DELAYED
INSERT SELECT
HIGH_PRIORITY and LOW_PRIORITY
INSERT - Default & Duplicate Values
INSERT IGNORE
INSERT ON DUPLICATE KEY UPDATE

1.1.1.4.2.6 HIGH_PRIORITY and


LOW_PRIORITY
Contents
1. See Also

The InnoDB storage engine uses row-level locking to ensure data integrity. However some storage engines (such as
MEMORY, MyISAM, Aria and MERGE) lock the whole table to prevent conflicts. These storage engines use two
separate queues to remember pending statements; one is for SELECTs and the other one is for write statements
(INSERT, DELETE, UPDATE). By default, the latter has a higher priority.
To give write operations a lower priority, the 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 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 variable, which is dynamic.
If write statements have a higher priority (default), the priority of individual write statements (INSERT, REPLACE,
UPDATE, DELETE) 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 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 from being used.

See Also
INSERT
INSERT DELAYED
INSERT SELECT
Concurrent Inserts
INSERT - Default & Duplicate Values
INSERT IGNORE
INSERT ON DUPLICATE KEY UPDATE

1.1.1.4.2.7 IGNORE
1.1.1.4.2.8 INSERT - Default & Duplicate
Values
Contents
1. Default Values
2. Duplicate Values
3. See Also

Default Values
670/3812
If the SQL_MODE contains STRICT_TRANS_TABLES and you are inserting 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) 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 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() 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 clause, INSERT ON DUPLICATE KEY UPDATE or the REPLACE
statement. Note that the IGNORE and DELAYED options are ignored when you use ON DUPLICATE KEY UPDATE.

See Also
INSERT
INSERT DELAYED
INSERT SELECT
HIGH_PRIORITY and LOW_PRIORITY
Concurrent Inserts
INSERT IGNORE
INSERT ON DUPLICATE KEY UPDATE

1.1.1.4.2.9 INSERT IGNORE


Contents
1. Ignoring Errors
2. Examples
3. See Also

Ignoring Errors
Normally INSERT stops and rolls back when it encounters an error.
By using the IGNORE keyword all errors are converted to warnings, which will not stop inserts of additional rows.
The IGNORE and DELAYED options are ignored when you use ON DUPLICATE KEY UPDATE.
Prior to MySQL and MariaDB 5.5.28 , no warnings were issued for duplicate key errors when using IGNORE . You can
get the old behavior if you set OLD_MODE to NO_DUP_KEY_WARNINGS_WITH_IGNORE .

Examples

671/3812
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 |
+------+
2 rows in set (0.00 sec)

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 |
+------+

See INSERT ON DUPLICATE KEY UPDATE for further examples using that syntax.

See Also
INSERT
INSERT DELAYED
INSERT SELECT
HIGH_PRIORITY and LOW_PRIORITY
Concurrent Inserts
INSERT - Default & Duplicate Values
INSERT IGNORE
INSERT ON DUPLICATE KEY UPDATE

1.1.1.4.2.10 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:

672/3812
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col=expr
[, col=expr] ... ]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
INSERT ... ON DUPLICATE KEY UPDATE is a MariaDB/MySQL extension to the INSERT statement that, if it finds a
duplicate unique or primary key, will instead perform an UPDATE.
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 primary key and the statement inserts or updates a row, the
LAST_INSERT_ID() function returns its AUTO_INCREMENT value.
The VALUES() 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 and DELAYED options are ignored when you use ON DUPLICATE KEY UPDATE .
See Partition Pruning and Selection for details on the PARTITION clause.
This statement activates INSERT and UPDATE triggers. See Trigger Overview for details.
See also a similar statement, REPLACE.

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.

673/3812
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.

674/3812
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() function for more.

See Also
INSERT
INSERT DELAYED
INSERT SELECT
HIGH_PRIORITY and LOW_PRIORITY
Concurrent Inserts
INSERT - Default & Duplicate Values
INSERT IGNORE
VALUES()

1.1.1.4.2.11 INSERT...RETURNING
MariaDB starting with 10.5.0
INSERT ... RETURNING was added in MariaDB 10.5.0, and returns a resultset of the inserted rows.

Syntax

675/3812
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 ...]]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
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 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

676/3812
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
REPLACE ... RETURNING
DELETE ... RETURNING
Returning clause (video)

1.1.1.4.3 Changing & Deleting Data


DELETE
2 Delete rows from one or more tables.

HIGH_PRIORITY and LOW_PRIORITY


Modifying statement priority in storage engines supporting table-level locks.

IGNORE
Suppress errors while trying to violate a UNIQUE constraint.

REPLACE
1 Equivalent to DELETE + INSERT, or just an INSERT if no rows are returned.

REPLACE...RETURNING
Returns a resultset of the replaced rows.

TRUNCATE TABLE
DROP and re-CREATE a table.

UPDATE
2 Modify rows in one or more tables.

1.1.1.4.3.1 DELETE
1.1.1.4.3.2 HIGH_PRIORITY and
LOW_PRIORITY
1.1.1.4.3.3 IGNORE
1.1.1.4.3.4 REPLACE
1.1.1.4.3.5 REPLACE...RETURNING
677/3812
MariaDB starting with 10.5.0
REPLACE ... RETURNING was added in MariaDB 10.5.0, 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 ...]]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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

678/3812
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
DELETE ... RETURNING
Returning clause (video)

1.1.1.4.3.6 TRUNCATE TABLE


1.1.1.4.3.7 UPDATE
1.1.1.5 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, execute with EXECUTE, and release it with DEALLOCATE .
PREPARE Statement
3 Define a prepare statement.

EXECUTE Statement
Executes a previously PREPAREd statement

DEALLOCATE / DROP PREPARE


Deallocates a prepared statement.

EXECUTE IMMEDIATE
Immediately execute a dynamic SQL statement

Out Parameters in PREPARE


3 Using question mark placeholders for out-parameters in the PREPARE statement

There are 1 related questions .

679/3812
1.1.1.5.1 PREPARE Statement
Syntax
PREPARE stmt_name FROM preparable_stmt

Contents
1. Syntax
2. Description
1. Oracle Mode
3. Permitted Statements
4. Example
5. See Also

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 (not a local
variable, 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, but not local variables 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() and ROW_COUNT() 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 return
information about them. DEALLOCATE PREPARE shouldn't clear the diagnostics area , unless it produces an error.
A prepared statement is executed with EXECUTE and released with DEALLOCATE PREPARE .
The 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
In Oracle mode from MariaDB 10.3, PREPARE stmt FROM 'SELECT :1, :2' is used, instead of ? .

Permitted Statements
680/3812
MariaDB starting with 10.6.2
All statements can be prepared, except PREPARE, EXECUTE, and DEALLOCATE / DROP PREPARE.

Prior to this, not all statements can be prepared. Only the following SQL commands are permitted:
ALTER TABLE
ANALYZE TABLE
BINLOG
CACHE INDEX
CALL
CHANGE MASTER
CHECKSUM {TABLE | TABLES}
COMMIT
{CREATE | DROP} DATABASE
{CREATE | DROP} INDEX
{CREATE | RENAME | DROP} TABLE
{CREATE | RENAME | DROP} USER
{CREATE | DROP} VIEW
DELETE
DESCRIBE
DO
EXPLAIN
FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER
| SLAVE | DES_KEY_FILE | USER_RESOURCES | QUERY CACHE | TABLE_STATISTICS |
INDEX_STATISTICS | USER_STATISTICS | CLIENT_STATISTICS}
GRANT
INSERT
INSTALL {PLUGIN | SONAME}
HANDLER READ
KILL
LOAD INDEX INTO CACHE
OPTIMIZE TABLE
REPAIR TABLE
REPLACE
RESET {MASTER | SLAVE | QUERY CACHE}
REVOKE
ROLLBACK
SELECT
SET
SET GLOBAL SQL_SLAVE_SKIP_COUNTER
SET ROLE
SET SQL_LOG_BIN
SET TRANSACTION ISOLATION LEVEL
SHOW EXPLAIN
SHOW {DATABASES | TABLES | OPEN TABLES | TABLE STATUS | COLUMNS | INDEX | TRIGGERS |
EVENTS | GRANTS | CHARACTER SET | COLLATION | ENGINES | PLUGINS [SONAME] | PRIVILEGES |
PROCESSLIST | PROFILE | PROFILES | VARIABLES | STATUS | WARNINGS | ERRORS |
TABLE_STATISTICS | INDEX_STATISTICS | USER_STATISTICS | CLIENT_STATISTICS | AUTHORS |
CONTRIBUTORS}
SHOW CREATE {DATABASE | TABLE | VIEW | PROCEDURE | FUNCTION | TRIGGER | EVENT}
SHOW {FUNCTION | PROCEDURE} CODE
SHOW BINLOG EVENTS
SHOW SLAVE HOSTS
SHOW {MASTER | BINARY} LOGS
SHOW {MASTER | SLAVE | TABLES | INNODB | FUNCTION | PROCEDURE} STATUS
SLAVE {START | STOP}
TRUNCATE TABLE
SHUTDOWN
UNINSTALL {PLUGIN | SONAME}
UPDATE
Synonyms are not listed here, but can be used. For example, DESC can be used instead of DESCRIBE.
Compound statements 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 can't be directly prepared. However, it is allowed in stored routines. 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);

681/3812
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
EXECUTE Statement
DEALLOCATE / DROP Prepared Statement
EXECUTE IMMEDIATE
682/3812
Oracle mode from MariaDB 10.3

1.1.1.5.2 Out Parameters in PREPARE


MariaDB 10.1.1
Out parameters in PREPARE were only available in MariaDB 10.1.1

One can use question mark placeholders for out-parameters in the PREPARE statement. Only SELECT … 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:

PREPARE stmt FROM "BEGIN NOT ATOMIC


DECLARE v_res INT;
SELECT COUNT(*) INTO v_res FROM t1;
SELECT 'Hello World', v_res INTO ?,?;
END"|

1.1.1.5.3 EXECUTE STATEMENT


1.1.1.5.4 DEALLOCATE / DROP PREPARE
Syntax
{DEALLOCATE | DROP} PREPARE stmt_name

Description
To deallocate a prepared statement produced with PREPARE , 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.

See Also
PREPARE Statement
EXECUTE Statement
EXECUTE IMMEDIATE

1.1.1.5.5 EXECUTE IMMEDIATE


MariaDB starting with 10.2.3
EXECUTE IMMEDIATE was introduced in MariaDB 10.2.3 .

683/3812
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

684/3812
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 status variable, as well as the Com_stmt_prepare,
Com_stmt_execute and Com_stmt_close status variables.
Note, EXECUTE IMMEDIATE does not increment the Com_execute_sql status variable. Com_execute_sql is used only
for PREPARE..EXECUTE.
This session screenshot demonstrates how EXECUTE IMMEDIATE affects status variables:

685/3812
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 |
+-----------------------+----------------+

1.1.1.6 Programmatic & Compound Statements


Compound statements in MariaDB can be used both inside and outside of stored programs.
Using Compound Statements Outside of Stored Programs
Compound statements are not just for stored programs.

BEGIN END
2 How to write compound statements.

CASE Statement
1 Conditional construct with multiple choices.

DECLARE CONDITION
For declaring a named error condition (SQLSTATE or error code).

DECLARE HANDLER
Construct to declare how errors are handled.

DECLARE Variable
1 Declare local variables within stored programs.

FOR
1 FOR loops allow code to be executed a fixed number of times.

GOTO
Jump to the given label.

IF
4 A basic conditional construct statement.

ITERATE
Used to repeat the execution of the current loop.

Labels
Identifiers used to identify a BEGIN ... END construct.

LEAVE
Used to exit a code block.

686/3812
LOOP
Used to loop within a code block without a condition.

REPEAT LOOP
Used to repeat statements until a search condition is true.

RESIGNAL
Used to send a SIGNAL again for the previous error.

RETURN
Statement to terminate execution of a stored function and return a value.

SELECT INTO
SQL statement for inserting values into variables.

SET Variable
1 Used to insert a value into a variable with a code block.

SIGNAL
May be used to produce a custom error message.

WHILE
Used to repeat a block of SQL statements while a search condition is true.

Cursors
Structure for traversing and processing results, sequentially.

Diagnostics
Error conditions and statement information.

1.1.1.6.1 Using Compound Statements Outside


of Stored Programs
Compound statements can also be used outside of stored programs.

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, IF, CASE, LOOP, WHILE, REPEAT statements may start a compound statement outside of stored
programs.
BEGIN must use the BEGIN NOT ATOMIC syntax (otherwise it'll be confused with BEGIN 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 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|

687/3812
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 ;

1.1.1.6.2 BEGIN END


Syntax
[begin_label:] BEGIN [NOT ATOMIC]
[statement_list]
END [end_label]

Contents
1. Syntax
2. Description
3. See Also

NOT ATOMIC is required when used outside of a stored procedure. 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 mode, every statement will be committed
separately. If you are not running in autocommit mode, you must execute a COMMIT or ROLLBACK 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 command-line client with the DELIMITER 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 can be labeled. 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, 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 CONDITION s;
DECLARE CURSOR s;
DECLARE HANDLER s;
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|

688/3812
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 variable, x is declared in the outter block. But in the inner block x is re-declared as a
CHAR and an y variable is declared. The inner SELECT 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 doesn't try to read y , because it doesn't
exist in that context.

See Also
Using compound statements outside of stored programs
Changes in Oracle mode from MariaDB 10.3

1.1.1.6.3 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. See the CASE OPERATOR for details on the
CASE operator outside of stored programs.
The CASE statement for stored programs 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 block, as shown in
this example:

689/3812
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 mysql client 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. The CASE statement cannot have an ELSE NULL clause, and it is
terminated with END CASE instead of END .

1.1.1.6.4 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, SIGNAL
or RESIGNAL statement (as long as the statement is located in the same BEGIN ... END block).
Conditions must be declared after local variables, but before CURSORs and HANDLERs.
A condition_value for DECLARE ... CONDITION can be an SQLSTATE 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.

1.1.1.6.5 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

690/3812
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.

Handlers must be declared after local variables, a CONDITION and a CURSOR.


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 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 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.
A condition name previously specified with DECLARE ... CONDITION . It must be in the same stored program. See
DECLARE CONDITION.
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. This condition also occurs
for SELECT ... INTO 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 statement.
An error that is handled by a DECLARE HANDLER construct can be issued again using the RESIGNAL statement.
Below is an example using DECLARE HANDLER :

691/3812
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 |
+------+

1.1.1.6.6 DECLARE Variable


Syntax
DECLARE var_name [, var_name] ... [[ROW] TYPE OF]] type [DEFAULT value]

Contents
1. Syntax
2. Description
1. TYPE OF / ROW TYPE OF
3. Examples
4. See Also

Description
This statement is used to declare local variables within stored programs. 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.
Local variables must be declared before CONDITION s, CURSORs 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
TYPE OF and ROW TYPE OF anchored data types for stored routines were introduced in MariaDB 10.3.

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 variables. It is not possible to use
ROW TYPE OF variables in a LIMIT 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 or DROP TABLE statements performed inside the current routine on the tables that appear
692/3812
in anchors won't affect the data type of the anchored variables, even if the variable is declared after an ALTER TABLE
or DROP TABLE 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 or CREATE FUNCTION will not check the referenced tables for existence.

Examples
TYPE OF and ROW TYPE OF from MariaDB 10.3:

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

1.1.1.6.7 FOR
MariaDB starting with 10.3
FOR loops were introduced in MariaDB 10.3.

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)

[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 ]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

693/3812
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:

694/3812
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

1.1.1.6.8 GOTO
MariaDB starting with 10.3
The GOTO statement was introduced in MariaDB 10.3 for Oracle compatibility.

Syntax
GOTO label

Contents
1. Syntax
2. Description
3. Example

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.

695/3812
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)

1.1.1.6.9 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, which differs from the IF statement described above.
Changes in Oracle mode from MariaDB 10.3

1.1.1.6.10 ITERATE
Syntax
ITERATE label

ITERATE can appear only within LOOP, REPEAT, and WHILE statements. ITERATE means "do the loop again", and
uses the statement's label to determine which statements to repeat. The label must be in the same stored program, not
in a caller procedure.
696/3812
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 - Exits a loop (or any labeled code block)

1.1.1.6.11 Labels
Syntax
label: <construct>
[label]

Labels are MariaDB identifiers which can be used to identify a BEGIN ... END 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 and ITERATE statements can be used to exit or repeat a portion of code identified by a label. They must be in
the same Stored Routine, Trigger or Event which contains the target label.
Below is an example using a simple label that is used to exit a LOOP:

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`;

1.1.1.6.12 LEAVE
697/3812
Syntax
LEAVE label

This statement is used to exit the flow control construct that has the given label. The label must be in the same stored
program, not in a caller procedure. LEAVE can be used within BEGIN ... END or loop constructs (LOOP, REPEAT,
WHILE). In Stored Procedures, Triggers and Events, LEAVE can refer to the outmost BEGIN ... END construct; in that
case, the program exits the procedure. In Stored Functions, RETURN can be used instead.
Note that LEAVE cannot be used to exit a DECLARE HANDLER 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 - Repeats a loop execution

1.1.1.6.13 LOOP
Syntax
[begin_label:] LOOP
statement_list
END LOOP [end_label]

Contents
1. Syntax
2. Description
3. See Also

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 statement.
A LOOP statement can be labeled. end_label cannot be given unless begin_label also is present. If both are present,
they must be the same.
See Delimiters in the mysql client for more on delimiter usage in the client.

See Also
LOOP in Oracle mode
ITERATE
LEAVE
698/3812
FOR Loops

1.1.1.6.14 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. end_label cannot be given unless begin_label also is present. If both are present,
they must be the same.
See Delimiters in the mysql 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 |
+------+

699/3812
1.1.1.6.15 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

Contents
1. Syntax
2. Description
3. See Also

Description
The syntax of RESIGNAL and its semantics are very similar to SIGNAL. This statement can only be used within an error
HANDLER. It produces an error, like SIGNAL. RESIGNAL clauses are the same as SIGNAL, except that they all are
optional, even SQLSTATE. 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. For a description of the clauses, see diagnostics area .
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.
If used out of a HANDLER construct, RESIGNAL produces the following error:

ERROR 1645 (0K000): RESIGNAL when handler not active

In MariaDB 5.5, if a HANDLER contained a CALL to another procedure, that procedure could use RESIGNAL . Since
MariaDB 10.0, trying to do this raises the above error.
For a list of SQLSTATE values and MariaDB error codes, see MariaDB Error Codes.
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. 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.

700/3812
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, 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
SIGNAL
HANDLER
Stored Routines
MariaDB Error Codes

1.1.1.6.16 RETURN
Syntax
701/3812
RETURN expr

The RETURN statement terminates execution of a stored function 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, triggers, or events. LEAVE can be used instead.
The following example shows that RETURN can return the result of a scalar subquery:

CREATE FUNCTION users_count() RETURNS BOOL


READS SQL DATA
BEGIN
RETURN (SELECT COUNT(DISTINCT User) FROM mysql.user);
END;

1.1.1.6.17 SELECT INTO


Syntax
SELECT col_name [, col_name] ...
INTO var_name [, var_name] ...
table_expr

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 and user-defined variables.
For the complete syntax, see SELECT.
Another way to set a variable's value is the SET statement.
SELECT ... INTO results are not stored in the query cache even if SQL_CACHE is specified.

Examples
SELECT id, data INTO @x,@y
FROM test.t1 LIMIT 1;

See Also
SELECT - full SELECT syntax.
SELECT INTO OUTFILE - formatting and writing the result to an external file.
SELECT INTO DUMPFILE - binary-safe writing of the unformatted results to an external file.

1.1.1.6.18 SET Variable

702/3812
1.1.1.6.19 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

Contents
1. Syntax
2. Errors
3. Examples
4. See Also

SIGNAL empties the diagnostics area and produces a custom error. This statement can be used anywhere, but is
generally useful when used inside a stored program. When the error is produced, it can be caught by a HANDLER. If
not, the current stored program, or the current statement, will terminate with the specified error.
Sometimes an error HANDLER just needs to SIGNAL the same error it received, optionally with some changes. Usually
the RESIGNAL statement is the most convenient way to do this.
error_condition can be an SQLSTATE value or a named error condition defined via DECLARE CONDITION.
SQLSTATE must be a constant string consisting of five characters. These codes are standard to ODBC and ANSI SQL.
For customized errors, the recommended SQLSTATE is '45000'. For a list of SQLSTATE values used by MariaDB, see
the MariaDB Error Codes page. The SQLSTATE can be read via the API method mysql_sqlstate( ) .
To specify error properties user-defined variables and local variables can be used, as well as character set conversions
(but you can't set a collation).
The error properties, their type and their default values are explained in the diagnostics area 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'

703/3812
Examples
Here's what happens if SIGNAL 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 for an error code. When the error occurs, we SIGNAL 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
RESIGNAL
HANDLER
Stored Routines
704/3812
MariaDB Error Codes

1.1.1.6.20 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 can be used instead.
A WHILE statement can be labeled. 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

1.1.1.6.21 Cursors
A cursor is a structure that allows you to go over records sequentially, and perform processing based on the result.
Cursor Overview
Structure for traversing and processing results sequentially.

DECLARE CURSOR
Declares a cursor which can be used inside stored programs.

OPEN
Open a previously declared cursor.

FETCH
Fetch a row from a cursor.

CLOSE
Close a previously opened cursor.

There are 1 related questions .

1.1.1.6.21.1 Cursor Overview


Contents
1. Description
2. Examples
3. See Also

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, and MariaDB cursors are non-scrollable, read-only and asensitive.
705/3812
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 statement and opened with an OPEN statement. Rows are read with a
FETCH statement before the cursor is finally closed with a CLOSE 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 statement is generally used. The HANDLER should handler the 1329 error,
or the '02000' SQLSTATE, or the NOT FOUND error class.
Only SELECT 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 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, cursors can have parameters. 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). See
DECLARE CURSOR and OPEN for syntax, and below for an example:

Examples

706/3812
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

707/3812
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
OPEN cursor_name
FETCH cursor_name
CLOSE cursor_name
Cursors in Oracle mode

1.1.1.6.21.2 DECLARE CURSOR


Syntax
<= MariaDB 10.2

DECLARE cursor_name CURSOR FOR select_statement

From MariaDB 10.3

DECLARE cursor_name CURSOR [(cursor_formal_parameter[,...])] FOR select_statement

cursor_formal_parameter:
name type [collate clause]

From MariaDB 10.8

708/3812
DECLARE cursor_name CURSOR [(cursor_formal_parameter[,...])] FOR select_statement

cursor_formal_parameter:
[IN] name type [collate clause]

Contents
1. Syntax
2. Description
1. Parameters
2. IN
3. See Also

Description
This statement declares a cursor. Multiple cursors may be declared in a stored program, but each cursor in a given
block must have a unique name.
select_statement is not executed until the OPEN 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, but after local variables and CONDITIONs.

Parameters
MariaDB starting with 10.3.0
From MariaDB 10.3.0, 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
From MariaDB 10.8.0 preview release, the IN qualifier is supported in the cursor_format_parameter part of the
syntax.

See Cursor Overview for an example.

See Also
Cursor Overview
OPEN cursor_name
FETCH cursor_name
CLOSE cursor_name
Cursors in Oracle mode

1.1.1.6.21.3 OPEN
Syntax
<= MariaDB 10.2

OPEN cursor_name

From MariaDB 10.3

OPEN cursor_name [expression[,...]];

709/3812
Contents
1. Syntax
2. Description
3. See Also

Description
This statement opens a cursor which was previously declared with DECLARE CURSOR.
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 rows from a cursor.
See Cursor Overview for an example.

See Also
Cursor Overview
DECLARE CURSOR
FETCH cursor_name
CLOSE cursor_name
Cursors in Oracle mode

1.1.1.6.21.4 FETCH
Syntax
FETCH cursor_name INTO var_name [, var_name] ...

Contents
1. Syntax
2. Description
3. See Also

Description
This statement fetches the next row (if a row exists) using the specified open cursor, and advances the cursor pointer.
var_name can be a local variable, but not a user-defined variable.
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 for an example.

See Also
Cursor Overview
DECLARE CURSOR
OPEN cursor_name
CLOSE cursor_name
Cursors in Oracle mode

1.1.1.6.21.5 CLOSE
Syntax
CLOSE cursor_name

Contents
1. Syntax
2. Description
3. See Also

710/3812
Description
This statement closes a previously opened 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 for an example.

See Also
Cursor Overview
DECLARE CURSOR
OPEN cursor_name
FETCH cursor_name
Cursors in Oracle mode

1.1.1.7 Stored Routine Statements


CALL
3 Invokes a stored procedure.

DO
Executes expressions without returning results.

There are 1 related questions .

1.1.1.7.1 CALL
Syntax
CALL sp_name([parameter[,...]])
CALL sp_name[()]

Description
The CALL statement invokes a stored procedure that was defined previously with CREATE PROCEDURE.
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 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, local variables 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.
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() 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.

1.1.1.7.2 DO
711/3812
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() .

1.1.1.8 Table Statements


1.1.1.9 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 storage engine supports ACID-compliant transactions.

Transaction Articles
START TRANSACTION
1 Basic transaction control statements.

COMMIT
Ends a transaction, making changes visible to subsequent transactions

ROLLBACK
Cancel current transaction and the changes to data

SET TRANSACTION
5 Sets the transaction isolation level.

LOCK TABLES
5 Explicitly lock tables.

SAVEPOINT
1 SAVEPOINT for a ROLLBACK.

Metadata Locking
A lock which protects each transaction from external DDL statements.

SQL statements That Cause an Implicit Commit


List of statements which implicitly commit the current transaction

Transaction Timeouts
Timing out idle transactions

UNLOCK TABLES
Explicitly releases any table locks held by the current session.

WAIT and NOWAIT


Extended syntax so that it is possible to set lock wait timeout for certain statements.

XA Transactions
Transactions designed to allow distributed transactions.

1.1.1.9.1 START TRANSACTION


Syntax
712/3812
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

Contents
1. Syntax
2. Description
1. Access Mode
2. autocommit
3. DDL Statements
4. in_transaction
5. WITH CONSISTENT SNAPSHOT
3. Examples
4. See Also

Description
The START TRANSACTION or BEGIN statement begins a new transaction. COMMIT commits the current transaction,
making its changes permanent. ROLLBACK rolls back the current transaction, canceling its changes. The SET
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 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 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 system variable). READ ONLY mode allows the storage engine to apply optimizations
that cannot be used for transactions which write data. The only exception to this rule is that read only transactions can
perform DDL statements on temporary tables.
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 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 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.

713/3812
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 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 or CONNECT), so it makes sense to use transactions with non-transactional tables.

in_transaction
The 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 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.

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
MyRocks and START TRANSACTION WITH CONSISTENT SNAPSHOT

1.1.1.9.2 COMMIT
The COMMIT statement ends a transaction, saving any changes to the data so that they become visible to subsequent
transactions. Also, unlocks metadata changed by current transaction. If 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 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 variable. In this case, the AND NO CHAIN and NO
RELEASE options override the server default.

See Also
autocommit - server system variable that determines whether statements are automatically committed.
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

714/3812
1.1.1.9.3 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.

1.1.1.9.4 SET TRANSACTION


1.1.1.9.5 LOCK TABLES
Syntax

715/3812
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

Contents
1. Syntax
2. Description
1. WAIT/NOWAIT
3. Limitations
4. See Also

Description
The lock_type can be one of:

Option Description
READ Read lock, no writes allowed
READ LOCAL Read lock, but allow concurrent inserts
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
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.
UNLOCK TABLES explicitly releases any table locks held by the current session.

MariaDB starting with 10.3.0

WAIT/NOWAIT
Set the lock wait timeout. See WAIT and NOWAIT.

Limitations
LOCK TABLES doesn't work when using Galera cluster. You may experience crashes or locks when used with
Galera.
LOCK TABLES works on XtraDB/InnoDB tables only if the innodb_table_locks system variable is set to 1 (the
default) and 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 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 mode. To preserve the data
integrity between transactional and non-transactional tables, the GET_LOCK() 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:

716/3812
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. This
restriction was removed in MariaDB 10.6.2:

ERROR 1314 (0A000): LOCK is not allowed in stored procedures

See Also
UNLOCK TABLES

1.1.1.9.6 SAVEPOINT
Syntax
SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier

Contents
1. Syntax
2. Description
3. Errors

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. A savepoint is a named sub-transaction.
Normally ROLLBACK 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 (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

1.1.1.9.7 Metadata Locking


717/3812
MariaDB supports metadata locking. This means that when a transaction (including XA transactions) 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) 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 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 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 plugin is installed, the Information Schema metadata_lock_info table stores information about
existing metadata locks.

MariaDB starting with 10.5.2


From MariaDB 10.5, the Performance Schema metadata_locks 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

1.1.1.9.8 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) produce a 1400 error (SQLSTATE 'XAE09') if a XA transaction is in effect.
Here is the list:

718/3812
ALTER DATABASE ... UPGRADE DATA DIRECTORY NAME
ALTER EVENT
ALTER FUNCTION
ALTER PROCEDURE
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 SERVER
CREATE TABLE
CREATE TRIGGER
CREATE USER
CREATE VIEW
DROP DATABASE
DROP EVENT
DROP FUNCTION
DROP INDEX
DROP PROCEDURE
DROP ROLE
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 variable.
Note that when a transaction starts (not in autocommit mode), all locks acquired with LOCK TABLES 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() 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.

719/3812
1.1.1.9.9 Transaction Timeouts
MariaDB has always had the wait_timeout and 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 introduced three new variables to handle this situation.
idle_transaction_timeout (all transactions)
idle_write_transaction_timeout (write transactions - called idle_readwrite_transaction_timeout until MariaDB
10.3.2)
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 affects all transactions, idle_write_transaction_timeout affects write transactions only and
idle_readonly_transaction_timeout affects read transactions only. The latter two variables work independently.
However, if either is set along with idle_transaction_timeout, the settings for idle_write_transaction_timeout or
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

1.1.1.9.10 UNLOCK TABLES


Syntax
UNLOCK TABLES

Contents
1. Syntax
2. Description

Description
720/3812
UNLOCK TABLES explicitly releases any table locks held by the current session. See LOCK TABLES for more information.
In addition to releasing table locks acquired by the LOCK TABLES 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 for more information about FLUSH TABLES WITH READ
LOCK .

721/3812
1.1.1.9.11 WAIT and NOWAIT
MariaDB starting with 10.3.0
MariaDB 10.3.0 introduced extended syntax so that it is possible to set innodb_lock_wait_timeout and
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
ALTER TABLE
CREATE INDEX
DROP INDEX
DROP TABLE
LOCK TABLES and UNLOCK TABLES
OPTIMIZE TABLE
RENAME TABLE
SELECT
TRUNCATE TABLE

1.1.1.9.12 XA Transactions
Contents
1. Overview
2. Internal XA vs External XA
3. Transaction Coordinator Log
4. Syntax
5. XA RECOVER
6. Examples
7. Known Issues
1. MariaDB Galera Cluster

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, TokuDB ,
722/3812
SPIDER and MyRocks support them. For InnoDB, until MariaDB 10.2, XA transactions can be disabled by setting the
innodb_support_xa server system variable to 0. From MariaDB 10.3, XA transactions are always supported.
Like regular transactions, XA transactions create metadata locks on accessed tables.
XA transactions require REPEATABLE READ as a minimum isolation level. However, distributed transactions should
always use SERIALIZABLE.
Trying to start more than one XA transaction at the same time produces a 1400 error (SQLSTATE '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 'XAE07').
The statements that cause an implicit COMMIT for regular transactions produce a 1400 error (SQLSTATE '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 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 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 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 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.

723/3812
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


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:

724/3812
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 does not support XA transactions.
However, MariaDB Galera Cluster builds include a built-in plugin called wsrep . Prior to MariaDB 10.4.3, this plugin was
internally considered an XA-capable storage engine. Consequently, these MariaDB Galera Cluster builds have multiple
XA-capable storage engines by default, even if the only "real" storage engine that supports external XA transactions
enabled on these builds by default is InnoDB. Therefore, when using one these builds MariaDB would be forced to use
a transaction coordinator log by default, which could have performance implications.
See Transaction Coordinator Log Overview: MariaDB Galera Cluster for more information.

1.1.1.10 HELP Command


1.1.1.11 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.

725/3812
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 ):

/*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 |
+---+

1.1.1.12 Built-in Functions


1.1.2 SQL Language Structure
SQL language structure rules.

726/3812
Identifier Names
Naming rules for identifiers.

Identifier Case-sensitivity
2 Whether objects are case-sensitive or not is partly determined by the under...

Binary Literals
Binary literals can be written in one of the following formats.

Boolean Literals
True and false.

Date and Time Literals


Literals regarding date and time.

Hexadecimal Literals
Hexadecimal literals can be written using any of the following syntaxes

Identifier Qualifiers
2 How to reference an object and its context in an SQL statement.

Identifier to File Name Mapping


Some identifiers map to a file name on the filesystem. Databases each have ...

MariaDB Error Codes


MariaDB error codes reference list.

Numeric Literals
Numeric literals are written as a sequence of digits from 0 to 9

Reserved Words
3 List of reserved words in MariaDB.

SQLSTATE
A string which identifies a condition's class and subclass

String Literals
1 Strings are sequences of characters and are enclosed with quotes.

Table Value Constructors


Documents adding arbitrary values to the result-set.

User-Defined Variables
6 Variables which exist within a session.

There are 3 related questions .

1.1.2.1 Identifier Names


Contents
1. Unquoted
2. Quoted
3. Further Rules
4. Quote Character
5. Maximum Length
6. Multiple Identifiers
7. Examples

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. If the ANSI_QUOTES SQL_MODE flag is set, double quotes ( " )
can also be used to quote identifiers. If the MSSQL flag is set, square brackets ( [ and ] ) can be used for quoting.
Even when using reserved words as names, fully qualified names do not need to be quoted. For example, test.select
has only one possible meaning, so it is correctly parsed even without quotes.
727/3812
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.
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 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 have a maximum length of 16 characters
Aliases have a maximum length of 256 characters, except for column aliases in CREATE VIEW 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 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:

728/3812
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:

729/3812
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)

1.1.2.2 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 names are affected by the systems case-sensitivity, while index, column,
column aliases, stored routine and event names are never case sensitive.
Log file group name are case sensitive.
The 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.


Please note that lower_case_table_names is a database initialization parameter. This means that, along with
innodb_page_size, this variable must be set before running mysql_install_db, and will not change the behavior of
servers unless applied before the creation of core system databases.

1.1.2.3 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, BINARY or BIT values.
To convert a binary literal into an integer, just add 0.

Examples
Printing the value as a binary string:

730/3812
SELECT 0b1000001;
+-----------+
| 0b1000001 |
+-----------+
| A |
+-----------+

Converting the same value into a number:

SELECT 0b1000001+0;
+-------------+
| 0b1000001+0 |
+-------------+
| 65 |
+-------------+

See Also
BIN()

1.1.2.4 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 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.
TRUE and FALSE are reserved words, while UNKNOWN is not.

See Also
BOOLEAN type

1.1.2.5 Date and Time Literals


Contents
1. Standard syntaxes
2. DATE literals
3. DATETIME literals
4. TIME literals
5. 2-digit years
6. Microseconds
7. Date and time literals and the
SQL_MODE
8. See also

Standard syntaxes
MariaDB supports the SQL standard and ODBC syntaxes for DATE, TIME and TIMESTAMP 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 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.

731/3812
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 for details.

732/3812
Date and time literals and the SQL_MODE
Unless the SQL_MODE 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

1.1.2.6 Hexadecimal Literals


Contents
1. Examples
1. Fun with Types
2. Differences Between MariaDB and
MySQL
2. See Also

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 and MariaDB 5.5.31 (fixing 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

733/3812
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(), 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()
UNHEX()

734/3812
1.1.2.7 Identifier Qualifiers
Contents
1. See Also

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, 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 and DATABASE() 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 for details.

See Also
Identifier Names
USE
DATABASE()

1.1.2.8 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, 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). 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

735/3812
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 | |
+-------+---------+------+-----+---------+-------+

1.1.2.9 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

Contents
1. Shared MariaDB/MySQL error codes
2. MariaDB-specific error codes

736/3812
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 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 tool can be used to get the error message which is associated with a given error code.

Shared MariaDB/MySQL error codes


Error
SQLSTATE Error Description
Code
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
Error dropping database (can't delete '%s', errno:
1009 HY000 ER_DB_DROP_DELETE
%d)
Error dropping database (can't rmdir '%s', errno:
1010 HY000 ER_DB_DROP_RMDIR
%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'
Disk full (%s); waiting for someone to free some
1021 HY000 ER_DISK_FULL
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

737/3812
Table storage engine for '%s' doesn't have this
1031 HY000 ER_ILLEGAL_HA
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
Out of memory; restart server and try again
1037 HY001 ER_OUTOFMEMORY
(needed %d bytes)
Out of sort memory, consider increasing server sort
1038 HY001 ER_OUT_OF_SORTMEMORY
buffer size
Unexpected EOF found when reading file '%s'
1039 HY000 ER_UNEXPECTED_EOF
(Errno: %d)
1040 08004 ER_CON_COUNT_ERROR Too many connections
Out of memory; check if mysqld or some other
process uses all available memory; if not, you may
1041 HY000 ER_OUT_OF_RESOURCES
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'
Access denied for user '%s'@'%s' (using password:
1045 28000 ER_ACCESS_DENIED_ERROR
%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'
Statement has sum functions and columns in same
1057 42000 ER_WRONG_SUM_SELECT
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
738/3812
Too many key parts specified; max %d parts
1070 42000 ER_TOO_MANY_KEY_PARTS
allowed
Specified key was too long; max key length is %d
1071 42000 ER_TOO_LONG_KEY
bytes
1072 42000 ER_KEY_COLUMN_DOES_NOT_EXITS Key column '%s' doesn't exist in table
BLOB column '%s' can't be used in key
1073 42000 ER_BLOB_USED_AS_KEY
specification with the used table type
Column length too big for column '%s' (max = %lu);
1074 42000 ER_TOO_BIG_FIELDLENGTH
use BLOB or TEXT instead
Incorrect table definition; there can be only one
1075 42000 ER_WRONG_AUTO_KEY
auto column and it must be defined as a key
%s: ready for connections. Version: '%s' socket:
1076 HY000 ER_READY
'%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
Table '%s' has no index like the one used in
1082 42S12 ER_NO_SUCH_INDEX
CREATE INDEX; recreate the table
Field separator argument is not what is expected;
1083 42000 ER_WRONG_FIELD_TERMINATORS
check the manual
You can't use fixed rowlength with BLOBs; please
1084 42000 ER_BLOBS_AND_NO_TERMINATED
use 'fields terminated by'
The file '%s' must be in the database directory or
1085 HY000 ER_TEXTFILE_NOT_READABLE
be readable by all
1086 HY000 ER_FILE_EXISTS_ERROR File '%s' already exists
Records: %ld Deleted: %ld Skipped: %ld
1087 HY000 ER_LOAD_INF
Warnings: %ld
1088 HY000 ER_ALTER_INF Records: %ld Duplicates: %ld
Incorrect prefix key; the used key part isn't a string,
1089 HY000 ER_WRONG_SUB_KEY the used length is longer than the key part, or the
storage engine doesn't support unique prefix keys
You can't delete all columns with ALTER TABLE;
1090 42000 ER_CANT_REMOVE_ALL_FIELDS
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


You can't specify target table '%s' for update in
1093 HY000 ER_UPDATE_TABLE_USED
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)
Table '%s' was locked with a READ lock and can't
1099 HY000 ER_TABLE_NOT_LOCKED_FOR_WRITE
be updated

Error
SQLSTATE Error Description
Code
Table '%s' was not locked with LOCK
1100 HY000 ER_TABLE_NOT_LOCKED
TABLES
1101 ER_UNUSED_17 You should never see it
739/3812
1102 42000 ER_WRONG_DB_NAME Incorrect database name '%s'
1103 42000 ER_WRONG_TABLE_NAME Incorrect table name '%s'
The SELECT would examine more than
MAX_JOIN_SIZE rows; check your
WHERE and use SET
1104 42000 ER_TOO_BIG_SELECT
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'
Incorrect parameter count to procedure
1107 42000 ER_WRONG_PARAMCOUNT_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
Table '%s' uses an extension that
1112 42000 ER_UNSUPPORTED_EXTENSION
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'
Too many tables; MariaDB can only use
1116 HY000 ER_TOO_MANY_TABLES
%d tables in a join
1117 HY000 ER_TOO_MANY_FIELDS Too many columns
Row size too large. The maximum row
size for the used table type, not counting
1118 42000 ER_TOO_BIG_ROWSIZE
BLOBs, is %ld. You have to change
some columns to TEXT or BLOBs
Thread stack overrun: Used: %ld of a
%ld stack. Use 'mysqld --
1119 HY000 ER_STACK_OVERRUN
thread_stack=#' to specify a bigger stack
if needed
Cross dependency found in OUTER
1120 42000 ER_WRONG_OUTER_JOIN
JOIN; examine your ON conditions
Table handler doesn't support NULL in
1121 42000 ER_NULL_COLUMN_IN_INDEX 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
Can't open shared library '%s' (Errno:
1126 HY000 ER_CANT_OPEN_LIBRARY
%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
Host '%s' is blocked because of many
1129 HY000 ER_HOST_IS_BLOCKED connection errors; unblock with
'mysqladmin flush-hosts'
Host '%s' is not allowed to connect to
1130 HY000 ER_HOST_NOT_PRIVILEGED
this MariaDB server
You are using MariaDB as an
1131 42000 ER_PASSWORD_ANONYMOUS_USER anonymous user and anonymous users
are not allowed to change passwords

740/3812
You must have privileges to update
1132 42000 ER_PASSWORD_NOT_ALLOWED tables in the mysql database to be able
to change passwords for others
Can't find any matching row in the user
1133 42000 ER_PASSWORD_NO_MATCH
table
Rows matched: %ld Changed: %ld
1134 HY000 ER_UPDATE_INF
Warnings: %ld
Can't create a new thread (Errno %d); if
you are not out of available memory, you
1135 HY000 ER_CANT_CREATE_THREAD
can consult the manual for a possible
OS-dependent bug
Column count doesn't match value count
1136 21S01 ER_WRONG_VALUE_COUNT_ON_ROW
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
Mixing of GROUP columns
(MIN(),MAX(),COUNT(),...) with no
1140 42000 ER_MIX_OF_GROUP_FUNC_AND_FIELDS
GROUP columns is illegal if there is no
GROUP BY clause
There is no such grant defined for user
1141 42000 ER_NONEXISTING_GRANT
'%s' on host '%s'
%s command denied to user '%s'@'%s'
1142 42000 ER_TABLEACCESS_DENIED_ERROR
for table '%s'
%s command denied to user '%s'@'%s'
1143 42000 ER_COLUMNACCESS_DENIED_ERROR
for column '%s' in table '%s'
Illegal GRANT/REVOKE command;
1144 42000 ER_ILLEGAL_GRANT_FOR_TABLE please consult the manual to see which
privileges can be used
The host or user argument to GRANT is
1145 42000 ER_GRANT_WRONG_HOST_OR_USER
too long
1146 42S02 ER_NO_SUCH_TABLE Table '%s.%s' doesn't exist
There is no such grant defined for user
1147 42000 ER_NONEXISTING_TABLE_GRANT
'%s' on host '%s' on table '%s'
The used command is not allowed with
1148 42000 ER_NOT_ALLOWED_COMMAND
this MariaDB version
You have an error in your SQL syntax;
check the manual that corresponds to
1149 42000 ER_SYNTAX_ERROR
your MariaDB server version for the right
syntax to use
Delayed insert thread couldn't get
1150 HY000 ER_DELAYED_CANT_CHANGE_LOCK
requested lock for table %s
1151 HY000 ER_TOO_MANY_DELAYED_THREADS Too many delayed threads in use
Aborted connection %ld to db: '%s' user:
1152 08S01 ER_ABORTING_CONNECTION
'%s' (%s)
Got a packet bigger than
1153 08S01 ER_NET_PACKET_TOO_LARGE
'max_allowed_packet' bytes
Got a read error from the connection
1154 08S01 ER_NET_READ_ERROR_FROM_PIPE
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
Couldn't uncompress communication
1157 08S01 ER_NET_UNCOMPRESS_ERROR
packet
Got an error reading communication
1158 08S01 ER_NET_READ_ERROR
packets

741/3812
Got timeout reading communication
1159 08S01 ER_NET_READ_INTERRUPTED
packets
Got an error writing communication
1160 08S01 ER_NET_ERROR_ON_WRITE
packets
Got timeout writing communication
1161 08S01 ER_NET_WRITE_INTERRUPTED
packets
Result string is longer than
1162 42000 ER_TOO_LONG_STRING
'max_allowed_packet' bytes
The used table type doesn't support
1163 42000 ER_TABLE_CANT_HANDLE_BLOB
BLOB/TEXT columns
The used table type doesn't support
1164 42000 ER_TABLE_CANT_HANDLE_AUTO_INCREMENT
AUTO_INCREMENT columns
INSERT DELAYED can't be used with
1165 HY000 ER_DELAYED_INSERT_TABLE_LOCKED table '%s' because it is locked with
LOCK TABLES
1166 42000 ER_WRONG_COLUMN_NAME Incorrect column name '%s'
The used storage engine can't index
1167 42000 ER_WRONG_KEY_COLUMN
column '%s'
Unable to open underlying table which is
1168 HY000 ER_WRONG_MRG_TABLE differently defined or of non-MyISAM
type or doesn't exist
Can't write, because of unique
1169 23000 ER_DUP_UNIQUE
constraint, to table '%s'
BLOB/TEXT column '%s' used in key
1170 42000 ER_BLOB_KEY_WITHOUT_LENGTH
specification without a key length
All parts of a PRIMARY KEY must be
1171 42000 ER_PRIMARY_CANT_HAVE_NULL 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
This version of MariaDB is not compiled
1174 HY000 ER_NO_RAID_COMPILED
with RAID support
You are using safe update mode and
1175 HY000 ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE 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
The storage engine for the table doesn't
1178 42000 ER_CHECK_NOT_IMPLEMENTED
support %s
You are not allowed to execute this
1179 25000 ER_CANT_DO_THIS_DURING_AN_TRANSACTION
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
Aborted connection %ld to db: '%s' user:
1184 08S01 ER_NEW_ABORTING_CONNECTION
'%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
Failed rebuilding the index of dumped
1187 HY000 ER_INDEX_REBUILD
table '%s'
1188 HY000 ER_MASTER Error from master: '%s'

742/3812
1189 08S01 ER_MASTER_NET_READ Net error reading from master
1190 08S01 ER_MASTER_NET_WRITE Net error writing to master
Can't find FULLTEXT index matching the
1191 HY000 ER_FT_MATCHING_KEY_NOT_FOUND
column list
Can't execute the given command
1192 HY000 ER_LOCK_OR_ACTIVE_TRANSACTION because you have active locked tables
or an active transaction
1193 HY000 ER_UNKNOWN_SYSTEM_VARIABLE Unknown system variable '%s'
Table '%s' is marked as crashed and
1194 HY000 ER_CRASHED_ON_USAGE
should be repaired
Table '%s' is marked as crashed and last
1195 HY000 ER_CRASHED_ON_REPAIR
(automatic?) repair failed
Some non-transactional changed tables
1196 HY000 ER_WARNING_NOT_COMPLETE_ROLLBACK
couldn't be rolled back
Multi-statement transaction required
more than 'max_binlog_cache_size'
1197 HY000 ER_TRANS_CACHE_FULL
bytes of storage; increase this mysqld
variable and try again
This operation cannot be performed with
1198 HY000 ER_SLAVE_MUST_STOP
a running slave; run STOP SLAVE first
This operation requires a running slave;
1199 HY000 ER_SLAVE_NOT_RUNNING
configure slave and do START SLAVE

Error
SQLSTATE Error Description
Code
The server is not configured as slave;
1200 HY000 ER_BAD_SLAVE fix in config file or with CHANGE
MASTER TO
Could not initialize master info
1201 HY000 ER_MASTER_INFO structure; more error messages can be
found in the MariaDB error log
Could not create slave thread; check
1202 HY000 ER_SLAVE_THREAD
system resources
User %s already has more than
1203 42000 ER_TOO_MANY_USER_CONNECTIONS 'max_user_connections' active
connections
You may only use constant
1204 HY000 ER_SET_CONSTANTS_ONLY
expressions with SET
Lock wait timeout exceeded; try
1205 HY000 ER_LOCK_WAIT_TIMEOUT
restarting transaction
The total number of locks exceeds the
1206 HY000 ER_LOCK_TABLE_FULL
lock table size
Update locks cannot be acquired
1207 25000 ER_READ_ONLY_TRANSACTION during a READ UNCOMMITTED
transaction
DROP DATABASE not allowed while
1208 HY000 ER_DROP_DB_WITH_READ_LOCK
thread is holding global read lock
CREATE DATABASE not allowed
1209 HY000 ER_CREATE_DB_WITH_READ_LOCK
while thread is holding global read lock
1210 HY000 ER_WRONG_ARGUMENTS Incorrect arguments to %s
'%s'@'%s' is not allowed to create new
1211 42000 ER_NO_PERMISSION_TO_CREATE_USER
users
Incorrect table definition; all MERGE
1212 HY000 ER_UNION_TABLES_IN_DIFFERENT_DIR
tables must be in the same database
Deadlock found when trying to get
1213 40001 ER_LOCK_DEADLOCK
lock; try restarting transaction

743/3812
The used table type doesn't support
1214 HY000 ER_TABLE_CANT_HANDLE_FT
FULLTEXT indexes
1215 HY000 ER_CANNOT_ADD_FOREIGN Cannot add foreign key constraint
Cannot add or update a child row: a
1216 23000 ER_NO_REFERENCED_ROW
foreign key constraint fails
Cannot delete or update a parent row:
1217 23000 ER_ROW_IS_REFERENCED
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
Error when executing command %s:
1220 HY000 ER_ERROR_WHEN_EXECUTING_COMMAND
%s
1221 HY000 ER_WRONG_USAGE Incorrect usage of %s and %s
The used SELECT statements have a
1222 21000 ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
different number of columns
Can't execute the query because you
1223 HY000 ER_CANT_UPDATE_WITH_READLOCK
have a conflicting read lock
Mixing of transactional and non-
1224 HY000 ER_MIXING_NOT_ALLOWED
transactional tables is disabled
1225 HY000 ER_DUP_ARGUMENT Option '%s' used twice in statement
User '%s' has exceeded the '%s'
1226 42000 ER_USER_LIMIT_REACHED
resource (current value: %ld)
Access denied; you need (at least one
1227 42000 ER_SPECIFIC_ACCESS_DENIED_ERROR
of) the %s privilege(s) for this operation
Variable '%s' is a SESSION variable
1228 HY000 ER_LOCAL_VARIABLE
and can't be used with SET GLOBAL
Variable '%s' is a GLOBAL variable and
1229 HY000 ER_GLOBAL_VARIABLE
should be set with SET GLOBAL
Variable '%s' doesn't have a default
1230 42000 ER_NO_DEFAULT
value
Variable '%s' can't be set to the value
1231 42000 ER_WRONG_VALUE_FOR_VAR
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'
This version of MariaDB doesn't yet
1235 42000 ER_NOT_SUPPORTED_YET
support '%s'
Got fatal error %d from master when
1236 HY000 ER_MASTER_FATAL_ERROR_READING_BINLOG
reading data from binary log: '%s'
Slave SQL thread ignored the query
1237 HY000 ER_SLAVE_IGNORED_TABLE
because of replicate-*-table rules
1238 HY000 ER_INCORRECT_GLOBAL_LOCAL_VAR Variable '%s' is a %s variable
Incorrect foreign key definition for '%s':
1239 42000 ER_WRONG_FK_DEF
%s
Key reference and table reference
1240 HY000 ER_KEY_REF_DO_NOT_MATCH_TABLE_REF
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
Unknown prepared statement handler
1243 HY000 ER_UNKNOWN_STMT_HANDLER
(%.*s) given to %s
Help database is corrupt or does not
1244 HY000 ER_CORRUPT_HELP_DB
exist
1245 HY000 ER_CYCLIC_REFERENCE Cyclic reference on subqueries

744/3812
1246 HY000 ER_AUTO_CONVERT Converting column '%s' from %s to %s
1247 42S22 ER_ILLEGAL_REFERENCE Reference '%s' not supported (%s)
Every derived table must have its own
1248 42000 ER_DERIVED_MUST_HAVE_ALIAS
alias
Select %u was reduced during
1249 01000 ER_SELECT_REDUCED
optimization
Table '%s' from one of the SELECTs
1250 42000 ER_TABLENAME_NOT_ALLOWED_HERE
cannot be used in %s
Client does not support authentication
1251 08004 ER_NOT_SUPPORTED_AUTH_MODE protocol requested by server; consider
upgrading MariaDB client
All parts of a SPATIAL index must be
1252 42000 ER_SPATIAL_CANT_HAVE_NULL
NOT NULL
COLLATION '%s' is not valid for
1253 42000 ER_COLLATION_CHARSET_MISMATCH
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
Uncompressed data size too large; the
1256 HY000 ER_TOO_BIG_FOR_UNCOMPRESS maximum size is %d (probably, length
of uncompressed data was corrupted)
1257 HY000 ER_ZLIB_Z_MEM_ERROR ZLIB: Not enough memory
ZLIB: Not enough room in the output
1258 HY000 ER_ZLIB_Z_BUF_ERROR buffer (probably, length of
uncompressed data was corrupted)
1259 HY000 ER_ZLIB_Z_DATA_ERROR ZLIB: Input data corrupted
Row %u was cut by
1260 HY000 ER_CUT_VALUE_GROUP_CONCAT
GROUP_CONCAT()
Row %ld doesn't contain data for all
1261 01000 ER_WARN_TOO_FEW_RECORDS
columns
Row %ld was truncated; it contained
1262 01000 ER_WARN_TOO_MANY_RECORDS more data than there were input
columns
Column set to default value; NULL
1263 22004 ER_WARN_NULL_TO_NOTNULL supplied to NOT NULL column '%s' at
row %ld
Out of range value for column '%s' at
1264 22003 ER_WARN_DATA_OUT_OF_RANGE
row %ld
Data truncated for column '%s' at row
1265 01000 WARN_DATA_TRUNCATED
%ld
1266 HY000 ER_WARN_USING_OTHER_HANDLER Using storage engine %s for table '%s'
Illegal mix of collations (%s,%s) and
1267 HY000 ER_CANT_AGGREGATE_2COLLATIONS
(%s,%s) for operation '%s'
Cannot drop one or more of the
1268 HY000 ER_DROP_USER
requested users
Can't revoke all privileges for one or
1269 HY000 ER_REVOKE_GRANTS
more of the requested users
Illegal mix of collations (%s,%s),
1270 HY000 ER_CANT_AGGREGATE_3COLLATIONS
(%s,%s), (%s,%s) for operation '%s'
Illegal mix of collations for operation
1271 HY000 ER_CANT_AGGREGATE_NCOLLATIONS
'%s'
Variable '%s' is not a variable
1272 HY000 ER_VARIABLE_IS_NOT_STRUCT component (can't be used as
XXXX.variable_name)

1273 HY000 ER_UNKNOWN_COLLATION Unknown collation: '%s'

745/3812
SSL parameters in CHANGE MASTER
are ignored because this MariaDB
1274 HY000 ER_SLAVE_IGNORED_SSL_PARAMS slave was compiled without SSL
support; they can be used later if
MariaDB slave with SSL is started
Server is running in --secure-auth
mode, but '%s'@'%s' has a password
1275 HY000 ER_SERVER_IS_IN_SECURE_AUTH_MODE
in the old format; please change the
password to the new format
Field or reference '%s%s%s%s%s' of
1276 HY000 ER_WARN_FIELD_RESOLVED SELECT #%d was resolved in
SELECT #%d
Incorrect parameter or combination of
1277 HY000 ER_BAD_SLAVE_UNTIL_COND
parameters for START SLAVE UNTIL
It is recommended to use --skip-slave-
start when doing step-by-step
replication with START SLAVE UNTIL;
1278 HY000 ER_MISSING_SKIP_SLAVE
otherwise, you will get problems if you
get an unexpected slave's mysqld
restart
SQL thread is not to be started so
1279 HY000 ER_UNTIL_COND_IGNORED
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'
Query cache failed to set size %lu; new
1282 HY000 ER_WARN_QC_RESIZE
query cache size is %lu
Column '%s' cannot be part of
1283 HY000 ER_BAD_FT_COLUMN
FULLTEXT index
1284 HY000 ER_UNKNOWN_KEY_CACHE Unknown key cache '%s'
MariaDB is started in --skip-name-
1285 HY000 ER_WARN_HOSTNAME_WONT_WORK resolve mode; you must restart it
without this switch for this grant to work
1286 42000 ER_UNKNOWN_STORAGE_ENGINE Unknown storage engine '%s'
'%s' is deprecated and will be removed
1287 HY000 ER_WARN_DEPRECATED_SYNTAX in a future release. Please use %s
instead

The target table %s of the %s is not


1288 HY000 ER_NON_UPDATABLE_TABLE
updatable
The '%s' feature is disabled; you need
1289 HY000 ER_FEATURE_DISABLED MariaDB built with '%s' to have it
working
The MariaDB server is running with the
1290 HY000 ER_OPTION_PREVENTS_STATEMENT %s option so it cannot execute this
statement
Column '%s' has duplicated value '%s'
1291 HY000 ER_DUPLICATED_VALUE_IN_TYPE
in %s
1292 22007 ER_TRUNCATED_WRONG_VALUE Truncated incorrect %s value: '%s'
Incorrect table definition; there can be
only one TIMESTAMP column with
1293 HY000 ER_TOO_MUCH_AUTO_TIMESTAMP_COLS
CURRENT_TIMESTAMP in DEFAULT
or ON UPDATE clause
Invalid ON UPDATE clause for '%s'
1294 HY000 ER_INVALID_ON_UPDATE
column
This command is not supported in the
1295 HY000 ER_UNSUPPORTED_PS
prepared statement protocol yet
1296 HY000 ER_GET_ERRMSG Got error %d '%s' from %s

746/3812
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'
Invalid TIMESTAMP value in column
1299 HY000 ER_WARN_INVALID_TIMESTAMP
'%s' at row %ld

Error
SQLSTATE Error Description
Code
1300 HY000 ER_INVALID_CHARACTER_STRING Invalid %s character string: '%s'
Result of %s() was larger than
1301 HY000 ER_WARN_ALLOWED_PACKET_OVERFLOWED
max_allowed_packet (%ld) - truncated
Conflicting declarations: '%s%s' and
1302 HY000 ER_CONFLICTING_DECLARATIONS
'%s%s'
Can't create a %s from within another
1303 2F003 ER_SP_NO_RECURSIVE_CREATE
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
PROCEDURE %s can't return a result
1312 0A000 ER_SP_BADSELECT
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
The update log is deprecated and
replaced by the binary log; SET
1315 42000 ER_UPDATE_LOG_DEPRECATED_IGNORED SQL_LOG_UPDATE has been ignored.
This option will be removed in MariaDB
5.6 .
The update log is deprecated and
replaced by the binary log; SET
1316 42000 ER_UPDATE_LOG_DEPRECATED_TRANSLATED SQL_LOG_UPDATE has been translated
to SET SQL_LOG_BIN. This option will
be removed in MariaDB 5.6 .

1317 70100 ER_QUERY_INTERRUPTED Query execution was interrupted


Incorrect number of arguments for %s
1318 42000 ER_SP_WRONG_NO_OF_ARGS
%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
No data - zero rows fetched, selected, or
1329 02000 ER_SP_FETCH_NO_DATA
processed
747/3812
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
%s is not allowed in stored function or
1336 0A000 ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
trigger
Variable or condition declaration after
1337 42000 ER_SP_VARCOND_AFTER_CURSHNDLR
cursor or handler declaration
Cursor declaration after handler
1338 42000 ER_SP_CURSOR_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'
Unexpected end of file while parsing
1342 HY000 ER_FPARSER_EOF_IN_COMMENT
comment '%s'
Error while parsing parameter '%s' (line:
1343 HY000 ER_FPARSER_ERROR_IN_PARAMETER
'%s')
Unexpected end of file while skipping
1344 HY000 ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER
unknown parameter '%s'
EXPLAIN/SHOW can not be issued;
1345 HY000 ER_VIEW_NO_EXPLAIN
lacking privileges for underlying table
File '%s' has unknown type '%s' in its
1346 HY000 ER_FRM_UNKNOWN_TYPE
header
1347 HY000 ER_WRONG_OBJECT '%s.%s' is not %s
1348 HY000 ER_NONUPDATEABLE_COLUMN Column '%s' is not updatable
View's SELECT contains a subquery in
1349 HY000 ER_VIEW_SELECT_DERIVED
the FROM clause
1350 HY000 ER_VIEW_SELECT_CLAUSE View's SELECT contains a '%s' clause
View's SELECT contains a variable or
1351 HY000 ER_VIEW_SELECT_VARIABLE
parameter
View's SELECT refers to a temporary
1352 HY000 ER_VIEW_SELECT_TMPTABLE
table '%s'
View's SELECT and view's field list have
1353 HY000 ER_VIEW_WRONG_LIST
different column counts
View merge algorithm can't be used here
1354 HY000 ER_WARN_VIEW_MERGE
for now (assumed undefined algorithm)
View being updated does not have
1355 HY000 ER_WARN_VIEW_WITHOUT_KEY
complete key of underlying table in it
View '%s.%s' references invalid table(s)
or column(s) or function(s) or
1356 HY000 ER_VIEW_INVALID
definer/invoker of view lack rights to use
them
Can't drop or alter a %s from within
1357 HY000 ER_SP_NO_DROP_SP
another stored routine
GOTO is not allowed in a stored
1358 HY000 ER_SP_GOTO_IN_HNDLR
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

748/3812
Updating of %s row is not allowed in
1362 HY000 ER_TRG_CANT_CHANGE_ROW
%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
Incorrect %s value: '%s' for column '%s'
1366 HY000 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
at row %ld
1367 22007 ER_ILLEGAL_VALUE_FOR_TYPE Illegal %s '%s' value found during parsing
CHECK OPTION on non-updatable view
1368 HY000 ER_VIEW_NONUPD_CHECK
'%s.%s'
1369 HY000 ER_VIEW_CHECK_FAILED CHECK OPTION failed '%s.%s'
%s command denied to user '%s'@'%s'
1370 42000 ER_PROCACCESS_DENIED_ERROR
for routine '%s'
1371 HY000 ER_RELAY_LOG_FAIL Failed purging old relay logs: %s
Password hash should be a %d-digit
1372 HY000 ER_PASSWD_LENGTH
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
Server configuration does not permit
1375 HY000 ER_BINLOG_PURGE_PROHIBITED
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
The '%s' syntax is reserved for purposes
1382 HY000 ER_RESERVED_SYNTAX
internal to the MariaDB server
1383 HY000 ER_WSAS_FAILED WSAStartup Failed
Can't handle procedures with different
1384 HY000 ER_DIFF_GROUPS_PROC
groups yet
Select must have a group with this
1385 HY000 ER_NO_GROUP_FOR_PROC
procedure
Can't use ORDER clause with this
1386 HY000 ER_ORDER_WITH_PROC
procedure
Binary logging and replication forbid
1387 HY000 ER_LOGGING_PROHIBIT_CHANGING_OF
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
Prepared statement contains too many
1390 HY000 ER_PS_MANY_PARAM
placeholders
1391 HY000 ER_KEY_PART_0 Key part '%s' length cannot be 0
1392 HY000 ER_VIEW_CHECKSUM View text checksum failed
Can not modify more than one base table
1393 HY000 ER_VIEW_MULTIUPDATE
through a join view '%s.%s'
Can not insert into join view '%s.%s'
1394 HY000 ER_VIEW_NO_INSERT_FIELD_LIST
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
749/3812
XAER_INVAL: Invalid arguments (or
1398 XAE05 ER_XAER_INVAL
unsupported command)
XAER_RMFAIL: The command cannot be
1399 XAE07 ER_XAER_RMFAIL executed when global transaction is in
the %s state

Error
SQLSTATE Error Description
Code
XAER_OUTSIDE: Some work is
1400 XAE09 ER_XAER_OUTSIDE
done outside global transaction
XAER_RMERR: Fatal error
1401 XAE03 ER_XAER_RMERR occurred in the transaction branch
- check your data for consistency
XA_RBROLLBACK: Transaction
1402 XA100 ER_XA_RBROLLBACK
branch was rolled back
There is no such grant defined for
1403 42000 ER_NONEXISTING_PROC_GRANT user '%s' on host '%s' on routine
'%s'
Failed to grant EXECUTE and
1404 HY000 ER_PROC_AUTO_GRANT_FAIL
ALTER ROUTINE privileges
Failed to revoke all privileges to
1405 HY000 ER_PROC_AUTO_REVOKE_FAIL
dropped routine
Data too long for column '%s' at
1406 22001 ER_DATA_TOO_LONG
row %ld
1407 42000 ER_SP_BAD_SQLSTATE Bad SQLSTATE: '%s'
%s: ready for connections.
1408 HY000 ER_STARTUP Version: '%s' socket: '%s' port: %d
%s
Can't load value from file with fixed
1409 HY000 ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR
size rows to variable
You are not allowed to create a
1410 42000 ER_CANT_CREATE_USER_WITH_GRANT
user with GRANT
Incorrect %s value: '%s' for
1411 HY000 ER_WRONG_VALUE_FOR_TYPE
function %s
Table definition has changed,
1412 HY000 ER_TABLE_DEF_CHANGED
please retry transaction
Duplicate handler declared in the
1413 42000 ER_SP_DUP_HANDLER
same block
OUT or INOUT argument %d for
routine %s is not a variable or
1414 42000 ER_SP_NOT_VAR_ARG
NEW pseudo-variable in BEFORE
trigger
Not allowed to return a result set
1415 0A000 ER_SP_NO_RETSET
from a %s
Cannot get geometry object from
1416 22003 ER_CANT_CREATE_GEOMETRY_OBJECT data you send to the GEOMETRY
field
A routine failed and has neither NO
SQL nor READS SQL DATA in its
declaration and binary logging is
1417 HY000 ER_FAILED_ROUTINE_BREAK_BINLOG
enabled; if non-transactional tables
were updated, the binary log will
miss their changes

750/3812
This function has none of
DETERMINISTIC, NO SQL, or
READS SQL DATA in its
declaration and binary logging is
1418 HY000 ER_BINLOG_UNSAFE_ROUTINE
enabled (you *might* want to use
the less safe
log_bin_trust_function_creators
variable)
You do not have the SUPER
privilege and binary logging is
enabled (you *might* want to use
1419 HY000 ER_BINLOG_CREATE_ROUTINE_NEED_SUPER
the less safe
log_bin_trust_function_creators
variable)
You can't execute a prepared
statement which has an open
1420 HY000 ER_EXEC_STMT_WITH_OPEN_CURSOR
cursor associated with it. Reset the
statement to re-execute it.
The statement (%lu) has no open
1421 HY000 ER_STMT_HAS_NO_OPEN_CURSOR
cursor.
Explicit or implicit commit is not
1422 HY000 ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG allowed in stored function or
trigger.
Field of view '%s.%s' underlying
1423 HY000 ER_NO_DEFAULT_FOR_VIEW_FIELD
table doesn't have a default value
Recursive stored functions and
1424 HY000 ER_SP_NO_RECURSION
triggers are not allowed.
Too big scale %d specified for
1425 42000 ER_TOO_BIG_SCALE
column '%s'. Maximum is %lu.
Too big precision %d specified for
1426 42000 ER_TOO_BIG_PRECISION
column '%s'. Maximum is %lu.
For float(M,D, double(M,D or
1427 42000 ER_M_BIGGER_THAN_D decimal(M,D, M must be >= D
(column '%s').
You can't combine write-locking of
1428 HY000 ER_WRONG_LOCK_OF_SYSTEM_TABLE system tables with other tables or
lock types
Unable to connect to foreign data
1429 HY000 ER_CONNECT_TO_FOREIGN_DATA_SOURCE
source: %s
There was a problem processing
1430 HY000 ER_QUERY_ON_FOREIGN_DATA_SOURCE the query on the foreign data
source. Data source error: %s
The foreign data source you are
1431 HY000 ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST trying to reference does not exist.
Data source error: %s
Can't create federated table. The
1432 HY000 ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE data source connection string '%s'
is not in the correct format
The data source connection string
1433 HY000 ER_FOREIGN_DATA_STRING_INVALID
'%s' is not in the correct format
Can't create federated table.
1434 HY000 ER_CANT_CREATE_FEDERATED_TABLE
Foreign data src error: %s
1435 HY000 ER_TRG_IN_WRONG_SCHEMA Trigger in wrong schema
Thread stack overrun: %ld bytes
used of a %ld byte stack, and %ld
1436 HY000 ER_STACK_OVERRUN_NEED_MORE bytes needed. Use 'mysqld --
thread_stack=#' to specify a bigger
stack.
1437 42000 ER_TOO_LONG_BODY Routine body for '%s' is too long

751/3812
1438 HY000 ER_WARN_CANT_DROP_DEFAULT_KEYCACHE Cannot drop default keycache
Display width out of range for
1439 42000 ER_TOO_BIG_DISPLAYWIDTH
column '%s' (max = %lu)
XAER_DUPID: The XID already
1440 XAE08 ER_XAER_DUPID
exists
Datetime function: %s field
1441 22008 ER_DATETIME_FUNCTION_OVERFLOW
overflow
Can't update table '%s' in stored
function/trigger because it is
1442 HY000 ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
already used by statement which
invoked this stored function/trigger.
The definition of table '%s'
1443 HY000 ER_VIEW_PREVENT_UPDATE prevents operation %s on table
'%s'.
The prepared statement contains a
stored routine call that refers to
that same statement. It's not
1444 HY000 ER_PS_NO_RECURSION
allowed to execute a prepared
statement in such a recursive
manner
Not allowed to set autocommit from
1445 HY000 ER_SP_CANT_SET_AUTOCOMMIT
a stored function or trigger
1446 HY000 ER_MALFORMED_DEFINER Definer is not fully qualified
View '%s'.'%s' has no definer
information (old table format).
1447 HY000 ER_VIEW_FRM_NO_USER
Current user is used as definer.
Please recreate the view!
You need the SUPER privilege for
1448 HY000 ER_VIEW_OTHER_USER creation view with '%s'@'%s'
definer
The user specified as a definer
1449 HY000 ER_NO_SUCH_USER
('%s'@'%s') does not exist
Changing schema from '%s' to '%s'
1450 HY000 ER_FORBID_SCHEMA_CHANGE
is not allowed.
Cannot delete or update a parent
1451 23000 ER_ROW_IS_REFERENCED_2 row: a foreign key constraint fails
(%s)
Cannot add or update a child row:
1452 23000 ER_NO_REFERENCED_ROW_2
a foreign key constraint fails (%s)
Variable '%s' must be quoted with
1453 42000 ER_SP_BAD_VAR_SHADOW
`...`, or renamed
No definer attribute for trigger
'%s'.'%s'. The trigger will be
activated under the authorization of
1454 HY000 ER_TRG_NO_DEFINER the invoker, which may have
insufficient privileges. Please
recreate the trigger.

'%s' has an old format, you should


1455 HY000 ER_OLD_FILE_FORMAT
re-create the '%s' object(s)
Recursive limit %d (as set by the
1456 HY000 ER_SP_RECURSION_LIMIT max_sp_recursion_depth variable)
was exceeded for routine %s
Failed to load routine %s. The
table mysql.proc is missing,
1457 HY000 ER_SP_PROC_TABLE_CORRUPT
corrupt, or contains bad data
(internal code %d)
1458 42000 ER_SP_WRONG_NAME Incorrect routine name '%s'

752/3812
Table upgrade required. Please do
1459 HY000 ER_TABLE_NEEDS_UPGRADE "REPAIR TABLE `%s`" or
dump/reload to fix it!
AGGREGATE is not supported for
1460 42000 ER_SP_NO_AGGREGATE
stored functions
Can't create more than
1461 42000 ER_MAX_PREPARED_STMT_COUNT_REACHED max_prepared_stmt_count
statements (current value: %lu)
1462 HY000 ER_VIEW_RECURSIVE `%s`.`%s` contains view recursion
Non-grouping field '%s' is used in
1463 42000 ER_NON_GROUPING_FIELD_USED
%s clause
The used table type doesn't
1464 HY000 ER_TABLE_CANT_HANDLE_SPKEYS
support SPATIAL indexes
Triggers can not be created on
1465 HY000 ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
system tables
Leading spaces are removed from
1466 HY000 ER_REMOVED_SPACES
name '%s'
Failed to read auto-increment
1467 HY000 ER_AUTOINC_READ_FAILED
value from storage engine
1468 HY000 ER_USERNAME user name
1469 HY000 ER_HOSTNAME host name
String '%s' is too long for %s
1470 HY000 ER_WRONG_STRING_LENGTH
(should be no longer than %d)
The target table %s of the %s is
1471 HY000 ER_NON_INSERTABLE_TABLE
not insertable-into
Table '%s' is differently defined or
1472 HY000 ER_ADMIN_WRONG_MRG_TABLE 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 ''
First character of the FIELDS
TERMINATED string is ambiguous;
1475 HY000 ER_AMBIGUOUS_FIELD_TERM
please use non-optional and non-
empty FIELDS ENCLOSED BY
The foreign server, %s, you are
1476 HY000 ER_FOREIGN_SERVER_EXISTS
trying to create already exists.
The foreign server name you are
1477 HY000 ER_FOREIGN_SERVER_DOESNT_EXIST trying to reference does not exist.
Data source error: %s
Table storage engine '%s' does not
1478 HY000 ER_ILLEGAL_HA_CREATE_OPTION
support the create option '%s'
Syntax error: %s PARTITIONING
1479 HY000 ER_PARTITION_REQUIRES_VALUES_ERROR requires definition of VALUES %s
for each partition
Only %s PARTITIONING can use
1480 HY000 ER_PARTITION_WRONG_VALUES_ERROR
VALUES %s in partition definition
MAXVALUE can only be used in
1481 HY000 ER_PARTITION_MAXVALUE_ERROR
last partition definition
Subpartitions can only be hash
1482 HY000 ER_PARTITION_SUBPARTITION_ERROR
partitions and by key
Must define subpartitions on all
1483 HY000 ER_PARTITION_SUBPART_MIX_ERROR
partitions if on one partition
Wrong number of partitions
1484 HY000 ER_PARTITION_WRONG_NO_PART_ERROR defined, mismatch with previous
setting

753/3812
Wrong number of subpartitions
1485 HY000 ER_PARTITION_WRONG_NO_SUBPART_ERROR defined, mismatch with previous
setting
Constant/Random expression in
1486 HY000 ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR (sub)partitioning function is not
allowed
Constant, random or timezone-
dependent expressions in
1486 HY000 ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
(sub)partitioning function are not
allowed
Expression in RANGE/LIST
1487 HY000 ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR
VALUES must be constant
Field in list of fields for partition
1488 HY000 ER_FIELD_NOT_FOUND_PART_ERROR
function not found in table
List of fields is only allowed in KEY
1489 HY000 ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR
partitions
The partition info in the frm file is
1490 HY000 ER_INCONSISTENT_PARTITION_INFO_ERROR not consistent with what can be
written into the frm file
The %s function returns the wrong
1491 HY000 ER_PARTITION_FUNC_NOT_ALLOWED_ERROR
type
For %s partitions each partition
1492 HY000 ER_PARTITIONS_MUST_BE_DEFINED_ERROR
must be defined
VALUES LESS THAN value must
1493 HY000 ER_RANGE_NOT_INCREASING_ERROR be strictly increasing for each
partition
VALUES value must be of same
1494 HY000 ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
type as partition function
Multiple definition of same constant
1495 HY000 ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR
in list partitioning
Partitioning can not be used stand-
1496 HY000 ER_PARTITION_ENTRY_ERROR
alone in query
The mix of handlers in the
1497 HY000 ER_MIX_HANDLER_ERROR partitions is not allowed in this
version of MariaDB
For the partitioned engine it is
1498 HY000 ER_PARTITION_NOT_DEFINED_ERROR
necessary to define all %s
Too many partitions (including
1499 HY000 ER_TOO_MANY_PARTITIONS_ERROR
subpartitions) were defined

Error
SQLSTATE Error Description
Code
It is only possible to mix
RANGE/LIST partitioning with
1500 HY000 ER_SUBPARTITION_ERROR
HASH/KEY partitioning for
subpartitioning
Failed to create specific handler
1501 HY000 ER_CANT_CREATE_HANDLER_FILE
file
A BLOB field is not allowed in
1502 HY000 ER_BLOB_FIELD_IN_PART_FUNC_ERROR
partition function

A %s must include all columns in


1503 HY000 ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF
the table's partitioning function
Number of %s = 0 is not an
1504 HY000 ER_NO_PARTS_ERROR
allowed value
Partition management on a not
1505 HY000 ER_PARTITION_MGMT_ON_NONPARTITIONED
partitioned table is not possible

754/3812
Foreign key clause is not yet
1506 HY000 ER_FOREIGN_KEY_ON_PARTITIONED supported in conjunction with
partitioning
1507 HY000 ER_DROP_PARTITION_NON_EXISTENT Error in list of partitions to %s
Cannot remove all partitions, use
1508 HY000 ER_DROP_LAST_PARTITION
DROP TABLE instead
COALESCE PARTITION can only
1509 HY000 ER_COALESCE_ONLY_ON_HASH_PARTITION
be used on HASH/KEY partitions
REORGANIZE PARTITION can
only be used to reorganize
1510 HY000 ER_REORG_HASH_ONLY_ON_SAME_N
partitions not to change their
numbers
REORGANIZE PARTITION
without parameters can only be
1511 HY000 ER_REORG_NO_PARAM_ERROR
used on auto-partitioned tables
using HASH PARTITIONs
%s PARTITION can only be used
1512 HY000 ER_ONLY_ON_RANGE_LIST_PARTITION
on RANGE/LIST partitions
Trying to Add partition(s) with
1513 HY000 ER_ADD_PARTITION_SUBPART_ERROR
wrong number of subpartitions
At least one partition must be
1514 HY000 ER_ADD_PARTITION_NO_NEW_PARTITION
added
At least one partition must be
1515 HY000 ER_COALESCE_PARTITION_NO_PARTITION
coalesced
More partitions to reorganize than
1516 HY000 ER_REORG_PARTITION_NOT_EXIST
there are partitions

1517 HY000 ER_SAME_NAME_PARTITION Duplicate partition name %s


It is not allowed to shut off binlog
1518 HY000 ER_NO_BINLOG_ERROR
on this command
When reorganizing a set of
1519 HY000 ER_CONSECUTIVE_REORG_PARTITIONS partitions they must be in
consecutive order
Reorganize of range partitions
cannot change total ranges except
1520 HY000 ER_REORG_OUTSIDE_RANGE
for last partition where it can
extend the range
Partition function not supported in
1521 HY000 ER_PARTITION_FUNCTION_FAILURE
this version for this handler
Partition state cannot be defined
1522 HY000 ER_PART_STATE_ERROR
from CREATE/ALTER TABLE
The %s handler only supports 32
1523 HY000 ER_LIMITED_PART_RANGE
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'
Table has no partition for value
1526 HY000 ER_NO_PARTITION_FOR_GIVEN_VALUE
%s
It is not allowed to specify %s
1527 HY000 ER_FILEGROUP_OPTION_ONLY_ONCE
more than once
1528 HY000 ER_CREATE_FILEGROUP_FAILED Failed to create %s
1529 HY000 ER_DROP_FILEGROUP_FAILED Failed to drop %s
The handler doesn't support
1530 HY000 ER_TABLESPACE_AUTO_EXTEND_ERROR
autoextend of tablespaces
A size parameter was incorrectly
1531 HY000 ER_WRONG_SIZE_NUMBER specified, either number or on the
form 10M

755/3812
The size number was correct but
1532 HY000 ER_SIZE_OVERFLOW_ERROR we don't allow the digit part to be
more than 2 billion
1533 HY000 ER_ALTER_FILEGROUP_FAILED Failed to alter: %s
Writing one row to the row-based
1534 HY000 ER_BINLOG_ROW_LOGGING_FAILED
binary log failed
Table definition on master and
1535 HY000 ER_BINLOG_ROW_WRONG_TABLE_DEF
slave does not match: %s
Slave running with --log-slave-
updates must use row-based
1536 HY000 ER_BINLOG_ROW_RBR_TO_SBR binary logging to be able to
replicate row-based binary log
events
1537 HY000 ER_EVENT_ALREADY_EXISTS Event '%s' already exists
Failed to store event %s. Error
1538 HY000 ER_EVENT_STORE_FAILED
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
INTERVAL is either not positive or
1542 HY000 ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG
too big
ENDS is either invalid or before
1543 HY000 ER_EVENT_ENDS_BEFORE_STARTS
STARTS
Event execution time is in the past.
1544 HY000 ER_EVENT_EXEC_TIME_IN_THE_PAST
Event has been disabled
1545 HY000 ER_EVENT_OPEN_TABLE_FAILED Failed to open mysql.event
1546 HY000 ER_EVENT_NEITHER_M_EXPR_NOR_M_AT No datetime expression provided
Column count of mysql.%s is
1547 HY000 ER_COL_COUNT_DOESNT_MATCH_CORRUPTED wrong. Expected %d, found %d.
The table is probably corrupted
Cannot load from mysql.%s. The
1548 HY000 ER_CANNOT_LOAD_FROM_TABLE
table is probably corrupted
Failed to delete the event from
1549 HY000 ER_EVENT_CANNOT_DELETE
mysql.event
Error during compilation of event's
1550 HY000 ER_EVENT_COMPILE_ERROR
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


Cannot drop index '%s': needed in
1553 HY000 ER_DROP_INDEX_FK
a foreign key constraint
The syntax '%s' is deprecated and
1554 HY000 ER_WARN_DEPRECATED_SYNTAX_WITH_VER will be removed in MariaDB %s.
Please use %s instead
You can't write-lock a log table.
1555 HY000 ER_CANT_WRITE_LOCK_LOG_TABLE
Only read access is possible
You can't use locks with log
1556 HY000 ER_CANT_LOCK_LOG_TABLE
tables.
Upholding foreign key constraints
1557 23000 ER_FOREIGN_DUPLICATE_KEY for table '%s', entry '%s', key %d
would lead to a duplicate entry
Column count of mysql.%s is
wrong. Expected %d, found %d.
1558 HY000 ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE Created with MariaDB %d, now
running %d. Please use
mysql_upgrade to fix this error.

756/3812
Cannot switch out of the row-
based binary log format when the
1559 HY000 ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
session has open temporary
tables
Cannot change the binary logging
ER_STORED_FUNCTION_
1560 HY000 format inside a stored function or
PREVENTS_SWITCH_BINLOG_FORMAT
trigger
1561 ER_UNUSED_13 You should never see it
Cannot create temporary table
1562 HY000 ER_PARTITION_NO_TEMPORARY
with partitions
Partition constant is out of partition
1563 HY000 ER_PARTITION_CONST_DOMAIN_ERROR
function domain
This partition function is not
1564 HY000 ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
allowed
1565 HY000 ER_DDL_LOG_ERROR Error in DDL log
Not allowed to use NULL value in
1566 HY000 ER_NULL_IN_VALUES_LESS_THAN
VALUES LESS THAN
1567 HY000 ER_WRONG_PARTITION_NAME Incorrect partition name
Transaction isolation level can't be
1568 25001 ER_CANT_CHANGE_TX_ISOLATION changed while a transaction is in
progress
ALTER TABLE causes
auto_increment resequencing,
1569 HY000 ER_DUP_ENTRY_AUTOINCREMENT_CASE
resulting in duplicate entry '%s' for
key '%s'
1570 HY000 ER_EVENT_MODIFY_QUEUE_ERROR Internal scheduler error %d
Error during starting/stopping of
1571 HY000 ER_EVENT_SET_VAR_ERROR
the scheduler. Error code %u
Engine cannot be used in
1572 HY000 ER_PARTITION_MERGE_ERROR
partitioned tables
1573 HY000 ER_CANT_ACTIVATE_LOG Cannot activate '%s' log
The server was not built with row-
1574 HY000 ER_RBR_NOT_AVAILABLE
based replication
1575 HY000 ER_BASE64_DECODE_ERROR Decoding of base64 string failed
Recursion of EVENT DDL
1576 HY000 ER_EVENT_RECURSION_FORBIDDEN statements is forbidden when body
is present
Cannot proceed because system
tables used by Event Scheduler
1577 HY000 ER_EVENTS_DB_ERROR
were found damaged at server
start
Only integers allowed as number
1578 HY000 ER_ONLY_INTEGERS_ALLOWED
here
This storage engine cannot be
1579 HY000 ER_UNSUPORTED_LOG_ENGINE
used for log tables"

You cannot '%s' a log table if


1580 HY000 ER_BAD_LOG_STATEMENT
logging is enabled
Cannot rename '%s'. When
logging enabled, rename to/from
1581 HY000 ER_CANT_RENAME_LOG_TABLE log table must rename two tables:
the log table to an archive table
and another table back to '%s'
Incorrect parameter count in the
1582 42000 ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
call to native function '%s'
Incorrect parameters in the call to
1583 42000 ER_WRONG_PARAMETERS_TO_NATIVE_FCT
native function '%s'
757/3812
Incorrect parameters in the call to
1584 42000 ER_WRONG_PARAMETERS_TO_STORED_FCT
stored function '%s'
This function '%s' has the same
1585 HY000 ER_NATIVE_FCT_NAME_COLLISION
name as a native function
1586 23000 ER_DUP_ENTRY_WITH_KEY_NAME Duplicate entry '%s' for key '%s'
Too many files opened, please
1587 HY000 ER_BINLOG_PURGE_EMFILE
execute the command again
Event execution time is in the past
and ON COMPLETION NOT
1588 HY000 ER_EVENT_CANNOT_CREATE_IN_THE_PAST PRESERVE is set. The event was
dropped immediately after
creation.
Event execution time is in the past
and ON COMPLETION NOT
1589 HY000 ER_EVENT_CANNOT_ALTER_IN_THE_PAST PRESERVE is set. The event was
dropped immediately after
creation.
The incident %s occured on the
1590 HY000 ER_SLAVE_INCIDENT
master. Message: %s
Table has no partition for some
1591 HY000 ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT
existing values
Unsafe statement written to the
binary log using statement format
1592 HY000 ER_BINLOG_UNSAFE_STATEMENT
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
Binary logging not possible.
1598 HY000 ER_BINLOG_LOGGING_IMPOSSIBLE
Message: %s
View `%s`.`%s` has no creation
1599 HY000 ER_VIEW_NO_CREATION_CTX
context

Error
SQLSTATE Error Description
Code
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
ER_NO_FORMAT_DESCRIPTION_EVENT The BINLOG statement of type `%s` was not preceded
1609 HY000 _BEFORE_BINLOG_STATEMENT 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
XA_RBTIMEOUT: Transaction branch was rolled
1613 XA106 ER_XA_RBTIMEOUT
back: took too long
XA_RBDEADLOCK: Transaction branch was rolled
1614 XA102 ER_XA_RBDEADLOCK
back: deadlock was detected

758/3812
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
%s variable '%s' is read-only. Use SET %s to assign
1621 HY000 ER_VARIABLE_IS_READONLY
the value
Storage engine %s does not support rollback for this
1622 HY000 ER_WARN_ENGINE_TRANSACTION_ROLLBACK statement. Transaction rolled back and must be
restarted
1623 HY000 ER_SLAVE_HEARTBEAT_FAILURE Unexpected master's heartbeat data: %s
The requested value for the heartbeat period is either
1624 HY000 ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE 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)
FUNCTION %s does not exist. Check the 'Function
1630 42000 ER_FUNC_INEXISTENT_NAME_COLLISION 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
SIGNAL/RESIGNAL can only use a CONDITION
1646 HY000 ER_SIGNAL_BAD_CONDITION_TYPE
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'
The requested server id %d clashes with the slave
1650 HY000 ER_SLAVE_IGNORE_SERVER_IDS
startup option --replicate-same-server-id
Query cache is disabled; restart the server with
1651 HY000 ER_QUERY_CACHE_DISABLED
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
Cannot have more than one value for this type of %s
1657 HY000 ER_TOO_MANY_VALUES_ERROR
partitioning

759/3812
Row expressions in VALUES IN only allowed for multi-
1658 HY000 ER_ROW_SINGLE_PARTITION_FIELD_ERROR
field column partitioning
Field '%s' is of a not allowed type for this type of
1659 HY000 ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
partitioning
1660 HY000 ER_PARTITION_FIELDS_TOO_LONG The total length of the partitioning fields is too large
Cannot execute statement: impossible to write to
1661 HY000 ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE binary log since both row-incapable engines and
statement-incapable engines are involved.
Cannot execute statement: impossible to write to
binary log since BINLOG_FORMAT = ROW and at
1662 HY000 ER_BINLOG_ROW_MODE_AND_STMT_ENGINE least one table uses a storage engine limited to
statement-based logging.

Cannot execute statement: impossible to write to


binary log since statement is unsafe, storage engine is
1663 HY000 ER_BINLOG_UNSAFE_AND_STMT_ENGINE
limited to statement-based logging, and
BINLOG_FORMAT = MIXED. %s
Cannot execute statement: impossible to write to
binary log since statement is in row format and at least
1664 HY000 ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE
one table uses a storage engine limited to statement-
based logging.
Cannot execute statement: impossible to write to
binary log since BINLOG_FORMAT = STATEMENT
1665 HY000 ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
and at least one table uses a storage engine limited to
row-based logging.%s
Cannot execute statement: impossible to write to
1666 HY000 ER_BINLOG_ROW_INJECTION_AND_STMT_MODE binary log since statement is in row format and
BINLOG_FORMAT = STATEMENT.
Cannot execute statement: impossible to write to
ER_BINLOG_MULTIPLE_ENGINES
1667 HY000 binary log since more than one engine is involved and
_AND_SELF_LOGGING_ENGINE
at least one engine is self-logging.
The statement is unsafe because it uses a LIMIT
1668 HY000 ER_BINLOG_UNSAFE_LIMIT clause. This is unsafe because the set of rows
included cannot be predicted.
The statement is unsafe because it uses INSERT
1669 HY000 ER_BINLOG_UNSAFE_INSERT_DELAYED DELAYED. This is unsafe because the times when
rows are inserted cannot be predicted.
The statement is unsafe because it uses the general
log, slow query log, or performance_schema table(s).
1670 HY000 ER_BINLOG_UNSAFE_SYSTEM_TABLE
This is unsafe because system tables may differ on
slaves.
Statement is unsafe because it invokes a trigger or a
stored function that inserts into an
1671 HY000 ER_BINLOG_UNSAFE_AUTOINC_COLUMNS
AUTO_INCREMENT column. Inserted values cannot
be logged correctly.
Statement is unsafe because it uses a UDF which may
1672 HY000 ER_BINLOG_UNSAFE_UDF
not return the same value on the slave.
Statement is unsafe because it uses a system variable
1673 HY000 ER_BINLOG_UNSAFE_SYSTEM_VARIABLE
that may have a different value on the slave.
Statement is unsafe because it uses a system function
1674 HY000 ER_BINLOG_UNSAFE_SYSTEM_FUNCTION
that may return a different value on the slave.
Statement is unsafe because it accesses a non-
1675 HY000 ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS transactional table after accessing a transactional
table within the same transaction.

1676 HY000 ER_MESSAGE_AND_STATEMENT %s Statement: %s


Column %d of table '%s.%s' cannot be converted from
1677 HY000 ER_SLAVE_CONVERSION_FAILED
type '%s' to type '%s'
1678 HY000 ER_SLAVE_CANT_CREATE_CONVERSION Can't create conversion table for table '%s.%s'
ER_INSIDE_TRANSACTION Cannot modify @@session.binlog_format inside a
1679 HY000
_PREVENTS_SWITCH_BINLOG_FORMAT transaction
1680 HY000 ER_PATH_LENGTH The path specified for %s is too long.
'%s' is deprecated and will be removed in a future
1681 HY000 ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT
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.

760/3812
Table '%s'.'%s' was skipped since its definition is
1684 HY000 ER_WARN_I_S_SKIPPED_TABLE
being modified by concurrent DDL statement
Cannot modify
ER_INSIDE_TRANSACTION
1685 HY000 @@session.binlog_direct_non_transactional_updates
_PREVENTS_SWITCH_BINLOG_DIRECT
inside a transaction
ER_STORED_FUNCTION_PREVENTS Cannot change the binlog direct flag inside a stored
1686 HY000
_SWITCH_BINLOG_DIRECT function or trigger
A SPATIAL index may only contain a geometrical type
1687 42000 ER_SPATIAL_MUST_HAVE_GEOM_COL
column
1688 HY000 ER_TOO_LONG_INDEX_COMMENT Comment for index '%s' is too long (max = %lu)
Wait on a lock was aborted due to a pending exclusive
1689 HY000 ER_LOCK_ABORTED
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
ER_BINLOG_UNSAFE_MULTIPLE_ENGINES Mixing self-logging and non-self-logging engines in a
1692 HY000
_AND_SELF_LOGGING_ENGINE statement is unsafe.
Statement accesses nontransactional table as well as
1693 HY000 ER_BINLOG_UNSAFE_MIXED_STATEMENT transactional or temporary table, and writes to any of
them.
ER_INSIDE_TRANSACTION_ Cannot modify @@session.sql_log_bin inside a
1694 HY000
PREVENTS_SWITCH_SQL_LOG_BIN transaction
ER_STORED_FUNCTION_ Cannot change the sql_log_bin inside a stored
1695 HY000
PREVENTS_SWITCH_SQL_LOG_BIN 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'
SET PASSWORD has no significance for users
1699 HY000 ER_SET_PASSWORD_AUTH_PLUGIN
authenticating via plugins

Error
SQLSTATE Error Description
Code
GRANT with IDENTIFIED WITH is illegal
1700 HY000 ER_GRANT_PLUGIN_USER_EXISTS
because the user %-.*s already exists
Cannot truncate a table referenced in a foreign
1701 42000 ER_TRUNCATE_ILLEGAL_FK
key constraint (%s)
Plugin '%s' is force_plus_permanent and can
1702 HY000 ER_PLUGIN_IS_PERMANENT
not be unloaded
The requested value for the heartbeat period is
less than 1 millisecond. The value is reset to 0,
1703 HY000 ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN
meaning that heartbeating will effectively be
disabled.
The requested value for the heartbeat period
exceeds the value of slave_net_timeout
1704 HY000 ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX
seconds. A sensible value for the period should
be less than the timeout.
Multi-row statements required more than
1705 HY000 ER_STMT_CACHE_FULL 'max_binlog_stmt_cache_size' bytes of storage;
increase this mysqld variable and try again
Primary key/partition key update is not allowed
1706 HY000 ER_MULTI_UPDATE_KEY_CONFLICT since the table is updated both as '%s' and
'%s'.
Table rebuild required. Please do "ALTER
1707 HY000 ER_TABLE_NEEDS_REBUILD
TABLE `%s` FORCE" or dump/reload to fix it!
The value of '%s' should be no less than the
1708 HY000 WARN_OPTION_BELOW_LIMIT
value of '%s'
Index column size too large. The maximum
1709 HY000 ER_INDEX_COLUMN_TOO_LONG
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 record is too big.
INSERT IGNORE... SELECT is unsafe because
the order in which rows are retrieved by the
1714 HY000 ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT SELECT determines which (if any) rows are
ignored. This order cannot be predicted and
may differ on master and the slave.

761/3812
INSERT... SELECT... ON DUPLICATE KEY
UPDATE is unsafe because the order in which
rows are retrieved by the SELECT determines
1715 HY000 ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE
which (if any) rows are updated. This order
cannot be predicted and may differ on master
and the slave.
REPLACE... SELECT is unsafe because the
order in which rows are retrieved by the
1716 HY000 ER_BINLOG_UNSAFE_REPLACE_SELECT SELECT determines which (if any) rows are
replaced. This order cannot be predicted and
may differ on master and the slave.
CREATE... IGNORE SELECT is unsafe
because the order in which rows are retrieved
1717 HY000 ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT by the SELECT determines which (if any) rows
are ignored. This order cannot be predicted
and may differ on master and the slave.
CREATE... REPLACE SELECT is unsafe
because the order in which rows are retrieved
1718 HY000 ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT by the SELECT determines which (if any) rows
are replaced. This order cannot be predicted
and may differ on master and the slave.
UPDATE IGNORE is unsafe because the order
in which rows are updated determines which (if
1719 HY000 ER_BINLOG_UNSAFE_UPDATE_IGNORE 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
Statements writing to a table with an auto-
increment column after selecting from another
table are unsafe because the order in which
1722 HY000 ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT rows are retrieved determines what (if any)
rows will be written. This order cannot be
predicted and may differ on master and the
slave.
CREATE TABLE... SELECT... on a table with an
auto-increment column is unsafe because the
order in which rows are retrieved by the
1723 HY000 ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC
SELECT determines which (if any) rows are
inserted. This order cannot be predicted and
may differ on master and the slave.
INSERT... ON DUPLICATE KEY UPDATE on a
1724 HY000 ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
table with more than one UNIQUE KEY is unsafe
1725 HY000 ER_TABLE_IN_FK_CHECK Table is being used in foreign key check.
Storage engine '%s' does not support system
1726 HY000 ER_UNSUPPORTED_ENGINE
tables. [%s.%s]
INSERT into autoincrement field which is not the
1727 HY000 ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST first part in the composed primary key is
unsafe.
Cannot load from %s.%s. The table is probably
1728 HY000 ER_CANNOT_LOAD_FROM_TABLE_V2
corrupted
The requested value %s for the master delay
1729 HY000 ER_MASTER_DELAY_VALUE_OUT_OF_RANGE
exceeds the maximum %u
Only Format_description_log_event and row
1730 HY000 ER_ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT events are allowed in BINLOG statements (but
%s was provided
Non matching attribute '%s' between partition
1731 HY000 ER_PARTITION_EXCHANGE_DIFFERENT_OPTION
and table
Table to exchange with partition is partitioned:
1732 HY000 ER_PARTITION_EXCHANGE_PART_TABLE
'%s'
Table to exchange with partition is temporary:
1733 HY000 ER_PARTITION_EXCHANGE_TEMP_TABLE
'%s'
Subpartitioned table, use subpartition instead
1734 HY000 ER_PARTITION_INSTEAD_OF_SUBPARTITION
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
Option binlog_cache_size (%lu) is greater than
max_binlog_cache_size (%lu); setting
1738 HY000 ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX
binlog_cache_size equal to
max_binlog_cache_size.
Cannot use %s access on index '%s' due to
1739 HY000 ER_WARN_INDEX_NOT_APPLICABLE
type or collation conversion on field '%s'
Table to exchange with partition has foreign key
1740 HY000 ER_PARTITION_EXCHANGE_FOREIGN_KEY
references: '%s'

762/3812
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
Replication event checksum verification failed
1743 HY000 ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE
while reading from network.
Replication event checksum verification failed
1744 HY000 ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE
while reading from a log file.
Option binlog_stmt_cache_size (%lu) is greater
than max_binlog_stmt_cache_size (%lu);
1745 HY000 ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX
setting binlog_stmt_cache_size equal to
max_binlog_stmt_cache_size.
Can't update table '%s' while '%s' is being
1746 HY000 ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT
created.
1747 HY000 ER_PARTITION_CLAUSE_ON_NONPARTITIONED PARTITION () clause on non partitioned table
Found a row not matching the given partition
1748 HY000 ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET
set
1749 HY000 ER_NO_SUCH_PARTITION_UNUSED partition '%s' doesn't exist
Failure while changing the type of replication
1750 HY000 ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE repository: %s.

The creation of some temporary tables could


1751 HY000 ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE
not be rolled back.
Some temporary tables were dropped, but
1752 HY000 ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE
these operations could not be rolled back.
%s is not supported in multi-threaded slave
1753 HY000 ER_MTS_FEATURE_IS_NOT_SUPPORTED
mode. %s
The number of modified databases exceeds the
1754 HY000 ER_MTS_UPDATED_DBS_GREATER_MAX maximum %d; the database names will not be
included in the replication event metadata.
Cannot execute the current event group in the
parallel mode. Encountered event %s, relay-log
1755 HY000 ER_MTS_CANT_PARALLEL name %s, position %s which prevents execution
of this event group in parallel mode. Reason:
%s.
1756 HY000 ER_MTS_INCONSISTENT_DATA %s
FULLTEXT index is not supported for
1757 HY000 ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING
partitioned tables.
1758 35000 ER_DA_INVALID_CONDITION_NUMBER Invalid condition number
Sending passwords in plain text without
1759 HY000 ER_INSECURE_PLAIN_TEXT
SSL/TLS is extremely insecure.
Storing MySQL user name or password
information in the master info repository is not
secure and is therefore not recommended.
1760 HY000 ER_INSECURE_CHANGE_MASTER Please consider using the USER and
PASSWORD connection options for START
SLAVE; see the 'START SLAVE Syntax' in the
MySQL Manual for more information.
Foreign key constraint for table '%s', record
1761 23000 ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO '%s' would lead to a duplicate entry in table
'%s', key '%s'
Foreign key constraint for table '%s', record
1762 23000 ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO '%s' would lead to a duplicate entry in a child
table
Setting authentication options is not possible
1763 HY000 ER_SQLTHREAD_WITH_SECURE_SLAVE when only the Slave SQL Thread is being
started.
The table does not have FULLTEXT index to
1764 HY000 ER_TABLE_HAS_NO_FT
support this query
The system variable %s cannot be set in stored
1765 HY000 ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER
functions or triggers.
The system variable %s cannot be set when
1766 HY000 ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION
there is an ongoing transaction.
The system variable @@SESSION.GTID_NEXT
1767 HY000 ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST has the value %s, which is not listed in
@@SESSION.GTID_NEXT_LIST.
The system variable @@SESSION.GTID_NEXT
1768 HY000 ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION_WHEN_GTID_NEXT_LIST_IS_NULL
cannot change inside a transaction.
The statement 'SET %s' cannot invoke a stored
1769 HY000 ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION
function.
The system variable @@SESSION.GTID_NEXT
1770 HY000 ER_GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL cannot be 'AUTOMATIC' when
@@SESSION.GTID_NEXT_LIST is non-NULL.
Skipping transaction %s because it has already
1771 HY000 ER_SKIPPING_LOGGED_TRANSACTION
been executed and logged.

763/3812
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'.
Impossible to generate Global Transaction
Identifier: the integer component reached the
1775 HY000 ER_GNO_EXHAUSTED
maximal value. Restart the server with a new
server_uuid.
Parameters MASTER_LOG_FILE,
MASTER_LOG_POS, RELAY_LOG_FILE and
1776 HY000 ER_BAD_SLAVE_AUTO_POSITION
RELAY_LOG_POS cannot be set when
MASTER_AUTO_POSITION is active.
CHANGE MASTER TO
MASTER_AUTO_POSITION = 1 can only be
1777 HY000 ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON
executed when @@GLOBAL.GTID_MODE =
ON.
Cannot execute statements with implicit commit
1778 HY000 ER_CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET inside a transaction when
@@SESSION.GTID_NEXT != AUTOMATIC.
GTID_MODE = ON or GTID_MODE =
1779 HY000 ER_GTID_MODE_2_OR_3_REQUIRES_DISABLE_GTID_UNSAFE_STATEMENTS_ON UPGRADE_STEP_2 requires
DISABLE_GTID_UNSAFE_STATEMENTS = 1.
@@GLOBAL.GTID_MODE = ON or
UPGRADE_STEP_2 requires
1779 HY000 ER_GTID_MODE_2_OR_3_REQUIRES_ENFORCE_GTID_CONSISTENCY_ON
@@GLOBAL.ENFORCE_GTID_CONSISTENCY
= 1.
@@GLOBAL.GTID_MODE = ON or
1780 HY000 ER_GTID_MODE_REQUIRES_BINLOG UPGRADE_STEP_1 or UPGRADE_STEP_2
requires --log-bin and --log-slave-updates.
@@SESSION.GTID_NEXT cannot be set to
1781 HY000 ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF UUID:NUMBER when
@@GLOBAL.GTID_MODE = OFF.
@@SESSION.GTID_NEXT cannot be set to
1782 HY000 ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON ANONYMOUS when @@GLOBAL.GTID_MODE
= ON.
@@SESSION.GTID_NEXT_LIST cannot be set
1783 HY000 ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF to a non-NULL value when
@@GLOBAL.GTID_MODE = OFF.
Found a Gtid_log_event or
1784 HY000 ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF Previous_gtids_log_event when
@@GLOBAL.GTID_MODE = OFF.

When
@@GLOBAL.ENFORCE_GTID_CONSISTENCY
= 1, updates to non-transactional tables can
1785 HY000 ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE only be done in either autocommitted
statements or single-statement transactions,
and never in the same statement as updates to
transactional tables.
CREATE TABLE ... SELECT is forbidden when
1786 HY000 ER_GTID_UNSAFE_CREATE_SELECT @@GLOBAL.ENFORCE_GTID_CONSISTENCY
= 1.
When
@@GLOBAL.ENFORCE_GTID_CONSISTENCY
= 1, the statements CREATE TEMPORARY
1787 HY000 ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION
TABLE and DROP TEMPORARY TABLE can
be executed in a non-transactional context only,
and require that AUTOCOMMIT = 1.
The value of @@GLOBAL.GTID_MODE can
only change one step at a time: OFF <->
UPGRADE_STEP_1 <-> UPGRADE_STEP_2 <-
1788 HY000 ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME
> ON. Also note that this value must be stepped
up or down simultaneously on all servers; see
the Manual for instructions.
The slave is connecting using CHANGE
MASTER TO MASTER_AUTO_POSITION = 1,
1789 HY000 ER_MASTER_HAS_PURGED_REQUIRED_GTIDS
but the master has purged binary logs
containing GTIDs that the slave requires.
@@SESSION.GTID_NEXT cannot be changed
by a client that owns a GTID. The client owns
1790 HY000 ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID
%s. Ownership is released on COMMIT or
ROLLBACK.
1791 HY000 ER_UNKNOWN_EXPLAIN_FORMAT Unknown EXPLAIN format name: '%s'
Cannot execute statement in a READ ONLY
1792 25006 ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
transaction.
Comment for table partition '%s' is too long
1793 HY000 ER_TOO_LONG_TABLE_PARTITION_COMMENT
(max = %lu

764/3812
Slave is not configured or failed to initialize
properly. You must at least set --server-id to
1794 HY000 ER_SLAVE_CONFIGURATION enable either a master or a slave. Additional
error messages can be found in the MySQL
error log.
InnoDB presently supports one FULLTEXT
1795 HY000 ER_INNODB_FT_LIMIT
index creation at a time
Cannot create FULLTEXT index on temporary
1796 HY000 ER_INNODB_NO_FT_TEMP_TABLE
InnoDB table
Column '%s' is of wrong type for an InnoDB
1797 HY000 ER_INNODB_FT_WRONG_DOCID_COLUMN
FULLTEXT index
Index '%s' is of wrong type for an InnoDB
1798 HY000 ER_INNODB_FT_WRONG_DOCID_INDEX
FULLTEXT index
Creating index '%s' required more than
1799 HY000 ER_INNODB_ONLINE_LOG_TOO_BIG 'innodb_online_alter_log_max_size' bytes of
modification log. Please try again.

Error
SQLSTATE Error Description
Code
1800 HY000 ER_UNKNOWN_ALTER_ALGORITHM Unknown ALGORITHM '%s'
1801 HY000 ER_UNKNOWN_ALTER_LOCK Unknown LOCK type '%s'
CHANGE MASTER cannot be
executed when the slave was
stopped with an error or killed in
1802 HY000 ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS
MTS mode. Consider using
RESET SLAVE or START
SLAVE UNTIL.
Cannot recover after SLAVE
errored out in parallel execution
1803 HY000 ER_MTS_RECOVERY_FAILURE mode. Additional error messages
can be found in the MySQL error
log.
Cannot clean up worker info
tables. Additional error
1804 HY000 ER_MTS_RESET_WORKERS
messages can be found in the
MySQL error log.
Column count of %s.%s is
1805 HY000 ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 wrong. Expected %d, found %d.
The table is probably corrupted
Slave must silently retry current
1806 HY000 ER_SLAVE_SILENT_RETRY_TRANSACTION
transaction
There is a foreign key check
1807 HY000 ER_DISCARD_FK_CHECKS_RUNNING 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
Tablespace is missing for table
1812 HY000 ER_TABLESPACE_MISSING
'%s'
Tablespace for table '%s' exists.
1813 HY000 ER_TABLESPACE_EXISTS Please DISCARD the tablespace
before IMPORT.
Tablespace has been discarded
1814 HY000 ER_TABLESPACE_DISCARDED
for table '%s'
1815 HY000 ER_INTERNAL_ERROR Internal error: %s
ALTER TABLE '%s' IMPORT
1816 HY000 ER_INNODB_IMPORT_ERROR TABLESPACE failed with error
%lu : '%s'
1817 HY000 ER_INNODB_INDEX_CORRUPT Index corrupt: %s

765/3812
YEAR(%lu) column type is
1818 HY000 ER_INVALID_YEAR_COLUMN_LENGTH deprecated. Creating YEAR(4)
column instead.
Your password does not satisfy
1819 HY000 ER_NOT_VALID_PASSWORD
the current policy requirements
You must SET PASSWORD
1820 HY000 ER_MUST_CHANGE_PASSWORD
before executing this statement
Failed to add the foreign key
constaint. Missing index for
1821 HY000 ER_FK_NO_INDEX_CHILD
constraint '%s' in the foreign
table '%s'
Failed to add the foreign key
constaint. Missing index for
1822 HY000 ER_FK_NO_INDEX_PARENT
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
Failed to open the referenced
1824 HY000 ER_FK_CANNOT_OPEN_PARENT
table '%s'
Failed to add the foreign key
constraint on table '%s'. Incorrect
1825 HY000 ER_FK_INCORRECT_OPTION
options in FOREIGN KEY
constraint '%s'
Duplicate foreign key constraint
1826 HY000 ER_FK_DUP_NAME
name '%s'
The password hash doesn't
have the expected format. Check
1827 HY000 ER_PASSWORD_FORMAT if the correct password algorithm
is being used with the
PASSWORD() function.
Cannot drop column '%s':
1828 HY000 ER_FK_COLUMN_CANNOT_DROP needed in a foreign key
constraint '%s'
Cannot drop column '%s':
1829 HY000 ER_FK_COLUMN_CANNOT_DROP_CHILD needed in a foreign key
constraint '%s' of table '%s'
Column '%s' cannot be NOT
1830 HY000 ER_FK_COLUMN_NOT_NULL NULL: needed in a foreign key
constraint '%s' SET NULL
Duplicate index '%s' defined on
the table '%s.%s'. This is
1831 HY000 ER_DUP_INDEX
deprecated and will be
disallowed in a future release.
Cannot change column '%s':
1832 HY000 ER_FK_COLUMN_CANNOT_CHANGE used in a foreign key constraint
'%s'
Cannot change column '%s':
1833 HY000 ER_FK_COLUMN_CANNOT_CHANGE_CHILD used in a foreign key constraint
'%s' of table '%s'
Cannot delete rows from table
1834 HY000 ER_FK_CANNOT_DELETE_PARENT which is parent in a foreign key
constraint '%s' of table '%s'
Malformed communication
1835 HY000 ER_MALFORMED_PACKET packet.

1836 HY000 ER_READ_ONLY_MODE Running in read-only mode

766/3812
When
@@SESSION.GTID_NEXT is
set to a GTID, you must explicitly
set it to a different value after a
COMMIT or ROLLBACK. Please
1837 HY000 ER_GTID_NEXT_TYPE_UNDEFINED_GROUP
check GTID_NEXT variable
manual page for detailed
explanation. Current
@@SESSION.GTID_NEXT is
'%s'.
The system variable %s cannot
1838 HY000 ER_VARIABLE_NOT_SETTABLE_IN_SP
be set in stored procedures.
@@GLOBAL.GTID_PURGED
can only be set when
1839 HY000 ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF
@@GLOBAL.GTID_MODE =
ON.
@@GLOBAL.GTID_PURGED
can only be set when
1840 HY000 ER_CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY
@@GLOBAL.GTID_EXECUTED
is empty.
@@GLOBAL.GTID_PURGED
can only be set when there are
1841 HY000 ER_CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY
no ongoing transactions (not
even in other clients).
@@GLOBAL.GTID_PURGED
1842 HY000 ER_GTID_PURGED_WAS_CHANGED
was changed from '%s' to '%s'.
@@GLOBAL.GTID_EXECUTED
1843 HY000 ER_GTID_EXECUTED_WAS_CHANGED
was changed from '%s' to '%s'.
Cannot execute statement:
impossible to write to binary log
since BINLOG_FORMAT =
1844 HY000 ER_BINLOG_STMT_MODE_AND_NO_REPL_TABLES
STATEMENT, and both
replicated and non replicated
tables are written to.
%s is not supported for this
1845 0A000 ER_ALTER_OPERATION_NOT_SUPPORTED
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
Partition specific operations do
1848 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION not yet support
LOCK/ALGORITHM
Columns participating in a
1849 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME
foreign key are renamed
Cannot change column type
1850 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE
INPLACE
Adding foreign keys needs
1851 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK
foreign_key_checks=OFF
Creating unique indexes with
IGNORE requires COPY
1852 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_IGNORE
algorithm to remove duplicate
rows
Dropping a primary key is not
1853 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK allowed without also adding a
new primary key
Adding an auto-increment
1854 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC
column requires a lock
Cannot replace hidden
1855 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS FTS_DOC_ID with a user-visible
one
767/3812
Cannot drop or rename
1856 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS
FTS_DOC_ID
Fulltext index creation requires a
1857 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS
lock
sql_slave_skip_counter can not
be set when the server is
running with
@@GLOBAL.GTID_MODE =
1858 HY000 ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_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'
Long database name and
identifier for object resulted in
1860 HY000 ER_IDENT_CAUSES_TOO_LONG_PATH path length exceeding %d
characters. Path: '%s'.

cannot silently convert NULL


1861 HY000 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL values, as required in this
SQL_MODE
Your password has expired. To
log in you must change it using a
1862 HY000 ER_MUST_CHANGE_PASSWORD_LOGIN
client that supports expired
passwords.
Found a row in wrong partition
1863 HY000 ER_ROW_IN_WRONG_PARTITION
%s
Cannot schedule event %s,
relay-log name %s, position %s
1864 HY000 ER_MTS_EVENT_BIGGER_PENDING_JOBS_SIZE_MAX to Worker thread because its
size %lu exceeds %lu of
slave_pending_jobs_size_max.
Cannot CREATE FULLTEXT
1865 HY000 ER_INNODB_NO_FT_USES_PARSER INDEX WITH PARSER on
InnoDB table
The binary log file '%s' is
1866 HY000 ER_BINLOG_LOGICAL_CORRUPTION
logically corrupted: %s
file %s was not purged because
it was being read by %d
1867 HY000 ER_WARN_PURGE_LOG_IN_USE
thread(s), purged only %d out of
%d files.
file %s was not purged because
1868 HY000 ER_WARN_PURGE_LOG_IS_ACTIVE
it is the active log file.
Auto-increment value in
1869 HY000 ER_AUTO_INCREMENT_CONFLICT UPDATE conflicts with internally
generated values
Row events are not logged for
%s statements that modify
1870 HY000 WARN_ON_BLOCKHOLE_IN_RBR
BLACKHOLE tables in row
format. Table(s): '%s'
Slave failed to initialize master
1871 HY000 ER_SLAVE_MI_INIT_REPOSITORY
info structure from the repository
Slave failed to initialize relay log
1872 HY000 ER_SLAVE_RLI_INIT_REPOSITORY
info structure from the repository

Access denied trying to change


1873 28000 ER_ACCESS_DENIED_CHANGE_USER_ERROR to user '%s'@'%s' (using
password: %s). Disconnecting.
1874 HY000 ER_INNODB_READ_ONLY InnoDB is in read only mode.

768/3812
STOP SLAVE command
execution is incomplete: Slave
SQL thread got the stop signal,
1875 HY000 ER_STOP_SLAVE_SQL_THREAD_TIMEOUT
thread is busy, SQL thread will
stop once the current task is
complete.
STOP SLAVE command
execution is incomplete: Slave IO
1876 HY000 ER_STOP_SLAVE_IO_THREAD_TIMEOUT thread got the stop signal, thread
is busy, IO thread will stop once
the current task is complete.
Operation cannot be performed.
1877 HY000 ER_TABLE_CORRUPT The table '%s.%s' is missing,
corrupt or contains bad data.
1878 HY000 ER_TEMP_FILE_WRITE_FAILURE Temporary file write failure.
Upgrade index name failed,
please use create index(alter
1879 HY000 ER_INNODB_FT_AUX_NOT_HEX_ID
table) algorithm copy to rebuild
index.
1880 ER_LAST_MYSQL_ERROR_MESSAGE "

MariaDB-specific error codes


Error
SQLSTATE Error Description
Code
1900 ER_UNUSED_18 "
Function or expression '%s' cannot be
1901 ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
used in the %s clause of %`s
1902 ER_UNUSED_19 "
Primary key cannot be defined upon a
1903 ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN
generated column
Key/Index cannot be defined on a virtual
1904 ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
generated column
Cannot define foreign key with %s clause
1905 ER_WRONG_FK_OPTION_FOR_GENERATED_COLUMN
on a generated column
The value specified for generated
1906 ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN column '%s' in table '%s' has been
ignored
This is not yet supported for generated
1907 ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN
columns
1908 ER_UNUSED_20 "
1909 ER_UNUSED_21 "
%s storage engine does not support
1910 ER_UNSUPPORTED_ENGINE_FOR_GENERATED_COLUMNS
generated columns
1911 ER_UNKNOWN_OPTION Unknown option '%-.64s'
Incorrect value '%-.64s' for option '%-
1912 ER_BAD_OPTION_VALUE
.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
Got overflow when converting '%-.128s'
1916 ER_DATA_OVERFLOW 22003
to %-.32s. Value truncated.
Truncated value '%-.128s' when
1917 ER_DATA_TRUNCATED 22003
converting to %-.32s
Encountered illegal value '%-.128s' when
1918 ER_BAD_DATA 22007
converting to %-.32s
Encountered illegal format of dynamic
1919 ER_DYN_COL_WRONG_FORMAT
column string
Dynamic column implementation limit
1920 ER_DYN_COL_IMPLEMENTATION_LIMIT
reached
Illegal value used as argument of
1921 ER_DYN_COL_DATA 22007
dynamic column function
Dynamic column contains unknown
1922 ER_DYN_COL_WRONG_CHARSET
character set

769/3812
At least one of the 'in_to_exists' or
1923 ER_ILLEGAL_SUBQUERY_OPTIMIZER_SWITCHES 'materialization' optimizer_switch flags
must be 'on'.

Query cache is disabled (resize or similar


1924 ER_QUERY_CACHE_IS_DISABLED command in progress); repeat this
command later
Query cache is globally disabled and you
1925 ER_QUERY_CACHE_IS_GLOBALY_DISABLED
can't enable it only for this session
View '%-.192s'.'%-.192s' ORDER BY
1926 ER_VIEW_ORDERBY_IGNORED 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
Cannot modify
1929 ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION @@session.skip_replication inside a
transaction
Cannot modify
1930 ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION @@session.skip_replication inside a
stored function or trigger
Query execution was interrupted. The
query examined at least %llu rows, which
1931 ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
exceeds LIMIT ROWS EXAMINED (%llu).
The query result may be incomplete.
Table '%-.192s.%-.192s' doesn't exist in
1932 ER_NO_SUCH_TABLE_IN_ENGINE 42S02
engine
Target is not running an EXPLAINable
1933 ER_TARGET_NOT_EXPLAINABLE
command
Connection '%.*s' conflicts with existing
1934 ER_CONNECTION_ALREADY_EXISTS
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
Engine %s failed to discover table %`-
1939 ER_SQL_DISCOVER_ERROR
.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
Could not update replication slave gtid
1942 ER_CANNOT_UPDATE_GTID_STATE
state
GTID %u-%u-%llu and %u-%u-%llu
1943 ER_DUPLICATE_GTID_DOMAIN
conflict (duplicate domain id %u)
1944 ER_GTID_OPEN_TABLE_FAILED Failed to open %s.%s
Connecting slave requested to start from
1945 ER_GTID_POSITION_NOT_FOUND_IN_BINLOG GTID %u-%u-%llu, which is not in the
master's binlog
Failed to load replication slave GTID
1946 ER_CANNOT_LOAD_SLAVE_GTID_STATE
position from table %s.%s
Specified GTID %u-%u-%llu conflicts with
the binary log which contains a more
recent GTID %u-%u-%llu. If
1947 ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG
MASTER_GTID_POS=CURRENT_POS
is used, the binlog position will override
the new value of @@gtid_slave_pos.
Specified value for @@gtid_slave_pos
contains no value for replication domain
%u. This conflicts with the binary log
1948 ER_MASTER_GTID_POS_MISSING_DOMAIN 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.
START SLAVE UNTIL master_gtid_pos
1949 ER_UNTIL_REQUIRES_USING_GTID
requires that slave is using GTID
An attempt was made to binlog GTID %u-
%u-%llu which would create an out-of-
1950 ER_GTID_STRICT_OUT_OF_ORDER order sequence number with existing
GTID %u-%u-%llu, and gtid strict mode is
enabled.
The binlog on the master is missing the
GTID %u-%u-%llu requested by the
1951 ER_GTID_START_FROM_BINLOG_HOLE slave (even though a subsequent
sequence number does exist), and GTID
strict mode is enabled

770/3812
Unexpected GTID received from master
after reconnect. This normally indicates
1952 ER_SLAVE_UNEXPECTED_MASTER_SWITCH
that the master server was replaced
without restarting the slave threads. %s
Cannot modify
@@session.gtid_domain_id or
1953 ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO
@@session.gtid_seq_no inside a
transaction
Cannot modify
@@session.gtid_domain_id or
1954 ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO
@@session.gtid_seq_no inside a stored
function or trigger
Connecting slave requested to start from
GTID %u-%u-%llu, which is not in the
master's binlog. Since the master's
1955 ER_GTID_POSITION_NOT_FOUND_IN_BINLOG2 binlog contains GTIDs with higher
sequence numbers, it probably means
that the slave has diverged due to
executing extra errorneous transactions
This operation is not allowed if any GTID
1956 ER_BINLOG_MUST_BE_EMPTY 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.
Cannot change
1963 ER_CHANGE_SLAVE_PARALLEL_THREADS_ACTIVE @@slave_parallel_threads while another
change is in progress
Commit failed due to failure of an earlier
1964 ER_PRIOR_COMMIT_FAILED
commit on which this one depends
1965 ER_IT_IS_A_VIEW '%-.192s' is a view
When using GTID,
@@sql_slave_skip_counter can not be
used. Instead, setting
1966 ER_SLAVE_SKIP_NOT_IN_GTID
@@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
Query execution was interrupted
1969 ER_STATEMENT_TIMEOUT
(max_statement_time exceeded)
%s does not support subqueries or
1970 ER_SUBQUERIES_NOT_SUPPORTED
stored functions.
The system variable %.200s cannot be
1971 ER_SET_STATEMENT_NOT_SUPPORTED
set in SET STATEMENT.
1972 ER_UNUSED_9 You should never see it
Can't create user '%-.64s'@'%-.64s'; it
1973 ER_USER_CREATE_EXISTS
already exists
Can't drop user '%-.64s'@'%-.64s'; it
1974 ER_USER_DROP_EXISTS
doesn't exist
Can't create role '%-.64s'; it already
1975 ER_ROLE_CREATE_EXISTS
exists
1976 ER_ROLE_DROP_EXISTS Can't drop role '%-.64s'; it doesn't exist
Cannot convert '%s' character 0x%-.64s
1977 ER_CANNOT_CONVERT_CHARACTER
to '%s'
Incorrect default value '%-.128s' for
1978 ER_INVALID_DEFAULT_VALUE_FOR_FIELD
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'

Aggregate function '%-.192s)' of


1981 ER_WARN_AGGFUNC_DEPENDENCE
SELECT #%d belongs to SELECT #%d
<%-.64s> option ignored for InnoDB
1982 WARN_INNODB_PARTITION_OPTION_IGNORED
partition

Error
SQLSTATE Error Description
Code
3000 ER_FILE_CORRUPT File %s is corrupted
771/3812
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
3001 ER_ERROR_ON_MASTER
manually on the slave and then restart the slave
with SET GLOBAL
SQL_SLAVE_SKIP_COUNTER=1; START
SLAVE;. Query:'%s'"
Query caused different errors on master and
slave. Error on master: message (format)='%s'
3002 ER_INCONSISTENT_ERROR 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.
GET STACKED DIAGNOSTICS when handler
3004 ER_GET_STACKED_DA_WITHOUT_ACTIVE_HANDLER 0Z002
not active
%s is no longer supported. The statement was
3005 ER_WARN_LEGACY_SYNTAX_CONVERTED
converted to %s.
Statement is unsafe because it uses a fulltext
3006 ER_BINLOG_UNSAFE_FULLTEXT_PLUGIN parser plugin which may not return the same
value on the slave.
Cannot DISCARD/IMPORT tablespace
3007 ER_CANNOT_DISCARD_TEMPORARY_TABLE
associated with temporary table
Foreign key cascade delete/update exceeds
3008 ER_FK_DEPTH_EXCEEDED
max depth of %d.
Column count of %s.%s is wrong. Expected %d,
found %d. Created with MariaDB %d, now
3009 ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE_V2
running %d. Please use mysql_upgrade to fix this
error.
Trigger %s.%s.%s does not have CREATED
3010 ER_WARN_TRIGGER_DOESNT_HAVE_CREATED
attribute.
Referenced trigger '%s' for the given action time
3011 ER_REFERENCED_TRG_DOES_NOT_EXIST_MYSQL
and event type does not exist.
EXPLAIN FOR CONNECTION command is
3012 ER_EXPLAIN_NOT_SUPPORTED supported only for
SELECT/UPDATE/INSERT/DELETE/REPLACE
3013 ER_INVALID_FIELD_SIZE Invalid size for column '%-.192s'.
Table storage engine '%-.64s' found required
3014 ER_MISSING_HA_CREATE_OPTION
create option missing
3015 ER_ENGINE_OUT_OF_MEMORY Out of memory in storage engine '%-.64s'.
The password for anonymous user cannot be
3016 ER_PASSWORD_EXPIRE_ANONYMOUS_USER
expired.
This operation cannot be performed with a
3017 ER_SLAVE_SQL_THREAD_MUST_STOP running slave sql thread; run STOP SLAVE
SQL_THREAD first
Cannot create FULLTEXT index on materialized
3018 ER_NO_FT_MATERIALIZED_SUBQUERY
subquery
3019 ER_INNODB_UNDO_LOG_FULL Undo Log error: %s
3020 ER_INVALID_ARGUMENT_FOR_LOGARITHM Invalid argument for logarithm
This operation cannot be performed with a
3021 ER_SLAVE_CHANNEL_IO_THREAD_MUST_STOP running slave io thread; run STOP SLAVE
IO_THREAD FOR CHANNEL '%s' first.
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
3022 ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO
are deleted by any replicated DROP statement.
Suggest to wait until slave_open_temp_tables =
0.
CHANGE MASTER TO with a
MASTER_LOG_FILE clause but no
3023 ER_WARN_ONLY_MASTER_LOG_FILE_NO_POS MASTER_LOG_POS clause may not be safe.
The old position value may not be valid for the
new binary log file.

Query execution was interrupted, maximum


3024 ER_QUERY_TIMEOUT
statement execution time exceeded

772/3812
Select is not a read only statement, disabling
3025 ER_NON_RO_SELECT_DISABLE_TIMER
timer
3026 ER_DUP_LIST_ENTRY Duplicate entry '%-.192s'.
'%s' mode no longer has any effect. Use
3027 ER_SQL_MODE_NO_EFFECT STRICT_ALL_TABLES or
STRICT_TRANS_TABLES instead.
Expression #%u of ORDER BY contains
3028 ER_AGGREGATE_ORDER_FOR_UNION
aggregate function and applies to a UNION
Expression #%u of ORDER BY contains
3029 ER_AGGREGATE_ORDER_NON_AGG_QUERY aggregate function and applies to the result of a
non-aggregated query
Slave worker has stopped after at least one
previous worker encountered an error when
slave-preserve-commit-order was enabled. To
3030 ER_SLAVE_WORKER_STOPPED_PREVIOUS_THD_ERROR 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.
slave_preserve_commit_order is not supported
3031 ER_DONT_SUPPORT_SLAVE_PRESERVE_COMMIT_ORDER
%s.
3032 ER_SERVER_OFFLINE_MODE The server is currently in offline mode
Binary geometry function %s given two
3033 ER_GIS_DIFFERENT_SRIDS geometries of different srids: %u and %u, which
should have been identical.
Calling geometry function %s with unsupported
3034 ER_GIS_UNSUPPORTED_ARGUMENT
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.
Unable to calculate centroid because geometry
3039 ER_BOOST_GEOMETRY_CENTROID_EXCEPTION
is empty in function %s.
Geometry overlay calculation error: geometry
3040 ER_BOOST_GEOMETRY_OVERLAY_INVALID_INPUT_EXCEPTION
data is invalid in function %s.
Geometry turn info calculation error: geometry
3041 ER_BOOST_GEOMETRY_TURN_INFO_EXCEPTION
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.
The password provided for the replication user
3056 ER_CHANGE_MASTER_PASSWORD_LENGTH
exceeds the maximum length of 32 characters
3057 42000 ER_USER_LOCK_WRONG_NAME Incorrect user-level lock name '%-.192s'.
Deadlock found when trying to get user-level lock;
3058 ER_USER_LOCK_DEADLOCK try rolling back transaction/releasing locks and
restarting lock acquisition.
REPLACE cannot be executed as it requires
3059 ER_REPLACE_INACCESSIBLE_ROWS
deleting rows that are not in the view

773/3812
Do not support online operation on table with GIS
3060 ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS
index

Error
SQLSTATE Error Description
Code
COM_MULTI can't return a result set in the
4000 0A000 ER_COMMULTI_BADCONTEXT
given context
Command '%s' is not allowed for
4001 ER_BAD_COMMAND_IN_MULTI
COM_MULTI
WITH column list and SELECT field list
4002 ER_WITH_COL_WRONG_LIST have different column counts

4003 ER_TOO_MANY_DEFINITIONS_IN_WITH_CLAUSE Too many WITH elements in WITH clause


Duplicate query name %`-.64s in WITH
4004 ER_DUP_QUERY_NAME
clause
4005 ER_RECURSIVE_WITHOUT_ANCHORS No anchors for recursive WITH element '%s'
Unacceptable mutual recursion with
4006 ER_UNACCEPTABLE_MUTUAL_RECURSION
anchored table '%s'
Reference to recursive WITH table '%s' in
4007 ER_REF_TO_RECURSIVE_WITH_TABLE_IN_DERIVED
materialized derived
Restrictions imposed on recursive
4008 ER_NOT_STANDARD_COMPLIANT_RECURSIVE definitions are violated for table
'%s'"R_WRONG_WINDOW_SPEC_NAME
Window specification with name '%s' is not
4009 ER_WRONG_WINDOW_SPEC_NAME
defined
Multiple window specifications with the
4010 ER_DUP_WINDOW_NAME
same name '%s'
Window specification referencing another
4011 ER_PARTITION_LIST_IN_REFERENCING_WINDOW_SPEC
one '%s' cannot contain partition list
Referenced window specification '%s'
4012 ER_ORDER_LIST_IN_REFERENCING_WINDOW_SPEC
already contains order list
Referenced window specification '%s'
4013 ER_WINDOW_FRAME_IN_REFERENCED_WINDOW_SPEC
cannot contain window frame
Unacceptable combination of window
4014 ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS
frame bound specifications
Window function is allowed only in SELECT
4015 ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION
list and ORDER BY clause
Window function is not allowed in window
4016 ER_WINDOW_FUNCTION_IN_WINDOW_SPEC
specification
4017 ER_NOT_ALLOWED_WINDOW_FRAME Window frame is not allowed with '%s'
No order list in window specification for
4018 ER_NO_ORDER_LIST_IN_WINDOW_SPEC
'%s'
RANGE-type frame requires ORDER BY
4019 ER_RANGE_FRAME_NEEDS_SIMPLE_ORDERBY
clause with single sort key
4020 ER_WRONG_TYPE_FOR_ROWS_FRAME Integer is required for ROWS-type frame
Numeric datatype is required for RANGE-
4021 ER_WRONG_TYPE_FOR_RANGE_FRAME
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


CONSTRAINT %`s failed for %`-.192s.%`-
4025 23000 ER_CONSTRAINT_FAILED
.192s
4026 ER_EXPRESSION_IS_TOO_BIG Expression in the %s clause is too big
Got an error evaluating stored expression
4027 ER_ERROR_EVALUATING_EXPRESSION
%s
Got an error when calculating default value
4028 ER_CALCULATING_DEFAULT_VALUE
for %`s
Expression for field %`-.64s is referring to
4029 ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
uninitialized field %`s
4030 ER_PARTITION_DEFAULT_ERROR Only one DEFAULT partition allowed

774/3812
Referenced trigger '%s' for the given action
4031 ER_REFERENCED_TRG_DOES_NOT_EXIST
time and event type does not exist
Default/ignore value is not supported for
4032 ER_INVALID_DEFAULT_PARAM
such parameter usage
Only row based replication supported for
4033 ER_BINLOG_NON_SUPPORTED_BULK
bulk operations
4034 ER_BINLOG_UNCOMPRESS_ERROR Uncompress the compressed binlog failed
Broken JSON string in argument %d to
4035 ER_JSON_BAD_CHR
function '%s' at position %d
Character disallowed in JSON in argument
4036 ER_JSON_NOT_JSON_CHR
%d to function '%s' at position %d
Unexpected end of JSON text in argument
4037 ER_JSON_EOS
%d to function '%s'
Syntax error in JSON text in argument %d
4038 ER_JSON_SYNTAX
to function '%s' at position %d
Incorrect escaping in JSON text in
4039 ER_JSON_ESCAPING
argument %d to function '%s' at position %d
Limit of %d on JSON nested strucures
4040 ER_JSON_DEPTH depth is reached in argument %d to
function '%s' at position %d
Unexpected end of JSON path in argument
4041 ER_JSON_PATH_EOS
%d to function '%s'
Syntax error in JSON path in argument %d
4042 ER_JSON_PATH_SYNTAX
to function '%s' at position %d
Limit of %d on JSON path depth is reached
4043 ER_JSON_PATH_DEPTH in argument %d to function '%s' at position
%d
Wildcards in JSON path not allowed in
4044 ER_JSON_PATH_NO_WILDCARD
argument %d to function '%s'
JSON path should end with an array
4045 ER_JSON_PATH_ARRAY
identifier in argument %d to function '%s'
Argument 2 to function '%s' must be "one"
4046 ER_JSON_ONE_OR_ALL
or "all".
CREATE TEMPORARY TABLE is not
allowed with
4047 ER_UNSUPPORT_COMPRESSED_TEMPORARY_TABLE
ROW_FORMAT=COMPRESSED or
KEY_BLOCK_SIZE.
Incorrect GeoJSON format specified for
4048 ER_GEOJSON_INCORRECT
st_geomfromgeojson function.
Incorrect GeoJSON format - too few points
4049 ER_GEOJSON_TOO_FEW_POINTS
for linestring specified.
Incorrect GeoJSON format - polygon not
4050 ER_GEOJSON_NOT_CLOSED
closed.
Path expression '$' is not allowed in
4051 ER_JSON_PATH_EMPTY
argument %d to function '%s'.
A slave with the same
4052 ER_SLAVE_SAME_ID 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
Can't execute updates on master with
4056 ER_REQUIRE_ROW_BINLOG_FORMAT
binlog_format != ROW.
MyRocks supports only READ
COMMITTED and REPEATABLE READ
4057 ER_ISOLATION_MODE_NOT_SUPPORTED
isolation levels. Please change from current
isolation level %s
When unique checking is disabled in
MyRocks, INSERT,UPDATE,LOAD
statements with clauses that update or
4058 ER_ON_DUPLICATE_DISABLED
replace the key (i.e. INSERT ON
DUPLICATE KEY UPDATE, REPLACE)
are not allowed. Query: %s

775/3812
Can't execute updates when you started a
transaction with START TRANSACTION
4059 ER_UPDATES_WITH_CONSISTENT_SNAPSHOT
WITH CONSISTENT [ROCKSDB]
SNAPSHOT.
This transaction was rolled back and cannot
be committed. Only supported operation is
4060 ER_ROLLBACK_ONLY to roll it back, so all pending changes will be
discarded. Please restart another
transaction.

MyRocks currently does not support


4061 ER_ROLLBACK_TO_SAVEPOINT ROLLBACK TO SAVEPOINT if modifying
rows.
Only REPEATABLE READ isolation level
is supported for START TRANSACTION
4062 ER_ISOLATION_LEVEL_WITH_CONSISTENT_SNAPSHOT
WITH CONSISTENT SNAPSHOT in
RocksDB Storage Engine.
Unsupported collation on string indexed
4063 ER_UNSUPPORTED_COLLATION
column %s.%s Use binary collation (%s).
Table '%s' does not exist, but metadata
information exists inside MyRocks. This is a
4064 ER_METADATA_INCONSISTENCY sign of data inconsistency. Please check if
'%s.frm' exists, and try to restore it if it does
not exist.
Column family ('%s') flag (%d) is different
4065 ER_CF_DIFFERENT from an existing flag (%d). Assign a new
CF flag, or do not change existing CF flag.
TTL duration (%s) in MyRocks must be an
4066 ER_RDB_TTL_DURATION_FORMAT
unsigned non-null 64-bit integer.
Status error %d received from RocksDB:
4067 ER_RDB_STATUS_GENERAL
%s
%s, Status error %d received from
4068 ER_RDB_STATUS_MSG
RocksDB: %s
TTL support is currently disabled when
4069 ER_RDB_TTL_UNSUPPORTED
table has a hidden PK.
TTL column (%s) in MyRocks must be an
unsigned non-null 64-bit integer, exist inside
4070 ER_RDB_TTL_COL_FORMAT
the table, and have an accompanying ttl
duration.
The per-index column family option has
4071 ER_PER_INDEX_CF_DEPRECATED
been deprecated
MyRocks failed creating new key definitions
4072 ER_KEY_CREATE_DURING_ALTER
during alter.
MyRocks failed populating secondary key
4073 ER_SK_POPULATE_DURING_ALTER
during alter.
Window functions can not be used as
4074 ER_SUM_FUNC_WITH_WINDOW_FUNC_AS_ARG
arguments to group functions.
4075 ER_NET_OK_PACKET_TOO_LARGE OK packet too large
Incorrect GeoJSON format - empty
4076 ER_GEOJSON_EMPTY_COORDINATES
'coordinates' array.
MyRocks doesn't currently support
4077 ER_MYROCKS_CANT_NOPAD_COLLATION
collations with \"No pad\" attribute.
Illegal parameter data types %s and %s for
4078 ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
operation '%s'
Illegal parameter data type %s for operation
4079 ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
'%s'
Incorrect parameter count to cursor '%-
4080 ER_WRONG_PARAMCOUNT_TO_CURSOR
.192s'
Unknown structured system variable or
4081 ER_UNKNOWN_STRUCTURED_VARIABLE
ROW routine variable '%-.*s'
Row variable '%-.192s' does not have a
4082 ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD
field '%-.192s'
END identifier '%-.192s' does not match
4083 ER_END_IDENTIFIER_DOES_NOT_MATCH
'%-.192s'
4084 ER_SEQUENCE_RUN_OUT Sequence '%-.64s.%-.64s' has run out

776/3812
Sequence '%-.64s.%-.64s' values are
4085 ER_SEQUENCE_INVALID_DATA
conflicting
Sequence '%-.64s.%-.64s' table structure is
4086 ER_SEQUENCE_INVALID_TABLE_STRUCTURE
invalid (%s)
4087 ER_SEQUENCE_ACCESS_ERROR Sequence '%-.64s.%-.64s' access error
Sequences requires binlog_format mixed
4088 ER_SEQUENCE_BINLOG_FORMAT
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'
Wrong INSERT into a SEQUENCE. One
can only do single table INSERT into a
4093 ER_WRONG_INSERT_INTO_SEQUENCE 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
Subroutine '%-.192s' is declared in the
4095 ER_PACKAGE_ROUTINE_IN_SPEC_NOT_DEFINED_IN_BODY package specification but is not defined in
the package body
Subroutine '%-.192s' has a forward
4096 ER_PACKAGE_ROUTINE_FORWARD_DECLARATION_NOT_DEFINED
declaration but is not defined
Compressed column '%-.192s' can't be
4097 ER_COMPRESSED_COLUMN_USED_AS_KEY
used in key specification
4098 ER_UNKNOWN_COMPRESSION_METHOD Unknown compression method: %s
The used table value constructor has a
4099 ER_WRONG_NUMBER_OF_VALUES_IN_TVC
different number of values
Field reference '%-.192s' can't be used in
4100 ER_FIELD_REFERENCE_IN_TVC
table value constructor
Numeric datatype is required for %s
4101 ER_WRONG_TYPE_FOR_PERCENTILE_FUNC
function
Argument to the %s function is not a
4102 ER_ARGUMENT_NOT_CONSTANT
constant for a partition
Argument to the %s function does not
4103 ER_ARGUMENT_OUT_OF_RANGE
belong to the range [0,1]
%s function only accepts arguments that
4104 ER_WRONG_TYPE_OF_ARGUMENT
can be converted to numerical types
Aggregate specific instruction (FETCH
4105 ER_NOT_AGGREGATE_FUNCTION GROUP NEXT ROW) used in a wrong
context
Aggregate specific instruction(FETCH
4106 ER_INVALID_AGGREGATE_FUNCTION GROUP NEXT ROW) missing from the
aggregate function
4107 ER_INVALID_VALUE_TO_LIMIT Limit only accepts integer values
Invisible column %`s must have a default
4108 ER_INVISIBLE_NOT_NULL_WITHOUT_DEFAULT
value
Rows matched: %ld Changed: %ld
4109 ER_UPDATE_INFO_WITH_SYSTEM_VERSIONING
Inserted: %ld Warnings: %ld
%`s must be of type %s for system-
4110 ER_VERS_FIELD_WRONG_TYPE
versioned table %`s
Transaction-precise system versioning for
4111 ER_VERS_ENGINE_UNSUPPORTED
%`s is not supported
4112 ER_UNUSED_23 You should never see it
4113 ER_PARTITION_WRONG_TYPE Wrong partitioning type, expected type: %`s
Versioned table %`s.%`s: last HISTORY
4114 WARN_VERS_PART_FULL partition (%`s) is out of %s, need more
HISTORY partitions
4115 WARN_VERS_PARAMETERS Maybe missing parameters: %s
Can only drop oldest partitions when
4116 ER_VERS_DROP_PARTITION_INTERVAL
rotating by INTERVAL
4117 ER_UNUSED_25 You should never see it

777/3812
4118 WARN_VERS_PART_NON_HISTORICAL Partition %`s contains non-historical data
Not allowed for system-versioned %`s.%`s.
Change
4119 ER_VERS_ALTER_NOT_ALLOWED
@@system_versioning_alter_history to
proceed with ALTER.
Not allowed for system-versioned %`s.%`s.
4120 ER_VERS_ALTER_ENGINE_PROHIBITED Change to/from native system versioning
engine is not supported.
SYSTEM_TIME range selector is not
4121 ER_VERS_RANGE_PROHIBITED
allowed
Conflicting FOR SYSTEM_TIME clauses in
4122 ER_CONFLICTING_FOR_SYSTEM_TIME
WITH RECURSIVE
Table %`s must have at least one versioned
4123 ER_VERS_TABLE_MUST_HAVE_COLUMNS
column
4124 ER_VERS_NOT_VERSIONED Table %`s is not system-versioned
4125 ER_MISSING Wrong parameters for %`s: missing '%s'
PERIOD FOR SYSTEM_TIME must use
4126 ER_VERS_PERIOD_COLUMNS
columns %`s and %`s
Wrong parameters for partitioned %`s:
4127 ER_PART_WRONG_VALUE
wrong value for '%s'
Wrong partitions for %`s: must have at least
4128 ER_VERS_WRONG_PARTS one HISTORY and exactly one last
CURRENT
TRX_ID %llu not found in
4129 ER_VERS_NO_TRX_ID
`mysql.transaction_registry`
4130 ER_VERS_ALTER_SYSTEM_FIELD Can not change system versioning field %`s
Can not DROP SYSTEM VERSIONING for
4131 ER_DROP_VERSIONING_SYSTEM_TIME_PARTITION
table %`s partitioned BY SYSTEM_TIME
System-versioned tables in the %`s
4132 ER_VERS_DB_NOT_SUPPORTED
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
Transaction-precise system-versioned
4138 ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED tables do not support partitioning by ROW
START or ROW END
4139 ER_INDEX_FILE_FULL The index file for table '%-.192s' is full
The column %`s.%`s cannot be changed
4140 ER_UPDATED_COLUMN_ONLY_ONCE more than once in a single UPDATE
statement
Row with no elements is not allowed in
4141 ER_EMPTY_ROW_IN_TVC
table value constructor in this context
SYSTEM_TIME partitions in table %`s does
4142 ER_VERS_QUERY_IN_PARTITION
not support historical query
%s index %`s does not support this
4143 ER_KEY_DOESNT_SUPPORT
operation
Changing table options requires the table to
4144 ER_ALTER_OPERATION_TABLE_OPTIONS_NEED_REBUILD
be rebuilt
Can't execute the command as you have a
4145 ER_BACKUP_LOCK_IS_ACTIVE
BACKUP STAGE active
You must start backup with \"BACKUP
4146 ER_BACKUP_NOT_RUNNING
STAGE START\"
Backup stage '%s' is same or before
4147 ER_BACKUP_WRONG_STAGE
current backup stage '%s'
4148 ER_BACKUP_STAGE_FAILED Backup stage '%s' failed
Unknown backup stage: '%s'. Stage should
4149 ER_BACKUP_UNKNOWN_STAGE be one of START, FLUSH, BLOCK_DDL,
BLOCK_COMMIT or END

778/3812
User is blocked because of too many
4150 ER_USER_IS_BLOCKED credential errors; unblock with 'FLUSH
PRIVILEGES'
4151 ER_ACCOUNT_HAS_BEEN_LOCKED Access denied, this account is locked
Application-time period table cannot be
4152 ER_PERIOD_TEMPORARY_NOT_ALLOWED
temporary
Fields of PERIOD FOR %`s have different
4153 ER_PERIOD_TYPES_MISMATCH
types
Cannot specify more than one application-
4154 ER_MORE_THAN_ONE_PERIOD
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
Column %`s used in period %`s specified
4157 ER_PERIOD_COLUMNS_UPDATED
in update SET list
Can't DROP CONSTRAINT `%s`. Use
4158 ER_PERIOD_CONSTRAINT_DROP
DROP PERIOD `%s` for this

4159 42000 ER_TOO_LONG_KEYPART Specified key part was too long; max key
S1009 part length is %u bytes
Comment for database '%-.64s' is too long
4160 ER_TOO_LONG_DATABASE_COMMENT
(max = %u)
4161 ER_UNKNOWN_DATA_TYPE Unknown data type: '%-.64s'
4162 ER_UNKNOWN_OPERATOR Operator does not exists: '%-.128s'
Table `%s.%s` history row start '%s' is later
4163 ER_WARN_HISTORY_ROW_START_TIME
than row end '%s'
%`s: STARTS is later than query time, first
4164 ER_PART_STARTS_BEYOND_INTERVAL history partition may exceed INTERVAL
value
DDL-statement is forbidden as table
4165 ER_GALERA_REPLICATION_NOT_SUPPORTED storage engine does not support Galera
replication
The used command is not allowed because
4166 HY000 ER_LOAD_INFILE_CAPABILITY_DISABLED the MariaDB server or client has disabled
the local infile capability
No secure transports are configured,
4167 ER_NO_SECURE_TRANSPORTS_CONFIGURED unable to set --
require_secure_transport=ON
Slave SQL thread ignored the '%s' because
4168 ER_SLAVE_IGNORED_SHARED_TABLE
table is shared
AUTO_INCREMENT column %`s cannot be
4169 ER_NO_AUTOINCREMENT_WITH_UNIQUE
used in the UNIQUE index %`s
Key %`s cannot explicitly include column
4170 ER_KEY_CONTAINS_PERIOD_FIELDS
%`s
Key %`s cannot have WITHOUT
4171 ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS
OVERLAPS
4172 ER_NOT_ALLOWED_IN_THIS_CONTEXT '%-.128s' is not allowed in this context
Engine %s does not support rollback.
4173 ER_DATA_WAS_COMMITED_UNDER_ROLLBACK Changes where commited during rollback
call
A primary key cannot be marked as
4174 ER_PK_INDEX_CANT_BE_IGNORED
IGNORE
SKIP LOCKED makes this statement
4175 ER_BINLOG_UNSAFE_SKIP_LOCKED
unsafe
Field '%s' can't be set for JSON_TABLE
4176 ER_JSON_TABLE_ERROR_ON_FIELD
'%s'.
4177 ER_JSON_TABLE_ALIAS_REQUIRED Every table function must have an alias.
Can't store an array or an object in the
4178 ER_JSON_TABLE_SCALAR_EXPECTED scalar column '%s' of JSON_TABLE '%s'.

Can't store multiple matches of the path in


4179 ER_JSON_TABLE_MULTIPLE_MATCHES
the column '%s' of JSON_TABLE '%s'.
FETCH ... WITH TIES requires ORDER BY
4180 ER_WITH_TIES_NEEDS_ORDER
clause to be present

779/3812
Dropped orphan trigger '%-.64s', originally
4181 ER_REMOVED_ORPHAN_TRIGGER
created for table: '%-.192s'
4182 ER_STORAGE_ENGINE_DISABLED Storage engine %s is disabled

1.1.2.10 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() 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 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

1.1.2.11 Reserved Words


Contents
1. Reserved Words
2. Exceptions
3. Oracle Mode
4. Function Names
5. See Also

The following is a list of all reserved words in MariaDB.


Reserved words cannot be used as Identifiers, 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

780/3812
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

781/3812
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
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

782/3812
INDEX
INFILE
INNER
INOUT
INSENSITIVE
INSERT
INT
INT1
INT2
INT3
INT4
INT8
INTEGER
INTERSECT Added in MariaDB 10.3.0
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

783/3812
MEDIUMTEXT
MIDDLEINT
MINUTE_MICROSECOND
MINUTE_SECOND
MOD
MODIFIES
NATURAL
NOT
NO_WRITE_TO_BINLOG
NULL
NUMERIC
OFFSET Added in MariaDB 10.6.0
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

784/3812
RESIGNAL
RESTRICT
RETURN
RETURNING
REVOKE
RIGHT
RLIKE
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

785/3812
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
DATE
ENUM
NO
TEXT
TIME
TIMESTAMP

Oracle Mode
In Oracle mode, from MariaDB 10.3, there are a number of extra reserved words:

Keyword Notes
BODY
ELSIF

786/3812
GOTO

HISTORY <= MariaDB 10.3.6 only


MINUS From MariaDB 10.6.1
OTHERS
PACKAGE
PERIOD <= MariaDB 10.3.6 only
RAISE
ROWNUM From MariaDB 10.6.1
ROWTYPE
SYSDATE From MariaDB 10.6.1
<= MariaDB 10.3.6 only. Note however that SYSTEM sometimes needs to be quoted to avoid
SYSTEM
confusion with System-versioned tables.
SYSTEM_TIME <= MariaDB 10.3.6 only
VERSIONING <= MariaDB 10.3.6 only
WITHOUT <= MariaDB 10.3.6 only

Function Names
If the IGNORE_SPACE SQL_MODE flag is set, function names become reserved words.

See Also
Information Schema KEYWORDS Table

1.1.2.12 SQLSTATE
1.1.2.13 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, double quotes will be treated as being used
for identifiers 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 hasn't been set to
NO_BACKSLASH_ESCAPES). For example:

787/3812
'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 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.

1.1.2.14 Table Value Constructors


MariaDB starting with 10.3.3
Table Value Constructors were introduced in MariaDB 10.3.3

Syntax
VALUES ( row_value[, row_value...]), (...)...

788/3812
Description
Contents
1. Syntax
2. Description
3. Examples

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 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 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 clause:

SELECT * FROM test.t1


UNION
VALUES (10, 20), (30, 40), (50, 60), (70, 80)
ORDER BY val1 DESC;

Using TVC with LIMIT 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 |
+------+------+

1.1.2.15 User-Defined Variables


Contents
1. Information Schema
2. Flushing User-Defined Variables
3. See Also

789/3812
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.
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 statement;
:= operator within a SQL statement;
SELECT ... INTO.
Since user-defined variables type cannot be declared, the only way to force their type is using CAST() or CONVERT():

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 clause.
They must be used to PREPARE 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 (as part of the User
Variables plugin) from MariaDB 10.2.

Flushing User-Defined Variables


User-defined variables are reset and the Information Schema table emptied with the FLUSH USER_VARIABLES
statement.

790/3812
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
Performance Schema user_variables_by_thread Table
Information Schema USER_VARIABLES Table

1.1.3 Geographic & Geometric Features


MariaDB supports spatial extensions that enable the creation, storage and analysis of geographic features. These can
be used in the Aria, MyISAM, InnoDB/XtraDB and ARCHIVE engines in MariaDB.
Partitioned tables do not support geometric types.
GIS Resources
Resources for those interested in GIS

GIS features in 5.3.3


Basic information about the existing spatial features can be found in the G...

Geometry Types
Supported geometry types.

Geometry Hierarchy
The base Geometry class has subclasses for Point, Curve, Surface and GeometryCollection

Geometry Constructors
Geometry constructors

Geometry Properties
Geometry properties

Geometry Relations
Geometry relations

LineString Properties
LineString properties

MBR (Minimum Bounding Rectangle)

Point Properties
Point properties

Polygon Properties
Polygon properties

WKB
Well-Known Binary format for geometric data

WKT
Well-Known Text geometry representation

MySQL/MariaDB Spatial Support Matrix


3 Table comparing when different spatial features were introduced into MySQL and MariaDB

791/3812
SPATIAL INDEX
5 An index type used for geometric columns.

MariaDB Plans - GIS


1 Old GIS plans

The maria/5.3-gis tree on Launchpad.


16 Note: This page is obsolete. The information is old, outdated, or otherwise...

GeoJSON
GeoJSON functions

There are 5 related questions .

1.1.3.1 GIS Resources


Here are a few resources for those interested in GIS in MariaDB.
OGC Simple Feature Access - the Open Geospatial Consortium's OpenGIS Simple Features Specifications For
SQL.
Geo/Spatial 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 " for more information.

1.1.3.2 GIS features in 5.3.3


Basic information about the existing spatial features can be found in the Geographic Features section of the
Knowlegebase. The Spatial Extensions page of the MySQL manual also applies to MariaDB.
The MariaDB 5.3.3 release , contains code improving the spatial functionality in MariaDB.
MySQL operates on spatial data based on the OpenGIS standards, particularly the OpenGIS 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, 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 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) 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_EQUALS(A, B) if A and B are equal
ST_WITHIN(A, B) if A lies within B

792/3812
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

1.1.3.3 Geometry Types


Contents
1. Description
2. Examples
1. POINT
2. LINESTRING
3. POLYGON
4. MULTIPOINT
5. MULTILINESTRING
6. MULTIPOLYGON
7. GEOMETRYCOLLECTION
8. GEOMETRY

Description
MariaDB provides a standard way of creating spatial columns for geometry types, for example, with CREATE TABLE or
ALTER TABLE. Currently, spatial columns are supported for MyISAM, InnoDB and ARCHIVE tables. See also SPATIAL
INDEX.
The basic geometry type is GEOMETRY . But the type can be more specific. The following types are supported:

Geometry Types
POINT
LINESTRING
POLYGON
MULTIPOINT
MULTILINESTRING
MULTIPOLYGON
GEOMETRYCOLLECTION
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
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

793/3812
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
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
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
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
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
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
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;

794/3812
1.1.3.4 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 represents zero-dimensional objects.
Curve represents one-dimensional objects, and has subclass LineString, with sub-subclasses Line and
LinearRing.
Surface is designed for two-dimensional objects and has subclass Polygon.
GeometryCollection has specialized zero-, one-, and two-dimensional collection classes named MultiPoint,
MultiLineString, and MultiPolygon 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, LineString, Polygon, GeometryCollection, MultiPoint, MultiLineString, and MultiPolygon are instantiable classes.

1.1.3.5 Geometry Constructors


1.1.3.6 Geometry Properties
1.1.3.7 Geometry Relations
1.1.3.8 LineString Properties
1.1.3.9 MBR (Minimum Bounding Rectangle)
1.1.3.10 Point Properties
1.1.3.11 Polygon Properties
1.1.3.12 WKB
1.1.3.13 WKT
1.1.3.14 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.

795/3812
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2
InnoDB Spatial Indexes - - - - x x - - - x
MyISAM Spatial Indexes x x x x x x x x x x
Aria Spatial Indexes - - - - - - x x x x
Area x x x x x d x x x x
AsBinary x x x x x d x x x x
AsText x x x x x d x x x x
AsWKB x x x x x d x x x x
AsWKT x x x x x d x x x x
Boundary - - - - - - - - x x
Buffer - - x x x d x x x x
Centroid - x x x x d x x x x
Contains MBR MBR MBR MBR MBR d MBR MBR MBR MBR
ConvexHull - - - - x d - - x x
Crosses MBR x x x x d MBR MBR MBR MBR
Dimension x x x x x d x x x x
Disjoint MBR MBR MBR MBR MBR d MBR MBR MBR MBR
Distance MBR - - x x d - - - -
EndPoint x x x x x d x x x x
Envelope x x x x x d x x x x
Equals MBR MBR MBR MBR MBR d MBR MBR MBR MBR
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2
ExteriorRing x x x x x d x x x x
GeomCollFromText x x x x x d x x x x
GeomCollFromWKB x x x x x d x x x x
GeometryCollection x x x x x x x x x x
GeometryCollectionFromText x x x x x d x x x x
GeometryCollectionFromWKB x x x x x d x x x x
GeometryFromText x x x x x d x x x x
GeometryFromWKB x x x x x d x x x x
GeometryN x x x x x d x x x x
GeometryType x x x x x d x x x x
GeomFromText x x x x x d x x x x
GeomFromWKB x x x x x d x x x x
GLength x x x x x d x x x x
InteriorRingN x x x x x d x x x x
Intersects MBR MBR MBR MBR MBR d MBR MBR MBR MBR
IsClosed x x x x x d x x x x
IsEmpty - * * * * d x x x x
IsRing - - - - - - - - x x
IsSimple - * * x x d - x x x
LineFromText x x x x x d x x x x

796/3812
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2

LineFromWKB x x x x x d x x x x
LineString x x x x x x x x x x
LineStringFromText x x x x x d x x x x
LineStringFromWKB x x x x x d x x x x
MBRContains MBR MBR MBR MBR MBR MBR MBR MBR MBR MBR
MBRCoveredBy - - - MBR MBR MBR - - - -
MBRDisjoint MBR MBR MBR MBR MBR MBR MBR MBR MBR MBR
MBREqual MBR MBR MBR MBR MBR MBR MBR MBR MBR MBR
MBREquals - - - MBR MBR MBR - - - MBR
MBRIntersects MBR MBR MBR MBR MBR MBR MBR MBR MBR MBR
MBROverlaps MBR MBR MBR MBR MBR MBR MBR MBR MBR MBR
MBRTouches MBR MBR MBR MBR MBR MBR MBR MBR MBR MBR
MBRWithin MBR MBR MBR MBR MBR MBR MBR MBR MBR MBR
MLineFromText x x x x x d x x x x
MLineFromWKB x x x x x d x x x x
MPointFromText x x x x x d x x x x
MPointFromWKB x x x x x d x x x x
MPolyFromText x x x x x d x x x x
MPolyFromWKB x x x x x d x x x x
MultiLineString x x x x x x x x x x
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2
MultiLineStringFromText x x x x x d x x x x
MultiLineStringFromWKB x x x x x d x x x x
MultiPoint x x x x x x x x x x
MultiPointFromText x x x x x d x x x x
MultiPointFromWKB x x x x x d x x x x
MultiPolygon x x x x x x x x x x
MultiPolygonFromText x x x x x d x x x x
MultiPolygonFromWKB x x x x x d x x x x
NumGeometries x x x x x d x x x x
NumInteriorRings x x x x x d x x x x
NumPoints x x x x x d x x x x
Overlaps MBR MBR MBR MBR MBR d MBR MBR MBR MBR
Point x x x x x x x x x x
PointFromText x x x x x d x x x x
PointFromWKB x x x x x d x x x x
PointOnSurface - - - - - - - - x x
PointN x x x x x d x x x x
PolyFromText x x x x x d x x x x
PolyFromWKB x x x x x d x x x x
Polygon x x x x x x x x x x

797/3812
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2
PolygonFromText x x x x x d x x x x
PolygonFromWKB x x x x x d x x x x
SRID x x x x x d x x x x
ST_Area - - x x x x - x x x
ST_AsBinary - - x x x x - x x x
ST_AsGeoJSON - - - x x x - - - x
ST_AsText - - x x x x - x x x
ST_AsWKB - - x x x x - x x x
ST_AsWKT - - x x x x - x x x
ST_Boundary - - - - - - - - x x
ST_Buffer - - x x x x - x x x
ST_Buffer_Strategy - - - x x x - - - -
ST_Centroid - - x x x x - x x x
ST_Contains - - x x x x - x x x
ST_ConvexHull - - - - x x - - x x
ST_Crosses - - x x x x - x x x
ST_Difference - - x x x x - x x x
ST_Dimension - - x x x x - x x x
ST_Disjoint - - x x x x - x x x
ST_Distance - - x x x x - x x x
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2
ST_Distance_Sphere - - - - - x - - - -
ST_EndPoint - - x x x x - x x x
ST_Envelope - - x x x x - x x x
ST_Equals - - x x x x - x x x
ST_ExteriorRing - - x x x x - x x x
ST_GeoHash - - - - x x - - - -
ST_GeomCollFromText - - x x x x - x x x
ST_GeomCollFromWKB - - x x x x - x x x
ST_GeometryCollectionFromText - - x x x x - x x x
ST_GeometryCollectionFromWKB - - x x x x - x x x
ST_GeometryFromText - - x x x x - x x x
ST_GeometryFromWKB - - x x x x - x x x
ST_GeometryN - - x x x x - x x x
ST_GeometryType - - x x x x - x x x
ST_GeomFromGeoJSON - - - - x x - - - x
ST_GeomFromText - - x x x x - x x x
ST_GeomFromWKB - - x x x x - x x x
ST_InteriorRingN - - x x x x - x x x
ST_Intersection - - x x x x - x x x
ST_Intersects - - x x x x - x x x
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2
798/3812
ST_IsClosed - - x x x x - x x x
ST_IsEmpty - - x x x x - x x x
ST_IsRing - - - - - - - - x x
ST_IsSimple - - x x x x - x x x
ST_IsValid - - - - - x - - - -
ST_LatFromGeoHash - - - - x x - - - -
ST_Length - - - - - x - x x x
ST_LineFromText - - x x x x - x x x
ST_LineFromWKB - - x x x x - x x x
ST_LineStringFromText - - x x x x - x x x
ST_LineStringFromWKB - - x x x x - x x x
ST_LongFromGeoHash - - - - x x - - - -
ST_NumGeometries - - x x x x - x x x
ST_NumInteriorRings - - x x x x - x x x
ST_NumPoints - - x x x x - x x x
ST_Overlaps - - x x x x - x x x
ST_PointFromGeoHash - - - - x x - - - -
ST_PointFromText - - x x x x - x x x
ST_PointFromWKB - - x x x x - x x x
ST_PointOnSurface - - - - - - - - x x
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2
ST_PointN - - x x x x - x x x
ST_PolyFromText - - x x x x - x x x
ST_PolyFromWKB - - x x x x - x x x
ST_PolygonFromText - - x x x x - x x x
ST_PolygonFromWKB - - x x x x - x x x
ST_Relate - - - - - - - - x x
ST_Simplify - - - - - x - - - -
ST_SRID - - x x x x - x x x
ST_StartPoint - - x x x x - x x x
ST_SymDifference - - x x x x - x x x
ST_Touches - - x x x x - x x x
ST_Union - - x x x x - x x x
ST_Validate - - - - - x - - - -
ST_Within - - x x x x - x x x
ST_X - - x x x x - x x x
ST_Y - - x x x x - x x x
StartPoint x x x x x d x x x x
Touches MBR x x x x d MBR MBR MBR MBR
Within MBR MBR MBR MBR MBR d MBR MBR MBR MBR
X x x x x x d x x x x
Y x x x x x d x x x x
My My My My My My MDB MDB MDB MDB
5.4.2 5.5 5.6.1 5.7.4 5.7.5 5.7.6 5.1 5.3.3 10.1.2 10.2

799/3812
1.1.3.15 SPATIAL INDEX
Contents
1. Description
1. Data-at-Rest Encyption

Description
On MyISAM, Aria and InnoDB 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 geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));

with ALTER TABLE:


ALTER TABLE geom ADD SPATIAL INDEX(g);

with CREATE 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.
To drop spatial indexes, use ALTER TABLE or DROP INDEX:
with ALTER TABLE:
ALTER TABLE geom DROP INDEX g;

with DROP INDEX:


DROP INDEX sp_index ON geom;

Data-at-Rest Encyption
Before MariaDB 10.4.3, InnoDB's spatial indexes could not be encrypted. If an InnoDB table was encrypted and if it
contained spatial indexes, then those indexes would be unencrypted.
In MariaDB 10.4.3 and later, if innodb_checksum_algorithm is set to full_crc32 or strict_full_crc32 , and if the
table does not use ROW_FORMAT=COMPRESSED , then InnoDB spatial indexes will be encrypted if the table is encrypted.
See MDEV-12026 for more information.

1.1.3.16 GeoJSON
GeoJSON is a format for encoding various geographic data structures.
ST_AsGeoJSON
Returns the given geometry as a GeoJSON element.

ST_GeomFromGeoJSON
Given a GeoJSON input, returns a geometry object

1.1.3.16.1 ST_AsGeoJSON
Syntax
ST_AsGeoJSON(g[, max_decimals[, options]])

Description
800/3812
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

1.1.3.16.2 ST_GeomFromGeoJSON
MariaDB starting with 10.2.4
ST_GeomFromGeoJSON was added in MariaDB 10.2.4

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 - see 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) |
+-----------------------------------+

1.1.4 NoSQL
MariaDB supports a lot of commands and interfaces that are closer to NoSQL than to SQL.
CONNECT
The CONNECT storage engine enables MariaDB to access external local or remote data.

HANDLER
Direct access to reading rows from the storage engine.

HandlerSocket
A NoSQL plugin giving you direct access to InnoDB and SPIDER.

801/3812
Dynamic Columns
18 Dynamic columns allow one to store different sets of columns for each row in a table

Dynamic Columns from MariaDB 10


Improvements to Dynamic Columns from MariaDB 10.

Dynamic Column API


Client-side API for reading and writing Dynamic Columns blobs

Dynamic Columns API


1 MariaDB 10.0 API for reading and writing dynamic-columns blobs

JSON Functions
Built-in functions related to JSON.

LOAD_FILE
Returns file contents as a string.

Cassandra Storage Engine


A storage engine interface to Cassandra.

There are 1 related questions .

1.1.4.1 CONNECT
1.1.4.2 HANDLER
The HANDLER statements give you direct access to reading rows from the storage engine. This is much faster than
normal access through SELECT as there is less parsing involved and no optimizer involved.
You can use prepared statements for HANDLER READ , which should give you a speed comparable to HandlerSocket. Also
see Yoshinori Matsunobu's blog post Using MySQL as a NoSQL - A story for exceeding 750,000 qps on a commodity
server .
HANDLER Commands
Direct access to table storage engine interfaces for key lookups and key or table scans.

HANDLER for MEMORY Tables


Using HANDLER commands efficiently with MEMORY/HEAP tables

802/3812
1.1.4.2.1 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

Contents
1. Syntax
2. Description
3. Key Lookup
4. Key Scans
5. Table Scans
6. Limitations
1. Finding 'Old Rows'
2. Invisible Columns
3. System-Versioned Tables
4. Other Limitations
7. Error Codes
8. See Also

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, Memory, MyISAM and InnoDB tables (and should work with most 'normal' storage
engines, but not with system tables, MERGE or views).
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 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.

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:

803/3812
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.

System-Versioned Tables
HANDLER ... READ reads everything from system-versioned tables, 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, 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 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

1.1.4.2.2 HANDLER for MEMORY Tables


This article explains how to use HANDLER commands efficiently with MEMORY/HEAP tables.
If you want to scan a table for over different key values, not just search for exact key values, you should create your
804/3812
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 key that only supports exact matches (=) while b is a BTREE 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.

1.1.4.3 HandlerSocket
HandlerSocket gives you direct access to InnoDB and SPIDER. 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.
HandlerSocket Installation
2 Installing the HandlerSocket plugin.

HandlerSocket Configuration Options


2 HandlerSocket configuration options.

HandlerSocket Client Libraries


Available HandlerSocket Client Libraries

Testing HandlerSocket in a Source Distribution


Testing HandlerSocket in a source distribution.

HandlerSocket External Resources


1 HandlerSocket external resources and documentation

1.1.4.3.1 HandlerSocket Installation


After MariaDB is installed, use the INSTALL PLUGIN 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 you first need to configure some settings. All HandlerSocket
configuration options are placed in the [mysqld] section of your my.cnf file.
At least the handlersocket_address, handlersocket_port and handlersocket_port_wr options need to be set. For
805/3812
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).

1.1.4.3.2 HandlerSocket Configuration Options


Contents
1. handlersocket_accept_balance
2. handlersocket_address
3. handlersocket_backlog
4. handlersocket_epoll
5. handlersocket_plain_secret
6. handlersocket_plain_secret_wr
7. handlersocket_port
8. handlersocket_port_wr
9. handlersocket_rcvbuf
10. handlersocket_readsize
11. handlersocket_sndbuf
12. handlersocket_threads
13. handlersocket_threads_wr
14. handlersocket_timeout
15. handlersocket_verbose
16. handlersocket_wrlock_timeout

The HandlerSocket plugin has the following options.


See also the Full list of MariaDB options, system and status variables.
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
806/3812
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
807/3812
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
808/3812
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

1.1.4.3.3 HandlerSocket Client Libraries


In order to make use of the HandlerSocket plugin in your applications, you will need to use the appropriate client library.
The following client libraries are available:
C++
libhsclient (included with the HandlerSocket plugin source)
Perl
perl-Net-HandlerSocket (included with the HandlerSocket plugin source)
PHP
Net_HandlerSocket
HSPHP
php-ext-handlersocketi
Java
hs4j
handlersocketforjava
Python
python-handler-socket
pyhandlersocket
Ruby
ruby-handlersocket
handlersocket
JavaScript
node-handlersocket
Scala
hs2client
Haskell
https://github.com/wuxb45/HandlerSocket-Haskell-Client

1.1.4.3.4 Testing HandlerSocket in a Source


Distribution
Contents
1. MariaDB 5.5
2. MariaDB 5.3

MariaDB 5.5
In MariaDB 5.5, 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
If you want to test or use handlersocket with a source installation of MariaDB 5.3, 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:


809/3812
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

1.1.4.3.5 HandlerSocket External Resources


Some resources and documentation about HandlerSocket.
The home of HandlerSocket is here .
The story of handlersocket can be found here .
Comparison of HANDLER and HandlerSocket can be found here .
HandlerSocket plugin for MySQL presentation by Akira Higuchi of DeNA - June 29 2010 - DeNA Technology
Seminar
HandlerSocket plugin for MySQL presentation by Akira Higuchi of DeNA - June 29 2011 - in Japanese

1.1.4.4 Dynamic Columns


Contents
1. Dynamic Columns Basics
2. Dynamic Columns Reference
1. Dynamic Columns Functions
1. COLUMN_CREATE
2. COLUMN_ADD
3. COLUMN_GET
4. COLUMN_DELETE
5. COLUMN_EXISTS
6. COLUMN_LIST
7. COLUMN_CHECK
8. COLUMN_JSON
2. Nesting Dynamic Columns
3. Datatypes
1. A Note About Lengths
4. MariaDB 5.3 vs MariaDB 10.0
5. Client-side API
6. Limitations
3. See Also

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.

810/3812
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

811/3812
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 section for further details. Note also 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() ), 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 section for more information about datatypes.

COLUMN_DELETE
812/3812
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.

813/3812
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 and CONVERT functions. However, note
that there are currently some differences - see MDEV-597 .

dynamic column internal


type description
type
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) - 9 bytes)
(variable length binary decimal representation with MariaDB
DECIMAL[(M[,D])] DYN_COL_DECIMAL
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, may be negative) - 6 bytes)
UNSIGNED
DYN_COL_UINT (variable length, up to 64bit unsigned integer)
[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-10.0.0 and 16,777,216 for MariaDB
10.0.1 +. 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 vs MariaDB 10.0


The dynamic columns feature was introduced into MariaDB in two steps:
814/3812
1. MariaDB 5.3 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 , 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.

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 for details.

Limitations
Description Limit
Max number of columns 65535
Max total length of packed dynamic column max_allowed_packet (1G)

See Also
Dynamic Columns from MariaDB 10

1.1.4.5 Dynamic Columns from MariaDB 10


Contents
1. Column Name Support
2. Changes in Behavior
3. New Functions
1. COLUMN_CHECK
2. COLUMN_JSON
4. Other Changes
5. Interface with Cassandra
6. See Also

MariaDB starting with 10.0.1


MariaDB 10.0.1 introduced the following improvements to the dynamic columns feature.

Column Name Support


It is possible to refer to column by names. Names can be used everywhere where in MariaDB 5.3 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:

815/3812
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 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 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.
816/3812
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. See 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 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
Cassandra Storage Engine

1.1.4.6 Dynamic Column API


This page describes the client-side API for reading and writing Dynamic Columns blobs.
Normally, you should use Dynamic column 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.

Contents
1. Where to get it
2. Data structures
1. DYNAMIC_COLUMN
2. DYNAMIC_COLUMN_VALUE
3. enum_dyncol_func_result
3. Function reference
1. mariadb_dyncol_create_many
2. mariadb_dyncol_update_many
3. mariadb_dyncol_exists
4. mariadb_dyncol_column_count
5. mariadb_dyncol_list
6. mariadb_dyncol_get
7. mariadb_dyncol_unpack
8. mariadb_dyncol_has_names
9. mariadb_dyncol_check
10. mariadb_dyncol_json
11. mariadb_dyncol_val_TYPE
12. mariadb_dyncol_prepare_decimal
13. mariadb_dyncol_value_init
14. mariadb_dyncol_column_cmp_named

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

817/3812
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

818/3812
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);

819/3812
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)

820/3812
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
821/3812
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);

1.1.4.7 Dynamic Columns from MariaDB 10


Contents
1. Column Name Support
2. Changes in Behavior
3. New Functions
1. COLUMN_CHECK
2. COLUMN_JSON
4. Other Changes
5. Interface with Cassandra
6. See Also

MariaDB starting with 10.0.1


MariaDB 10.0.1 introduced the following improvements to the dynamic columns feature.

Column Name Support


It is possible to refer to column by names. Names can be used everywhere where in MariaDB 5.3 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:

822/3812
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 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 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.
823/3812
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. See 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 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
Cassandra Storage Engine

1.1.4.8 JSON Functions


1.1.4.9 LOAD_FILE
1.1.5 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( )). 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 statement or in a SET clause in an UPDATE statement.

Arithmetic Operators
Addition Operator (+)
Addition.

DIV
Integer division.

Division Operator (/)


2 Division.

MOD
Modulo operation. Remainder of N divided by M.

Modulo Operator (%)


Modulo operator. Returns the remainder of N divided by M.

Multiplication Operator (*)


Multiplication.

Subtraction Operator (-)


Subtraction and unary minus.

Assignment Operators

824/3812
Assignment Operator (:=)
Assignment operator for assigning a value.

Assignment Operator (=)


The equal sign as an assignment operator.

Bit Functions and Operators


Operator Precedence
Precedence of SQL operators

&
Bitwise AND

<<
Left shift

>>
Shift right

BIT_COUNT
Returns the number of set bits

^
Bitwise XOR

|
Bitwise OR

~
Bitwise NOT

Parentheses
Parentheses modify the precedence of other operators in an expression

TRUE FALSE
TRUE and FALSE evaluate to 1 and 0

Comparison Operators
!=
Not equal operator.

<
Less than operator.

<=
Less than or equal operator.

<=>
2 NULL-safe equal operator.

=
1 Equal operator.

>
Greater than operator.

>=
Greater than or equal operator.

BETWEEN AND
True if expression between two values.

COALESCE
Returns the first non-NULL parameter

825/3812
GREATEST
1 Returns the largest argument.

IN
1 True if expression equals any of the values in the list.

INTERVAL
Index of the argument that is less than the first argument

IS
Tests whether a boolean is TRUE, FALSE, or UNKNOWN.

IS NOT
Tests whether a boolean value is not TRUE, FALSE, or UNKNOWN

IS NOT NULL
Tests whether a value is not NULL

IS NULL
Tests whether a value is NULL

ISNULL
Checks if an expression is NULL

LEAST
Returns the smallest argument.

NOT BETWEEN
Same as NOT (expr BETWEEN min AND max)

NOT IN
Same as NOT (expr IN (value,...))

Logical Operators
!
Logical NOT.

&&
Logical AND.

XOR
Logical XOR.

||
Logical OR.

Other Operators Articles


Operator Precedence
Precedence of SQL operators

There are 3 related questions .

1.1.5.1 Arithmetic Operators


Arithmetic operators for addition, subtraction, multiplication, division and the modulo operator
Addition Operator (+)
Addition.

DIV
Integer division.

Division Operator (/)


2 Division.
826/3812
MOD
Modulo operation. Remainder of N divided by M.

Modulo Operator (%)


Modulo operator. Returns the remainder of N divided by M.

Multiplication Operator (*)


Multiplication.

Subtraction Operator (-)


Subtraction and unary minus.

1.1.5.1.1 Addition Operator (+)


Syntax
+

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Addition.
If both operands are integers, the result is calculated with BIGINT 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
Subtraction Operator (-)
Multiplication Operator (*)
Division Operator (/)

1.1.5.1.2 DIV
1.1.5.1.3 Division Operator (/)
Syntax
/

827/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 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 is used (the default since MariaDB
10.2.4 ), 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 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
Addition Operator (+)
Subtraction Operator (-)
Multiplication Operator (*)

1.1.5.1.4 MOD
1.1.5.1.5 Modulo Operator (%)
Syntax
828/3812
N % M

Description
Modulo operator. Returns the remainder of N divided by M . See also MOD.

Examples
SELECT 1042 % 50;
+-----------+
| 1042 % 50 |
+-----------+
| 42 |
+-----------+

1.1.5.1.6 Multiplication Operator (*)


Syntax
*

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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
Addition Operator (+)
829/3812
Subtraction Operator (-)
Division Operator (/)

1.1.5.1.7 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 precision. If either integer is unsigned, the result is
also an unsigned integer, unless the NO_UNSIGNED_SUBTRACTION SQL_MODE 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
Addition Operator (+)
Multiplication Operator (*)
Division Operator (/)

1.1.5.2 Assignment Operators


Operators for assigning a value
Assignment Operator (:=)
Assignment operator for assigning a value.

Assignment Operator (=)


The equal sign as an assignment operator.

830/3812
1.1.5.2.1 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, := can always be used to assign a value to a variable.
This operator works with both user-defined variables and local variables.
When assigning the same value to several variables, LAST_VALUE() can be useful.

Examples
SELECT @x := 10;
+----------+
| @x := 10 |
+----------+
| 10 |
+----------+

SELECT @x, @y := @x;


+------+----------+
| @x | @y := @x |
+------+----------+
| 10 | 10 |
+------+----------+

1.1.5.2.2 Assignment Operator (=)


Syntax
identifier = expr

Contents
1. Syntax
2. Description
3. Examples

Description
The equal sign is used as both an assignment operator in certain contexts, and as a comparison operator. 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, the = assignment operator cannot be used in all
contexts, and is only valid as part of a SET statement, or the SET clause of an UPDATE statement
This operator works with both user-defined variables and local variables.

Examples
UPDATE table_name SET x = 2 WHERE x > 100;

SET @x = 1, @y := 2;

1.1.5.3 Bit Functions and Operators


831/3812
1.1.5.4 Comparison Operators
The comparison operators include: !=, <, <=, <=>, >=, >, etc...
!=
Not equal operator.

<
Less than operator.

<=
Less than or equal operator.

<=>
2 NULL-safe equal operator.

=
1 Equal operator.

>
Greater than operator.

>=
Greater than or equal operator.

BETWEEN AND
True if expression between two values.

COALESCE
Returns the first non-NULL parameter

GREATEST
1 Returns the largest argument.

IN
1 True if expression equals any of the values in the list.

INTERVAL
Index of the argument that is less than the first argument

IS
Tests whether a boolean is TRUE, FALSE, or UNKNOWN.

IS NOT
Tests whether a boolean value is not TRUE, FALSE, or UNKNOWN

IS NOT NULL
Tests whether a value is not NULL

IS NULL
Tests whether a value is NULL

ISNULL
Checks if an expression is NULL

LEAST
Returns the smallest argument.

NOT BETWEEN
Same as NOT (expr BETWEEN min AND max)

NOT IN
Same as NOT (expr IN (value,...))

1.1.5.4.1 Not Equal Operator: !=


832/3812
Syntax
<>, !=

Contents
1. Syntax
2. Description
3. Examples

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 |
+-------------------+

1.1.5.4.2 <
Syntax
<

Contents
1. Syntax
2. Description
3. Examples

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:

833/3812
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:

SELECT 'a'<'A';
+---------+
| 'a'<'A' |
+---------+
| 0 |
+---------+

1.1.5.4.3 <=
Syntax
<=

Contents
1. Syntax
2. Description
3. Examples

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 |
+----------+

834/3812
SELECT 'a'<='A';
+----------+
| 'a'<='A' |
+----------+
| 1 |
+----------+

1.1.5.4.4 <=>
Syntax
<=>

Description
NULL-safe equal operator. It performs an equality comparison like the = operator, 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.

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 |
+-------+-------------+----------+

1.1.5.4.5 =
Syntax
left_expr = right_expr

Contents
1. Syntax
2. Description
3. Examples

Description
Equal operator. Evaluates both SQL expressions and returns 1 if they are equal, 0 if they are not equal, or NULL 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:
835/3812
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 <=> operator.


= can also be used as an assignment operator.

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 |
+-------------+

1.1.5.4.6 >
Syntax
>

836/3812
Contents
1. Syntax
2. Description
3. Examples

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 |
+-----------+

1.1.5.4.7 >=
Syntax
>=

Contents
1. Syntax
2. Description
3. Examples

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

837/3812
SELECT 2 >= 2;
+--------+
| 2 >= 2 |
+--------+
| 1 |
+--------+

SELECT 'A' >= 'a';


+------------+
| 'A' >= 'a' |
+------------+
| 1 |
+------------+

1.1.5.4.8 BETWEEN AND


Syntax
expr BETWEEN min AND max

Contents
1. Syntax
2. Description
3. Examples

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, 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:
838/3812
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 |
+------------+---------------------+---------------------+

1.1.5.4.9 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.

Examples
SELECT COALESCE(NULL,1);
+------------------+
| COALESCE(NULL,1) |
+------------------+
| 1 |
+------------------+

839/3812
SELECT COALESCE(NULL,NULL,NULL);
+--------------------------+
| COALESCE(NULL,NULL,NULL) |
+--------------------------+
| NULL |
+--------------------------+

When two arguments are given, COALESCE() is the same as IFNULL():

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), 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
IS NULL operator
IS NOT NULL operator
IFNULL function
NULLIF function
CONNECT data types

1.1.5.4.10 GREATEST
Syntax
GREATEST(value1,value2,...)

Description
840/3812
With two or more arguments, returns the largest (maximum-valued) argument. The arguments are compared using the
same rules as for LEAST().

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 |
+-----------------------+

1.1.5.4.11 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, 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:

841/3812
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

1.1.5.4.12 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

842/3812
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 |
+-----------------------+

1.1.5.4.13 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
BOOLEAN Data Type

1.1.5.4.14 IS NOT
843/3812
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 |
+------------------+-------------------+

1.1.5.4.15 IS NOT NULL


Syntax
IS NOT NULL

Description
Tests whether a value is not NULL. See also NULL Values in MariaDB.

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
IS NULL operator
COALESCE function
IFNULL function
NULLIF function
CONNECT data types

1.1.5.4.16 IS NULL
Syntax
IS NULL

844/3812
Description
Tests whether a value is NULL. See also NULL Values in MariaDB.

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 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
IS NOT NULL operator
COALESCE function
IFNULL function
NULLIF function
CONNECT data types

1.1.5.4.17 ISNULL
Syntax
ISNULL(expr)

Description
If expr is NULL, ISNULL() returns 1, otherwise it returns 0.
See also NULL Values in MariaDB.

Examples
SELECT ISNULL(1+1);
+-------------+
| ISNULL(1+1) |
+-------------+
| 0 |
+-------------+

SELECT ISNULL(1/0);
+-------------+
| ISNULL(1/0) |
+-------------+
| 1 |
+-------------+

845/3812
1.1.5.4.18 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 |
+--------------------+

1.1.5.4.19 NOT BETWEEN


Syntax
expr NOT BETWEEN min AND max

Description
This is the same as NOT (expr BETWEEN 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 flag.

Examples
SELECT 1 NOT BETWEEN 2 AND 3;
+-----------------------+
| 1 NOT BETWEEN 2 AND 3 |
+-----------------------+
| 1 |
+-----------------------+

846/3812
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 |
+--------------------------+

1.1.5.4.20 NOT IN
Syntax
expr NOT IN (value,...)

Description
This is the same as NOT (expr IN (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:

847/3812
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 |
+-----------------------+

1.1.5.5 Logical Operators


NOT, AND, Exclusive OR and OR
!
Logical NOT.

&&
Logical AND.

XOR
Logical XOR.

||
Logical OR.

1.1.5.5.1 !
Syntax
NOT, !

Contents
1. Syntax
2. Description
3. Examples

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. If the HIGH_NOT_PRECEDENCE SQL_MODE flag is set, NOT and !
have the same precedence.

Examples

848/3812
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 |
+-------+

1.1.5.5.2 &&
Syntax
AND, &&

Contents
1. Syntax
2. Description
3. Examples

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 can be used.

Examples

849/3812
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 |
+-----------+

1.1.5.5.3 XOR
Syntax
XOR

Contents
1. Syntax
2. Description
3. Examples

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

850/3812
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 |
+---------------+

1.1.5.5.4 ||
Syntax
OR, ||

Contents
1. Syntax
2. Description
1. Oracle Mode
3. Examples
4. See Also

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 can be used.
Note that, if the PIPES_AS_CONCAT SQL_MODE is set, || is used as a string concatenation operator. This means that
a || b is the same as CONCAT(a,b) . See CONCAT() for details.

Oracle Mode
MariaDB starting with 10.3
In Oracle mode from MariaDB 10.3, || ignores NULL.

Examples

851/3812
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, from MariaDB 10.3:

SELECT 0 || NULL;
+-----------+
| 0 || NULL |
+-----------+
| 0 |
+-----------+

See Also
Oracle mode from MariaDB 10.3

1.1.5.6 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
BINARY , COLLATE
!
- (unary minus), [[bitwise-not|]] (unary bit inversion)
|| (string concatenation)
^
* , / , DIV , % , MOD
-, +
<< , >>
&
|
= (comparison), <=> , >= , > , <= , < , <> , != , IS , LIKE , REGEXP , IN
BETWEEN , CASE , WHEN , THEN , ELSE , END
NOT
&& , AND
XOR
|| (logical or), OR
= (assignment), :=
Functions precedence is always higher than operators precedence.
852/3812
In this page CASE refers to the CASE operator, not to the CASE statement .
If the HIGH_NOT_PRECEDENCE SQL_MODE 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 flag: if it is on,
|| can be used to concatenate strings (like the CONCAT() 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 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();

1.1.6 Sequences
MariaDB starting with 10.3
CREATE SEQUENCE was introduced in MariaDB 10.3.

A sequence is an object that generates a sequence of numeric values, as specified by the CREATE SEQUENCE
statement. Sequences are an alternative to AUTO_INCREMENT 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( ).

This section is about sequence objects. For details about the storage engine, see Sequence Storage Engine.

Sequence Overview
Object that generates a sequence of numeric values.

CREATE SEQUENCE
6 Creates a sequence that generates new values when called with NEXT VALUE FOR.

SHOW CREATE SEQUENCE


Shows the CREATE SEQUENCE statement that created the sequence.

ALTER SEQUENCE
Change options for a SEQUENCE.

DROP SEQUENCE
Deleting a SEQUENCE.

SEQUENCE Functions
Functions that can be used on SEQUENCEs.

SHOW TABLES
List of non-temporary tables, views or sequences.

1.1.6.1 Sequence Overview


853/3812
MariaDB starting with 10.3
Sequences were introduced in MariaDB 10.3.

Contents
1. Introduction
2. Creating a Sequence
3. Using Sequence Objects
1. Using Sequences in DEFAULT
4. Changing a Sequence
5. Dropping a Sequence
6. Replication
7. Standards Compliance
8. Notes
9. Table Operations that Work with
Sequences
10. Implementation
11. Underlying Table Structure
12. Credits
13. See Also

Introduction
A sequence is an object that generates a sequence of numeric values, as specified by the CREATE SEQUENCE
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 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 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().

Creating a Sequence
The CREATE SEQUENCE 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, 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, use

NEXT VALUE FOR sequence_name

or

NEXTVAL(sequence_name)

or in Oracle mode (SQL_MODE=ORACLE)

sequence_name.nextval

For retrieving the last value used by the current connection from a sequence use:

PREVIOUS VALUE FOR sequence_name

or

854/3812
LASTVAL(sequence_name)

or in Oracle mode (SQL_MODE=ORACLE)

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


MariaDB starting with 10.3.3
Starting from 10.3.3 you can use Sequences 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 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 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:

855/3812
SELECT SETVAL(s, 50);
+---------------+
| SETVAL(s, 50) |
+---------------+
| NULL |
+---------------+

Dropping a Sequence
The DROP SEQUENCE 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 and auto_increment_offset to generate unique values for each server.

Standards Compliance
MariaDB 10.3 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, and one can also create a sequence with CREATE TABLE and drop it
with DROP TABLE. One can SELECT 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. 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 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 or CREATE SEQUENCE, one row will be inserted.
If one tries to insert into a sequence table, the single row will be updated. This allows mysqldump 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 or DELETE 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 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. This shows the table structure that is behind the SEQUENCE including
the field names that can be used with SELECT or even CREATE TABLE.
CREATE TABLE sequence-structure ... SEQUENCE=1
ALTER TABLE sequence RENAME TO sequence2
RENAME TABLE sequence_name TO new_sequence_name
DROP TABLE sequence_name. This is allowed mainly to get old tools like mysqldump to work with sequence
tables.
SHOW TABLES

Implementation
Internally, sequence tables are created as a normal table without rollback (the InnoDB, Aria and MySAM 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 is enabled).

856/3812
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
ALTER SEQUENCE
DROP SEQUENCE
NEXT VALUE FOR
PREVIOUS VALUE FOR
SETVAL(). Set next value for the sequence.
AUTO INCREMENT

1.1.6.2 CREATE SEQUENCE


MariaDB starting with 10.3
CREATE SEQUENCE was introduced in MariaDB 10.3.

Syntax

857/3812
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]

Contents
1. Syntax
2. Description
1. Arguments to Create
2. Constraints on Create Arguments
3. Atomic DDL
3. Examples
4. See Also

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 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 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. 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().
CREATE SEQUENCE requires the CREATE privilege.
DROP SEQUENCE can be used to drop a sequence, and ALTER SEQUENCE to change it.

Arguments to Create
The following options may be used:

Option Default value Description


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
INCREMENT 1
system variable at the time of creation, which is always a positive number.
(see MDEV-16035 ).
1 if INCREMENT > 0
and -
MINVALUE Minimum value for the sequence
9223372036854775807
if INCREMENT < 0
9223372036854775806
MAXVALUE if INCREMENT > 0 and Max value for sequence
-1 if INCREMENT < 0
MINVALUE if
INCREMENT > 0 and
START First value that the sequence will generate
MAX_VALUE if
INCREMENT< 0
Number of values that should be cached. 0 if no CACHE. The underlying
CACHE 1000 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:

858/3812
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
MariaDB 10.6.1 supports Atomic DDL 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
ALTER SEQUENCE
DROP SEQUENCE
NEXT VALUE FOR
PREVIOUS VALUE FOR
SETVAL(). Set next value for the sequence.
AUTO INCREMENT
SHOW CREATE SEQUENCE

1.1.6.3 SHOW CREATE SEQUENCE


1.1.6.4 ALTER SEQUENCE
MariaDB starting with 10.3.1
ALTER SEQUENCE was introduced in MariaDB 10.3.

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]

859/3812
Contents
1. Syntax
2. Description
1. Arguments to ALTER SEQUENCE
2. INSERT
3. Notes
3. See Also

ALTER SEQUENCE allows one to change any values for a SEQUENCE created with CREATE SEQUENCE.
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.

Arguments to ALTER SEQUENCE


The following options may be used:

Option Default value Description


INCREMENT 1 Increment to use for values. May be negative.
1 if INCREMENT > 0 and -
MINVALUE 9223372036854775807 if Minimum value for the sequence.
INCREMENT < 0

9223372036854775806 if
MAXVALUE INCREMENT > 0 and -1 if Max value for sequence.
INCREMENT < 0

MINVALUE if INCREMENT >


START 0 and MAX_VALUE if First value that the sequence will generate.
INCREMENT < 0

Number of values that should be cached. 0 if no CACHE . The underlying


CACHE 1000 table will be updated first time a new sequence number is generated and
each time the cache runs out.
1 if the sequence should start again from MINVALUE # after it has run out of
CYCLE 0 (= NO CYCLE )
values.
START if restart value
RESTART If RESTART option is used, NEXT VALUE will return the restart value.
not is given

The optional clause RESTART [ WITH restart ] sets the next value for the sequence. This is equivalent to calling the
SETVAL() 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 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 mysqldump, 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:

860/3812
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() instead, as this is not blocking.
If you want to change storage engine, sequence comment or rename the sequence, you can use ALTER TABLE for
this.

See Also
Sequence Overview
CREATE SEQUENCE
DROP SEQUENCE
NEXT VALUE FOR
PREVIOUS VALUE FOR
SETVAL(). Set next value for the sequence.
AUTO INCREMENT
ALTER TABLE

1.1.6.5 DROP SEQUENCE


MariaDB starting with 10.3
DROP SEQUENCE was introduced in MariaDB 10.3.

Syntax
DROP [TEMPORARY] SEQUENCE [IF EXISTS] [/*COMMENT TO SAVE*/]
sequence_name [, sequence_name] ...

Contents
1. Syntax
2. Description
3. Notes
4. See Also

Description
DROP SEQUENCE removes one or more sequences created with CREATE SEQUENCE. 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.
861/3812
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.
DROP SEQUENCE requires the DROP privilege.

Notes
DROP SEQUENCE only removes sequences, not tables. However, DROP TABLE can remove both sequences and
tables.

See Also
Sequence Overview
CREATE SEQUENCE
ALTER SEQUENCE
DROP TABLE

1.1.6.6 SEQUENCE Functions


MariaDB starting with 10.3
SEQUENCEs were introduced in MariaDB 10.3.

Functions that can be used on SEQUENCEs


LASTVAL
Synonym for PREVIOUS VALUE for sequence_name.

NEXT VALUE for sequence_name


Generate next value for a SEQUENCE. Same as NEXTVAL().

NEXTVAL
Synonym for NEXT VALUE for sequence_name.

PREVIOUS VALUE FOR sequence_name


Get last value generated from a SEQUENCE. Same as LASTVAL().

SETVAL
Set the next value to be returned from a SEQUENCE.

1.1.6.6.1 LASTVAL
LASTVAL is a synonym for PREVIOUS VALUE for sequence_name.

1.1.6.6.2 NEXT VALUE for sequence_name


MariaDB starting with 10.3
SEQUENCEs were introduced in MariaDB 10.3

Syntax
NEXT VALUE FOR sequence

or

NEXTVAL(sequence_name)

862/3812
or in Oracle mode (SQL_MODE=ORACLE)

sequence_name.nextval

Contents
1. Syntax
2. Description
3. See Also

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() or ALTER SEQUENCE ... RESTART, NEXT VALUE FOR will notice
this and start from the next requested value.
FLUSH TABLES 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.

MariaDB starting with 10.3.3


You can also use NEXT VALUE FOR sequence for column DEFAULT .

See Also
Sequence Overview
CREATE SEQUENCE
ALTER SEQUENCE
PREVIOUS VALUE FOR
SETVAL(). Set next value for the sequence.
AUTO_INCREMENT

1.1.6.6.3 NEXTVAL
NEXTVAL is a synonym for NEXT VALUE for sequence_name.

1.1.6.6.4 PREVIOUS VALUE FOR


sequence_name
MariaDB starting with 10.3
SEQUENCEs were introduced in MariaDB 10.3.

Syntax
PREVIOUS VALUE FOR sequence_name

or

LASTVAL(sequence_name)

or in Oracle mode (SQL_MODE=ORACLE)

sequence_name.currval

863/3812
Contents
1. Syntax
2. Description
3. Example
4. See Also

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 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.

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
864/3812
Sequence Overview
CREATE SEQUENCE
ALTER SEQUENCE
NEXT VALUE FOR
SETVAL(). Set next value for the sequence.
AUTO_INCREMENT

1.1.6.6.5 SETVAL
MariaDB starting with 10.3.1
SEQUENCEs were introduced in MariaDB 10.3.

Syntax
SETVAL(sequence_name, next_value, [is_used, [round]])

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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) 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.
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.

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:

865/3812
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.

866/3812
SELECT SETVAL(s1, 99, 1, 1);
+----------------------+
| SETVAL(s1, 99, 1, 1) |
+----------------------+
| 99 |
+----------------------+

SELECT NEXTVAL(s1);
+-------------+
| NEXTVAL(s1) |
+-------------+
| 1 |
+-------------+

See Also
Sequence Overview
ALTER SEQUENCE
CREATE SEQUENCE
NEXT VALUE FOR
PREVIOUS VALUE FOR

1.1.6.7 SHOW TABLES


1.1.7 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).
System-Versioned Tables
26 System-versioned tables record the history of all changes to table data.

Application-Time Periods
Application-time period tables, defined by a range between two temporal columns.

Bitemporal Tables
Bitemporal tables use versioning both at the system and application-time period levels.

1.1.7.1 System-Versioned Tables


Contents
1. System-Versioned Tables
1. Creating a System-Versioned Table
2. Adding or Removing System
Versioning To/From a Table
3. Querying Historical Data
1. SELECT
2. Views and Subqueries
3. Use in Replication and Binary Logs
4. Transaction-Precise History in InnoDB
5. Storing the History Separately
1. Default Partitions
2. Automatically Creating Partitions
6. Removing Old History
7. Excluding Columns From Versioning
2. System Variables
1. system_versioning_alter_history
2. system_versioning_asof
3. system_versioning_innodb_algorithm_simple
4. system_versioning_insert_history
3. Limitations
4. See Also

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 (allow you to query and operate on a temporal range of data),
and bitemporal tables (which combine both system-versioning and application-time periods).
867/3812
System-Versioned Tables

MariaDB starting with 10.3.4


Support for system-versioned tables was added in MariaDB 10.3.4.

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 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 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;

868/3812
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

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, as if one had specified FOR
SYSTEM_TIME AS OF CURRENT_TIMESTAMP .

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

869/3812
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 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) 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 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 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
);

870/3812
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 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


Since partitioning by current and historical data is such a typical usecase, from MariaDB 10.5, 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


From MariaDB 10.9.1, the AUTO keyword can be used to automatically create history partitions.
871/3812
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 ).

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 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 privilege.
Currently, using the DELETE HISTORY statement with a BEFORE SYSTEM_TIME greater than the ROW_END of the
active records (as a TIMESTAMP, this has a maximum value of '2038-01-19 03:14:07' UTC) will result in the historical
records being dropped, and the active records being deleted and moved to history. See MDEV-25468 .
Prior to MariaDB 10.4.5, the TRUNCATE TABLE statement drops all historical records from a system-versioned-table.
From MariaDB 10.4.5, 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
872/3812
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
);

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 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 is not set).
Commandline: --system-versioning-alter-history=value
Scope: Global, Session
Dynamic: Yes
Type: Enum
Default Value: ERROR
Valid Values: ERROR , KEEP
Introduced: MariaDB 10.3.4

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 and REPLACE ..
SELECT need to state AS OF explicitly.
Commandline: None
Scope: Global, Session
Dynamic: Yes
Type: Varchar
Default Value: DEFAULT
Introduced: MariaDB 10.3.4

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
Removed: MariaDB 10.3.5

system_versioning_insert_history
Description: Allows direct inserts into ROW_START and ROW_END columns if secure_timestamp allows
873/3812
changing timestamp.
Commandline: --system-versioning-insert-history[={0|1}]
Scope: Global, Session
Dynamic: Yes
Type: Boolean
Default Value: OFF
Introduced: MariaDB 10.11.0

Limitations
Versioning clauses can not be applied to generated (virtual and persistent) columns.
mysqldump does not read historical rows from versioned tables, and so historical data will not be backed up. Also,
a restore of the timestamps would not be possible as they cannot be defined by an insert/a user.

See Also
Application-Time Periods
Bitemporal Tables
mysql.transaction_registry Table
MariaDB Temporal Tables (video)

1.1.7.2 Application-Time Periods


Contents
1. Creating Tables with Time Periods
2. Adding and Removing Time Periods
3. Deletion by Portion
4. Updating by Portion
5. WITHOUT OVERLAPS
6. Further Examples
7. See Also

MariaDB starting with 10.4.3


Support for application-time period-versioning was added in MariaDB 10.4.3.

Extending system-versioned tables, MariaDB 10.4 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, i.e. DATE, TIMESTAMP
or DATETIME (TIME and YEAR 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 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 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 statement now supports syntax for adding and removing time periods from a table. To add a period,
use the ADD PERIOD clause.
For example:

874/3812
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:

875/3812
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 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
876/3812
MariaDB starting with 10.5.3
MariaDB 10.5 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.

877/3812
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
Bitemporal Tables

1.1.7.3 Bitemporal Tables


MariaDB starting with 10.4.3
Bitemporal tables are tables that use versioning both at the system and application-time period levels.

Contents
1. Using Bitemporal Tables
2. See Also

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
Application-time Periods

1.2 Built-in Functions


Functions and procedures in MariaDB
Function and Operator Reference
A complete list of MariaDB functions and operators in alphabetical order.

String Functions
Built-In functions for the handling of strings and columns containing string values.

Date & Time Functions


Built-In functions for the handling of dates and times.

878/3812
Aggregate Functions
Aggregate functions used with GROUP BY clauses.

Numeric Functions
Numeric and arithmetic related functions in MariaDB.

Control Flow Functions


Built-In functions for assessing data to determine what results to return.

Pseudo Columns
MariaDB has pseudo columns that can be used for different purposes.

Secondary Functions
Bit Functions and Operators
Operators for comparison and setting of values, and related functions.

Encryption, Hashing and Compression Functions


Functions used for encryption, hashing and compression.

Information Functions
Functions which return information on the server, the user, or a given query.

Miscellaneous Functions
Functions for very singular and specific needs.

Special Functions
Dynamic Columns Functions
Functions for storing key/value pairs of data within a column.

Galera Functions
Built-in functions related to Galera.

Geographic Functions
Geographic, as well as geometric functions.

JSON Functions
Built-in functions related to JSON.

SEQUENCE Functions
Functions that can be used on SEQUENCEs.

Spider Functions
User-defined functions available with the Spider storage engine.

Window Functions
Window functions for performing calculations on a set of rows related to the current row.

There are 8 related questions .

1.2.1 Function and Operator Reference


Name Description
+ Addition operator
/ Division operator
* Multiplication operator
% Modulo operator. Returns the remainder of N divided by M
- Subtraction operator
!= Not equals
< Less than
<= Less than or equal
<=> NULL-safe equal
879/3812
= Equal
> Greater than
>= Greater than or equal
& Bitwise AND
<< Shift left
>> Shift right
^ Bitwise XOR
! Logical NOT
&& Logical AND
XOR Logical XOR
|| Logical OR

| Bitwise OR
:= Assignment operator
= Assignment and comparison operator
~ Bitwise NOT
ABS Returns an absolute value
ACOS Returns an arc cosine
ADD_MONTHS Add months to a date
ADDDATE Add days or another interval to a date
ADDTIME Adds a time to a time or datetime
AES_DECRYPT Decryption data encrypted with AES_ENCRYPT
AES_ENCRYPT Encrypts a string with the AES algorithm
AREA Synonym for ST_AREA
AsBinary Synonym for ST_AsBinary
ASCII Numeric ASCII value of leftmost character
ASIN Returns the arc sine
AsText Synonym for ST_AsText
AsWKB Synonym for ST_AsBinary
AsWKT Synonym for ST_AsText
ATAN Returns the arc tangent
ATAN2 Returns the arc tangent of two variables
AVG Returns the average value
BENCHMARK Executes an expression repeatedly
BETWEEN AND True if expression between two values
BIN Returns binary value
BINARY OPERATOR Casts to a binary string
BINLOG_GTID_POS Returns a string representation of the corresponding GTID position
BIT_AND Bitwise AND
BIT_COUNT Returns the number of set bits
BIT_LENGTH Returns the length of a string in bits
BIT_OR Bitwise OR
BIT_XOR Bitwise XOR
BOUNDARY Synonym for ST_BOUNDARY
BUFFER Synonym for ST_BUFFER
CASE Returns the result where value=compare_value or for the first condition that is true
CAST Casts a value of one type to another type
CEIL Synonym for CEILING()
CEILING Returns the smallest integer not less than X
CENTROID Synonym for ST_CENTROID
CHAR Function Returns string based on the integer values for the individual characters
CHARACTER_LENGTH Synonym for CHAR_LENGTH()

880/3812
CHAR_LENGTH Length of the string in characters
CHARSET Returns the character set
CHR Returns a string consisting of the character given by the code values of the integer
COALESCE Returns the first non-NULL parameter
COERCIBILITY Returns the collation coercibility value
COLLATION Collation of the string argument
COLUMN_ADD Adds or updates dynamic columns
COLUMN_CHECK Checks if a dynamic column blob is valid
COLUMN_CREATE Returns a dynamic columns blob
COLUMN_DELETE Deletes a dynamic column
COLUMN_EXISTS Checks is a column exists
COLUMN_GET Gets a dynamic column value by name
COLUMN_JSON Returns a JSON representation of dynamic column blob data
COLUMN_LIST Returns comma-separated list
COMPRESS Returns a binary, compressed string
CONCAT Returns concatenated string
CONCAT_WS Concatenate with separator
CONNECTION_ID Connection thread ID
CONTAINS Whether one geometry contains another
CONVERT Convert a value from one type to another type
CONV Converts numbers between different number bases
CONVERT_TZ Converts a datetime from on time zone to another
CONVEXHULL Synonym for ST_CONVEXHULL
COS Returns the cosine
COT Returns the cotangent
COUNT Returns count of non-null values
COUNT DISTINCT Returns count of number of different non-NULL values
CRC32 Computes a cyclic redundancy check value
CROSSES Whether two geometries spatially cross
CUME_DIST Window function that returns the cumulative distribution of a given row
CURDATE Returns the current date
CURRENT_DATE Synonym for CURDATE()
CURRENT_ROLE Current role name
CURRENT_TIME Synonym for CURTIME()
CURRENT_TIMESTAMP Synonym for NOW()
CURRENT_USER Username/host that authenicated the current client
CURTIME Returns the current time
DATABASE Current default database
DATE FUNCTION Extracts the date portion of a datetime
DATEDIFF Difference in days between two date/time values
DATE_ADD Date arithmetic - addition
DATE_FORMAT Formats the date value according to the format string
DATE_SUB Date arithmetic - subtraction
DAY Synonym for DAYOFMONTH()
DAYNAME Return the name of the weekday
DAYOFMONTH Returns the day of the month
DAYOFWEEK Returns the day of the week index
DAYOFYEAR Returns the day of the year
DECODE Decrypts a string encoded with ENCODE()
Returns comma separated numerics corresponding to a probability distribution represented
DECODE_HISTOGRAM
by a histogram

881/3812
DEFAULT Returns column default
DEGREES Converts from radians to degrees
DENSE_RANK Rank of a given row with identical values receiving the same result, no skipping
DES_DECRYPT Decrypts a string encrypted with DES_ENCRYPT()
DES_ENCRYPT Encrypts a string using the Triple-DES algorithm
DIMENSION Synonym for ST_DIMENSION
DISJOINT Whether the two elements do not intersect
DIV Integer division
ELT Returns the N'th element from a set of strings
ENCODE Encrypts a string
ENCRYPT Encrypts a string with Unix crypt()
ENDPOINT Synonym for ST_ENDPOINT
ENVELOPE Synonym for ST_ENVELOPE
EQUALS Indicates whether two geometries are spatially equal
EXP e raised to the power of the argument
EXPORT_SET Returns an on string for every bit set, an off string for every bit not set
ExteriorRing Synonym for ST_ExteriorRing
EXTRACT Extracts a portion of the date
EXTRACTVALUE Returns the text of the first text node matched by the XPath expression
FIELD Returns the index position of a string in a list
FIND_IN_SET Returns the position of a string in a set of strings
FLOOR Largest integer value not greater than the argument
FORMAT Formats a number
FOUND_ROWS Number of (potentially) returned rows
FROM_BASE64 Given a base-64 encoded string, returns the decoded result as a binary string
FROM_DAYS Returns a date given a day
FROM_UNIXTIME Returns a datetime from a Unix timestamp
GeomCollFromText Synonym for ST_GeomCollFromText
GeomCollFromWKB Synonym for ST_GeomCollFromWKB
GeometryCollectionFromText Synonym for ST_GeomCollFromText
GeometryCollectionFromWKB Synonym for ST_GeomCollFromWKB
GeometryFromText Synonym for ST_GeomFromText
GeometryFromWKB Synonym for ST_GeomFromWKB
GeomFromText Synonym for ST_GeomFromText
GeomFromWKB Synonym for ST_GeomFromWKB
GeometryN Synonym for ST_GeometryN
GEOMETRYCOLLECTION Constructs a WKB GeometryCollection
GeometryType Synonym for ST_GeometryType
GET_FORMAT Returns a format string
GET_LOCK Obtain LOCK
GLENGTH Length of a LineString value
GREATEST Returns the largest argument
GROUP_CONCAT Returns string with concatenated values from a group
HEX Returns hexadecimal value
HOUR Returns the hour
IF If expr1 is TRUE, returns expr2; otherwise returns expr3
IFNULL Check whether an expression is NULL
IN True if expression equals any of the values in the list
INTERVAL Index of the argument that is less than the first argument
INET6_ATON Given an IPv6 or IPv4 network address, returns a VARBINARY numeric value
INET6_NTOA Given an IPv6 or IPv4 network address, returns the address as a nonbinary string

882/3812
INET_ATON Returns numeric value of IPv4 address
INET_NTOA Returns dotted-quad representation of IPv4 address
INSERT Function Replaces a part of a string with another string
INSTR Returns the position of a string withing a string

InteriorRingN Synonym for ST_InteriorRingN


INTERSECTS Indicates whether two geometries spatially intersect
IS Tests whether a boolean is TRUE, FALSE, or UNKNOWN
IsClosed Synonym for ST_IsClosed
IsEmpty Synonym for ST_IsEmpty
IS_FREE_LOCK Checks whether lock is free to use
IS_IPV4 Whether or not an expression is a valid IPv4 address
IS_IPV4_COMPAT Whether or not an IPv6 address is IPv4-compatible
IS_IPV4_MAPPED Whether an IPv6 address is a valid IPv4-mapped address
IS_IPV6 Whether or not an expression is a valid IPv6 address
IS NOT Tests whether a boolean value is not TRUE, FALSE, or UNKNOWN
IS NOT NULL Tests whether a value is not NULL
IS NULL Tests whether a value is NULL
ISNULL Checks if an expression is NULL
IsRing Synonym for ST_IsRing
IsSimple Synonym for ST_IsSimple
IS_USED_LOCK Check if lock is in use
JSON_ARRAY Returns a JSON array containing the listed values
JSON_ARRAY_APPEND Appends values to the end of the given arrays within a JSON document
JSON_ARRAY_INSERT Inserts a value into a JSON document
JSON_COMPACT Removes all unnecessary spaces so the json document is as short as possible
Whether a value is found in a given JSON document or at a specified path within the
JSON_CONTAINS
document
JSON_CONTAINS_PATH Indicates whether the given JSON document contains data at the specified path or paths
JSON_DEPTH Maximum depth of a JSON document
JSON_DETAILED Represents JSON in the most understandable way emphasizing nested structures
JSON_EQUALS Check for equality between JSON objects.
JSON_EXISTS Determines whether a specified JSON value exists in the given data
JSON_EXTRACT Extracts data from a JSON document.
JSON_INSERT Inserts data into a JSON document
JSON_KEYS Returns keys from top-level value of a JSON object or top-level keys from the path
JSON_LENGTH Returns the length of a JSON document, or the length of a value within the document
JSON_LOOSE Adds spaces to a JSON document to make it look more readable
JSON_MERGE Merges the given JSON documents
JSON_MERGE_PATCH RFC 7396-compliant merge of the given JSON documents
JSON_MERGE_PRESERVE Synonym for JSON_MERGE_PATCH.
Recursively sorts keys and removes spaces, allowing comparison of json documents for
JSON_NORMALIZE
equality
JSON_OBJECT Returns a JSON object containing the given key/value pairs
JSON_OBJECTAGG Returns a JSON object containing key-value pairs
JSON_OVERLAPS Compares two json documents for overlaps
JSON_QUERY Given a JSON document, returns an object or array specified by the path
JSON_QUOTE Quotes a string as a JSON value
JSON_REMOVE Removes data from a JSON document
JSON_REPLACE Replaces existing values in a JSON document
JSON_SEARCH Returns the path to the given string within a JSON document
JSON_SET Updates or inserts data into a JSON document

883/3812
JSON_TABLE Returns a representation of a JSON document as a relational table
JSON_TYPE Returns the type of a JSON value
JSON_UNQUOTE Unquotes a JSON value, returning a string
JSON_VALID Whether a value is a valid JSON document or not
JSON_VALUE Given a JSON document, returns the specified scalar
LAST_DAY Returns the last day of the month
LAST_INSERT_ID Last inserted autoinc value
LAST_VALUE Returns the last value in a list
LASTVAL Get last value generated from a sequence
LCASE Synonym for [LOWER()
LEAST Returns the smallest argument
LEFT Returns the leftmost characters from a string
LENGTH Length of the string in bytes
LIKE Whether expression matches a pattern
LineFromText Synonym for ST_LineFromText
LineFromWKB Synonym for ST_LineFromWKB
LINESTRING Constructs a WKB LineString value from a number of WKB Point arguments
LineStringFromText Synonym for ST_LineFromText
LineStringFromWKB Synonym for ST_LineFromWKB
LN Returns natural logarithm
LOAD_FILE Returns file contents as a string
LOCALTIME Synonym for NOW()
LOCALTIMESTAMP Synonym for NOW()
LOCATE Returns the position of a substring in a string
LOG Returns the natural logarithm
LOG10 Returns the base-10 logarithm

LOG2 Returns the base-2 logarithm


LOWER Returns a string with all characters changed to lowercase
LPAD Returns the string left-padded with another string to a given length
LTRIM Returns the string with leading space characters removed
MAKE_SET Make a set of strings that matches a bitmask
MAKEDATE Returns a date given a year and day
MAKETIME Returns a time
MASTER_GTID_WAIT Wait until slave reaches the GTID position
MASTER_POS_WAIT Blocks until the slave has applied all specified updates
MATCH AGAINST Perform a fulltext search on a fulltext index
MAX Returns the maximum value
MBRContains Indicates one Minimum Bounding Rectangle contains another
MBRDisjoint Indicates whether the Minimum Bounding Rectangles of two geometries are disjoint
MBREqual Whether the Minimum Bounding Rectangles of two geometries are the same.
MBRIntersects Indicates whether the Minimum Bounding Rectangles of the two geometries intersect
MBROverlaps Whether the Minimum Bounding Rectangles of two geometries overlap.
MBRTouches Whether the Minimum Bounding Rectangles of two geometries touch.
MBRWithin Indicates whether one Minimum Bounding Rectangle is within another
MD5 MD5 checksum
MEDIAN Window function that returns the median value of a range of values
MICROSECOND Returns microseconds from a date or datetime
MID Synonym for SUBSTRING(str,pos,len)
MIN Returns the minimum value
MINUTE Returns a minute from 0 to 59

884/3812
MLineFromText Constructs MULTILINESTRING using its WKT representation and SRID
MLineFromWKB Constructs a MULTILINESTRING
MOD Modulo operation. Remainder of N divided by M
MONTH Returns a month from 1 to 12
MONTHNAME Returns the full name of the month
MPointFromText Constructs a MULTIPOINT value using its WKT and SRID
MPointFromWKB Constructs a MULTIPOINT value using its WKB representation and SRID
MPolyFromText Constructs a MULTIPOLYGON value
MPolyFromWKB Constructs a MULTIPOLYGON value using its WKB representation and SRID
MultiLineStringFromText Synonym for MLineFromText

MultiLineStringFromWKB A synonym for MLineFromWKB


MULTIPOINT Constructs a WKB MultiPoint value
MultiPointFromText Synonym for MPointFromText
MultiPointFromWKB Synonym for MPointFromWKB
MULTIPOLYGON Constructs a WKB MultiPolygon
MultiPolygonFromText Synonym for MPolyFromText
MultiPolygonFromWKB Synonym for MPolyFromWKB
MULTILINESTRING Constructs a MultiLineString value
NAME_CONST Returns the given value
NATURAL_SORT_KEY Sorting that is more more similar to natural human sorting
NOT LIKE Same as NOT(expr LIKE pat [ESCAPE 'escape_char'])
NOT REGEXP Same as NOT (expr REGEXP pat)
NULLIF Returns NULL if expr1 = expr2
NEXTVAL Generate next value for sequence
NOT BETWEEN Same as NOT (expr BETWEEN min AND max)
NOT IN Same as NOT (expr IN (value,...))
NOW Returns the current date and time
NTILE Returns an integer indicating which group a given row falls into
NumGeometries Synonym for ST_NumGeometries
NumInteriorRings Synonym for NumInteriorRings
NumPoints Synonym for ST_NumPoints
OCT Returns octal value
OCTET_LENGTH Synonym for LENGTH()
OLD_PASSWORD Pre MySQL 4.1 password implementation
ORD Return ASCII or character code
OVERLAPS Indicates whether two elements spatially overlap
PASSWORD Calculates a password string
PERCENT_RANK Window function that returns the relative percent rank of a given row
PERCENTILE_CONT Returns a value which corresponds to the given fraction in the sort order.
Returns the first value in the set whose ordered position is the same or more than the
PERCENTILE_DISC
specified fraction.
PERIOD_ADD Add months to a period
PERIOD_DIFF Number of months between two periods
PI Returns the value of π (pi)
POINT Constructs a WKB Point
PointFromText Synonym for ST_PointFromText
PointFromWKB Synonym for PointFromWKB
PointN Synonym for PointN
PointOnSurface Synonym for ST_PointOnSurface
POLYGON Constructs a WKB Polygon value from a number of WKB LineString arguments
PolyFromText Synonym for ST_PolyFromText

885/3812
PolyFromWKB Synonym for ST_PolyFromWKB
PolygonFromText Synonym for ST_PolyFromText
PolygonFromWKB Synonym for ST_PolyFromWKB

POSITION Returns the position of a substring in a string


POW Returns X raised to the power of Y
POWER Synonym for POW()
QUARTER Returns year quarter from 1 to 4
QUOTE Returns quoted, properly escaped string
RADIANS Converts from degrees to radians
RAND Random floating-point value
RANK Rank of a given row with identical values receiving the same result
REGEXP Performs pattern matching
REGEXP_INSTR Position of the first appearance of a regex
REGEXP_REPLACE Replaces all occurrences of a pattern
REGEXP_SUBSTR Returns the matching part of a string
RELEASE_LOCK Releases lock obtained with GET_LOCK()
REPEAT Function Returns a string repeated a number of times
REPLACE Function Replace occurrences of a string
REVERSE Reverses the order of a string
RIGHT Returns the rightmost N characters from a string
RLIKE Synonym for REGEXP()
RPAD Returns the string right-padded with another string to a given length
ROUND Rounds a number
ROW_COUNT Number of rows affected by previous statement
ROW_NUMBER Row number of a given row with identical values receiving a different result
RTRIM Returns the string with trailing space characters removed
SCHEMA Synonym for DATABASE()
SECOND Returns the second of a time
SEC_TO_TIME Converts a second to a time
SETVAL Set the next value to be returned by a sequence
SESSION_USER Synonym for USER()
SHA Synonym for SHA1()
SHA1 Calculates an SHA-1 checksum
SHA2 Calculates an SHA-2 checksum
SIGN Returns 1, 0 or -1
SIN Returns the sine
SLEEP Pauses for the given number of seconds
SOUNDEX Returns a string based on how the string sounds
SOUNDS LIKE SOUNDEX(expr1) = SOUNDEX(expr2)
SPACE Returns a string of space characters
SPIDER_BG_DIRECT_SQL Background SQL execution
SPIDER_COPY_TABLES Copy table data
SPIDER_DIRECT_SQL Execute SQL on the remote server

SPIDER_FLUSH_TABLE_MON_CACHE Refreshing Spider monitoring server information


SQRT Square root
SRID Synonym for ST_SRID
ST_AREA Area of a Polygon
ST_AsBinary Converts a value to its WKB representation
ST_AsText Converts a value to its WKT-Definition
ST_AsWKB Synonym for ST_AsBinary

886/3812
ST_ASWKT Synonym for ST_ASTEXT()
ST_BOUNDARY Returns a geometry that is the closure of a combinatorial boundary
ST_BUFFER A new geometry with a buffer added to the original geometry
ST_CENTROID The mathematical centroid (geometric center) for a MultiPolygon
ST_CONTAINS Whether one geometry is contained by another
ST_CONVEXHULL The minimum convex geometry enclosing all geometries within the set
ST_CROSSES Whether two geometries spatially cross
ST_DIFFERENCE Point set difference
ST_DIMENSION Inherent dimension of a geometry value
ST_DISJOINT Whether one geometry is spatially disjoint from another
ST_DISTANCE The distance between two geometries
ST_DISTANCE_SPHERE The spherical distance between two geometries
ST_ENDPOINT Returns the endpoint of a LineString
ST_ENVELOPE Returns the Minimum Bounding Rectangle for a geometry value
ST_EQUALS Whether two geometries are spatoially equal
ST_ExteriorRing Returns the exterior ring of a Polygon as a LineString
ST_GeomCollFromText Constructs a GEOMETRYCOLLECTION value
ST_GeomCollFromWKB Constructs a GEOMETRYCOLLECTION value from a WKB
ST_GeometryCollectionFromText Synonym for ST_GeomCollFromText
ST_GeometryCollectionFromWKB Synonym for ST_GeomCollFromWKB
ST_GeometryFromText Synonym for ST_GeomFromText
ST_GeometryFromWKB Synonym for ST_GeomFromWKB
ST_GEOMETRYN Returns the N-th geometry in a GeometryCollection
ST_GEOMETRYTYPE Returns name of the geometry type of which a given geometry instance is a member
ST_GeomFromText Constructs a geometry value using its WKT and SRID
ST_GeomFromWKB Constructs a geometry value using its WKB representation and SRID
ST_InteriorRingN Returns the N-th interior ring for a Polygon
ST_INTERSECTION The intersection, or shared portion, of two geometries
ST_INTERSECTS Whether two geometries spatially intersect
ST_ISCLOSED Returns true if a given LINESTRING's start and end points are the same
ST_ISEMPTY Indicated validity of geometry value
ST_IsRing Returns true if a given LINESTRING is both ST_IsClosed and ST_IsSimple
ST_IsSimple Returns true if the given Geometry has no anomalous geometric points
ST_LENGTH Length of a LineString value
ST_LineFromText Creates a linestring value
ST_LineFromWKB Constructs a LINESTRING using its WKB and SRID
ST_LineStringFromText Synonym for ST_LineFromText
ST_LineStringFromWKB Synonym for ST_LineFromWKB
ST_NUMGEOMETRIES Number of geometries in a GeometryCollection
ST_NumInteriorRings Number of interior rings in a Polygon
ST_NUMPOINTS Returns the number of Point objects in a LineString
ST_OVERLAPS Whether two geometries overlap
ST_PointFromText Constructs a POINT value
ST_PointFromWKB Constructs POINT using its WKB and SRID
ST_POINTN Returns the N-th Point in the LineString
ST_POINTONSURFACE Returns a POINT guaranteed to intersect a surface
ST_PolyFromText Constructs a POLYGON value
ST_PolyFromWKB Constructs POLYGON value using its WKB representation and SRID
ST_PolygonFromText Synonym for ST_PolyFromText
ST_PolygonFromWKB Synonym for ST_PolyFromWKB
ST_RELATE Returns true if two geometries are related

887/3812
ST_SRID Returns a Spatial Reference System ID
ST_STARTPOINT Returns the start point of a LineString
ST_SYMDIFFERENCE Portions of two geometries that don't intersect
ST_TOUCHES Whether one geometry g1 spatially touches another
ST_UNION Union of two geometries
ST_WITHIN Whether one geometry is within another
ST_X X-coordinate value for a point
ST_Y Y-coordinate for a point
STARTPOINT Synonym for ST_StartPoint
STD Population standard deviation
STDDEV Population standard deviation
STDDEV_POP Returns the population standard deviation
STDDEV_SAMP Standard deviation

STR_TO_DATE Converts a string to date


STRCMP Compares two strings in sort order
SUBDATE Subtract a date unit or number of days
SUBSTR Returns a substring from string starting at a given position
SUBSTRING Returns a substring from string starting at a given position
SUBSTRING_INDEX Returns the substring from string before count occurrences of a delimiter
SUBTIME Subtracts a time from a date/time
SUM Sum total
SYS_GUID Generates a globally unique identifier
SYSDATE Returns the current date and time
SYSTEM_USER Synonym for USER()
TAN Returns the tangent
TIME function Extracts the time
TIMEDIFF Returns the difference between two date/times
TIMESTAMP FUNCTION Return the datetime, or add a time to a date/time
TIMESTAMPADD Add interval to a date or datetime
TIMESTAMPDIFF Difference between two datetimes
TIME_FORMAT Formats the time value according to the format string
TIME_TO_SEC Returns the time argument, converted to seconds
TO_BASE64 Converts a string to its base-64 encoded form
TO_CHAR Converts a date/time type to a char
TO_DAYS Number of days since year 0
TO_SECONDS Number of seconds since year 0
TOUCHES Whether two geometries spatially touch
TRIM Returns a string with all given prefixes or suffixes removed
TRUNCATE Truncates X to D decimal places
UCASE Synonym for UPPER]]()
Interprets pairs of hex digits as a number and converts to the character represented by the
UNHEX
number
UNCOMPRESS Uncompresses string compressed with COMPRESS()
UNCOMPRESSED_LENGTH Returns length of a string before being compressed with COMPRESS()
UNIX_TIMESTAMP Returns a Unix timestamp
UPDATEXML Replace XML
UPPER Changes string to uppercase
USER Current user/host
UTC_DATE Returns the current UTC date
UTC_TIME Returns the current UTC time
UTC_TIMESTAMP Returns the current UTC date and time

888/3812
UUID Returns a Universal Unique Identifier
UUID_SHORT Return short universal identifier

VALUES or VALUE Refer to columns in INSERT ... ON DUPLICATE KEY UPDATE


VAR_POP Population standard variance
VAR_SAMP Returns the sample variance
VARIANCE Population standard variance
VERSION MariaDB server version
WEEK Returns the week number
WEEKDAY Returns the weekday index
WEEKOFYEAR Returns the calendar week of the date as a number in the range from 1 to 53
WEIGHT_STRING Weight of the input string
WITHIN Indicate whether a geographic element is spacially within another
WSREP_LAST_SEEN_GTID Returns the Global Transaction ID of the most recent write transaction observed by the client.
Returns the Global Transaction ID of the most recent write transaction performed by the
WSREP_LAST_WRITTEN_GTID
client.
Blocks the client until the transaction specified by the given Global Transaction ID is applied
WSREP_SYNC_WAIT_UPTO_GTID
and committed by the node
X Synonym for ST_X
Y Synonym for ST_Y
YEAR Returns the year for the given date
YEARWEEK Returns year and week for a date

1.2.2 String Functions


Functions dealing with strings, such as CHAR, CONVERT, CONCAT, PAD, REGEXP, TRIM, etc.
Regular Expressions Functions
Functions for dealing with regular expressions

Dynamic Columns Functions


Functions for storing key/value pairs of data within a column.

ASCII
Numeric ASCII value of leftmost character.

BIN
Returns binary value.

BINARY Operator
Casts to a binary string.

BIT_LENGTH
Returns the length of a string in bits.

CAST
3 Casts a value of one type to another type.

CHAR Function
Returns string based on the integer values for the individual characters.

CHARACTER_LENGTH
Synonym for CHAR_LENGTH().

CHAR_LENGTH
Length of the string in characters.

CHR
Returns string based on integer values of the individual characters.

CONCAT
Returns concatenated string.

889/3812
CONCAT_WS
Concatenate with separator.

CONVERT
Convert a value from one type to another type.

ELT
Returns the N'th element from a set of strings.

EXPORT_SET
Returns an on string for every bit set, an off string for every bit not set.

EXTRACTVALUE
1 Returns the text of the first text node matched by the XPath expression.

FIELD
Returns the index position of a string in a list.

FIND_IN_SET
1 Returns the position of a string in a set of strings.

FORMAT
3 Formats a number.

FROM_BASE64
Given a base-64 encoded string, returns the decoded result as a binary string.

HEX
2 Returns hexadecimal value.

INSERT Function
Replaces a part of a string with another string.

INSTR
Returns the position of a string within a string.

LCASE
Synonym for LOWER().

LEFT
Returns the leftmost characters from a string.

LENGTH
Length of the string in bytes.

LENGTHB
Length of the given string, in bytes.

LIKE
Whether expression matches a pattern.

LOAD_FILE
Returns file contents as a string.

LOCATE
Returns the position of a substring in a string.

LOWER
4 Returns a string with all characters changed to lowercase.

LPAD
Returns the string left-padded with another string to a given length.

LTRIM
Returns the string with leading space characters removed.

MAKE_SET
Make a set of strings that matches a bitmask.

890/3812
MATCH AGAINST
Perform a fulltext search on a fulltext index.

Full-Text Index Stopwords


Default list of full-text stopwords used by MATCH...AGAINST.

MID
Synonym for SUBSTRING(str,pos,len).

NATURAL_SORT_KEY
Sorting that is closer to natural human sorting.

NOT LIKE
Same as NOT(expr LIKE pat [ESCAPE 'escape_char']).

NOT REGEXP
Same as NOT (expr REGEXP pat).

OCTET_LENGTH
Returns the length of the given string, in bytes.

ORD
Return ASCII or character code.

POSITION
Returns the position of a substring in a string.

QUOTE
Returns quoted, properly escaped string.

REPEAT Function
Returns a string repeated a number of times.

REPLACE Function
Replace occurrences of a string.

REVERSE
Reverses the order of a string.

RIGHT
Returns the rightmost N characters from a string.

RPAD
Returns the string right-padded with another string to a given length.

RTRIM
Returns the string with trailing space characters removed.

SFORMAT
Given a string and a formatting specification, returns a formatted string.

SOUNDEX
Returns a string based on how the string sounds.

SOUNDS LIKE
SOUNDEX(expr1) = SOUNDEX(expr2).

SPACE
Returns a string of space characters.

STRCMP
Compares two strings in sort order.

SUBSTR
Returns a substring from string starting at a given position.

SUBSTRING
Returns a substring from string starting at a given position.

891/3812
SUBSTRING_INDEX
Returns the substring from string before count occurrences of a delimiter.

TO_BASE64
Converts a string to its base-64 encoded form.

TO_CHAR
Converts a date/time/timestamp type expression to a string.

TRIM
Returns a string with all given prefixes or suffixes removed.

TRIM_ORACLE
Synonym for the Oracle mode version of TRIM().

UCASE
Synonym for UPPER().

UNCOMPRESS
Uncompresses string compressed with COMPRESS().

UNCOMPRESSED_LENGTH
Returns length of a string before being compressed with COMPRESS().

UNHEX
Interprets pairs of hex digits as numbers and converts to the character represented by the number.

UPDATEXML
Replace XML.

UPPER
Changes string to uppercase.

WEIGHT_STRING
Weight of the input string.

Type Conversion
When implicit type conversion takes place.

There are 3 related questions .

1.2.2.1 Regular Expressions Functions


MariaDB includes a number of functions for dealing with regular expressions.
Regular Expressions Overview
1 Regular Expressions allow MariaDB to perform complex pattern matching on a string.

PCRE - Perl Compatible Regular Expressions


PCRE (Perl Compatible Regular Expressions) for enhanced regular expressions.

NOT REGEXP
Same as NOT (expr REGEXP pat).

REGEXP
Performs pattern matching

REGEXP_INSTR
Position of the first appearance of a regex.

REGEXP_REPLACE
Replaces all occurrences of a pattern.

REGEXP_SUBSTR
2 Returns the matching part of a string.

892/3812
RLIKE
Synonym for REGEXP

There are 1 related questions .

1.2.2.1.1 Regular Expressions Overview


Contents
1. Special Characters
1. ^
2. $
3. .
4. *
5. +
6. ?
7. ()
8. {}
9. []
1. ^
2. Word boundaries
3. Character Classes
4. Character Names
10. Combining
11. Escaping

Regular Expressions allow MariaDB to perform complex pattern matching on a string. In many cases, the simple pattern
matching provided by LIKE 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


Until MariaDB 10.0.5 , 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 article for the
enhancements made in 10.0.5.

Regular expression matches are performed with the REGEXP 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:

893/3812
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 |
+-------------------------+

894/3812
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)*

895/3812
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:

896/3812
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 :<: and :>: 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:

897/3812
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

898/3812
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 ','

899/3812
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:

900/3812
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+ :

901/3812
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 |
+---------------------+

1.2.2.1.2 Perl Compatible Regular Expressions


(PCRE) Documentation

902/3812
Contents
1.PCRE Versions
2.PCRE Enhancements
3.New Regular Expression Functions
4.PCRE Syntax
1. Special Characters
2. Character Classes
3. Generic Character Types
4. Unicode Character Properties
1. General Category Properties For \p
and \P
2. Special Category Properties For \p
and \P
3. Script Names For \p and \P
5. Extended Unicode Grapheme
Sequence
6. Simple Assertions
7. Option Setting
8. Multiline Matching
9. Newline Conventions
10. Newline Sequences
11. Comments
12. Quoting
13. Resetting the Match Start
14. Non-Capturing Groups
15. Non-Greedy Quantifiers
16. Atomic Groups
17. Possessive quantifiers
18. Absolute and Relative Numeric
Backreferences
19. Named Subpatterns and
Backreferences
20. Positive and Negative Look-Ahead
and Look-Behind Assertions
21. Subroutine Reference and Recursive
Patterns
22. Defining Subpatterns For Use By
Reference
23. Conditional Subpatterns
1. Conditions With Subpattern
References
2. Other Kinds of Conditions
24. Matching Zero Bytes (0x00)
25. Other PCRE Features
26. default_regex_flags Examples
27. See Also

PCRE Versions
PCRE Version Introduced Maturity
PCRE2 10.34 MariaDB 10.5.1 Stable
PCRE 8.43 MariaDB 10.1.39 Stable
PCRE 8.42 MariaDB 10.2.15 , MariaDB 10.1.33 , MariaDB 10.0.35 Stable
PCRE 8.41 MariaDB 10.2.8 , MariaDB 10.1.26 , MariaDB 10.0.32 Stable
PCRE 8.40 MariaDB 10.2.5 , MariaDB 10.1.22 , MariaDB 10.0.30 Stable
PCRE 8.39 MariaDB 10.1.15 , MariaDB 10.0.26 Stable
PCRE 8.38 MariaDB 10.1.10 , MariaDB 10.0.23 Stable
PCRE 8.37 MariaDB 10.1.5 , MariaDB 10.0.18 Stable
PCRE 8.36 MariaDB 10.1.2 , MariaDB 10.0.15 Stable
PCRE 8.35 MariaDB 10.1.0 , MariaDB 10.0.12 Stable
PCRE 8.34 MariaDB 10.0.8 Stable

903/3812
PCRE Enhancements
MariaDB 10.0.5 switched to the PCRE library, which significantly improved the power of the REGEXP/RLIKE
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 introduced three new functions that work with regular expressions:
REGEXP_REPLACE(), REGEXP_INSTR() and REGEXP_SUBSTR().
Also, REGEXP/RLIKE, and the new functions, now work correctly with all multi-byte character sets 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) - Replaces all occurrences of a pattern.
REGEXP_INSTR(subject, pattern) - Position of the first appearance of a regex .
REGEXP_SUBSTR(subject,pattern) - 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), so you won't need to change your applications that use SQL queries with the REGEXP/RLIKE
predicate.
MariaDB 10.0.11 introduced the 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 , 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 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 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 ,

904/3812
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
905/3812
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,
906/3812
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 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)

907/3812
(?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)


908/3812
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

Comments
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

909/3812
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(), 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


910/3812
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

911/3812
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

912/3812
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 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 for details.
Enhanced regex was implemented as a GSoC 2013 project by Sudheera Palihakkara.

default_regex_flags Examples
MariaDB starting with 10.0.11
The default_regex_flags variable was introduced in MariaDB 10.0.11

The 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:

913/3812
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

1.2.2.1.3 NOT REGEXP


Syntax
expr NOT REGEXP pat, expr NOT RLIKE pat

Description
This is the same as NOT (expr REGEXP pat).

1.2.2.1.4 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 for details on the syntax for regular expressions (see also PCRE
Regular Expressions).
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 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 moved to the PCRE regex library - see PCRE Regular Expressions for enhancements to REGEXP
introduced in MariaDB 10.0.5 .
The default_regex_flags variable addresses the remaining compatibilities between PCRE and the old regex library.

Examples

914/3812
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 introduced the 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 |
+-----------------------+

1.2.2.1.5 REGEXP_INSTR
Syntax
915/3812
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 to get offsets in bytes.
The function follows the case sensitivity rules of the effective collation. 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 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

1.2.2.1.6 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. 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 library for enhanced regular expression performance, and REGEXP_REPLACE
was introduced as part of this enhancement.
The default_regex_flags variable addresses the remaining compatibilities between PCRE and the old regex library.
916/3812
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

1.2.2.1.7 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. 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 library for enhanced regular expression performance, and REGEXP_SUBSTR
was introduced as part of this enhancement.
The 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

917/3812
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

1.2.2.1.8 RLIKE
Syntax
expr REGEXP pat, expr RLIKE pat

Description
RLIKE is a synonym for REGEXP.

1.2.2.2 Dynamic Columns Functions


Dynamic columns 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.
COLUMN_ADD
Adds or updates dynamic columns.

COLUMN_CHECK
Checks if a dynamic column blob is valid

COLUMN_CREATE
1 Returns a dynamic columns blob.

COLUMN_DELETE
Deletes a dynamic column.

COLUMN_EXISTS
Checks is a column exists.

COLUMN_GET
Gets a dynamic column value by name.

COLUMN_JSON
4 Returns a JSON representation of dynamic column blob data

COLUMN_LIST
Returns comma-separated list of columns names.

1.2.2.2.1 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
918/3812
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.

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() ), hence, in order to update the value in the table you have
to use the UPDATE ... SET dynamic_col=COLUMN_ADD(dynamic_col,
....) pattern.

1.2.2.2.2 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_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.

1.2.2.2.3 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 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 for further details.

Examples
INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE("column_name", "value");

1.2.2.2.4 COLUMN_DELETE
919/3812
Syntax
COLUMN_DELETE(dyncol_blob, column_nr, column_nr...);
COLUMN_DELETE(dyncol_blob, column_name, column_name...);

Description
Deletes a dynamic column with the specified name. Multiple names can be given. The return value is a dynamic column
blob after the modification.

1.2.2.2.5 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 for more information.

1.2.2.2.6 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 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 for more information about datatypes.

1.2.2.2.7 COLUMN_JSON
Syntax

920/3812
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 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.

1.2.2.2.8 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 for more information.

1.2.2.3 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

921/3812
SELECT ASCII(9);
+----------+
| ASCII(9) |
+----------+
| 57 |
+----------+

SELECT ASCII('9');
+------------+
| ASCII('9') |
+------------+
| 57 |
+------------+

SELECT ASCII('abc');
+--------------+
| ASCII('abc') |
+--------------+
| 97 |
+--------------+

1.2.2.4 BIN
Syntax
BIN(N)

Description
Returns a string representation of the binary value of the given longlong (that is, BIGINT ) number. This is equivalent to
CONV(N,10,2) . 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
CONV()
OCT()
HEX()

1.2.2.5 BINARY Operator


This page describes the BINARY operator. For details about the data type, see Binary Data Type.

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 or BLOB .
922/3812
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 |
+-------------------+

1.2.2.6 BIT_LENGTH
Syntax
BIT_LENGTH(str)

Contents
1. Syntax
2. Description
3. Examples
4. Compatibility

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
923/3812
PostgreSQL and Sybase support BIT_LENGTH().

1.2.2.7 CAST
Syntax
CAST(expr AS type)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The CAST() function takes a value of one type and produces a value of another type, similar to the CONVERT()
function.
The type can be one of the following values:
BINARY
CHAR
DATE
DATETIME
DECIMAL[(M[,D])]
DOUBLE
FLOAT (from MariaDB 10.4.5)
INTEGER
Short for SIGNED INTEGER
SIGNED [INTEGER]
UNSIGNED [INTEGER]
TIME
VARCHAR (in Oracle mode, from MariaDB 10.3)
The main difference between CAST and CONVERT() is that CONVERT(expr,type) is ODBC syntax while CAST(expr as
type) and CONVERT(... USING ...) are SQL92 syntax.
In MariaDB 10.4 and later, you can use the CAST() function with the INTERVAL keyword.
Until MariaDB 5.5.31 , 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 without specifying the character set, the 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 |
+-------------------------------------------------+

924/3812
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 field as a CHAR 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 , 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
Microseconds in MariaDB
String literals
COLLATION()
CONVERT()

1.2.2.8 CHAR Function


925/3812
Syntax
CHAR(N,... [USING charset_name])

Description
CHAR() interprets each argument as an INT 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, 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
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
ASCII() - Return ASCII value of first character
ORD() - Return value for character in single or multi-byte character sets
CHR - Similar, Oracle-compatible, function

1.2.2.9 CHAR_LENGTH
Syntax
CHAR_LENGTH(str)
CHARACTER_LENGTH(str)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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() (or OCTET_LENGTH() in Oracle
mode) 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.
926/3812
It is synonymous with the CHARACTER_LENGTH() function.

Examples
SELECT CHAR_LENGTH('MariaDB');
+------------------------+
| CHAR_LENGTH('MariaDB') |
+------------------------+
| 7 |
+------------------------+

When Oracle mode from MariaDB 10.3 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:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');


+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π') | LENGTH('π') | LENGTHB('π') | OCTET_LENGTH('π') |
+-------------------+--------------+---------------+--------------------+
| 1 | 1 | 2 | 2 |
+-------------------+--------------+---------------+--------------------+

See Also
LENGTH()
LENGTHB()
OCTET_LENGTH()
Oracle mode from MariaDB 10.3

1.2.2.10 CHARACTER_LENGTH
Syntax
CHARACTER_LENGTH(str)

Description
CHARACTER_LENGTH() is a synonym for CHAR_LENGTH() .

1.2.2.11 CHR
MariaDB starting with 10.3.1
The CHR() function was introduced in MariaDB 10.3.1 to provide Oracle compatibility

Syntax
CHR(N)

Description
CHR() interprets each argument N as an integer and returns a VARCHAR(1) 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 and collation_database system variables.
CHR() is similar to the CHAR() function, but only accepts a single argument.
927/3812
CHR() is available in all sql_modes.

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
ASCII() - Return ASCII value of first character
ORD() - Return value for character in single or multi-byte character sets
CHAR() - Similar function which accepts multiple integers

1.2.2.12 CONCAT
Syntax
CONCAT(str1,str2,...)

Contents
1. Syntax
2. Description
1. Oracle Mode
3. Examples
4. See Also

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() function with an empty separator, because that function is NULL -safe.
Use IFNULL() to turn NULLs into empty strings.
928/3812
Oracle Mode
MariaDB starting with 10.3
In Oracle mode from MariaDB 10.3, CONCAT ignores 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, from MariaDB 10.3:

SELECT CONCAT('Ma', 'ria', NULL, 'DB');


+---------------------------------+
| CONCAT('Ma', 'ria', NULL, 'DB') |
+---------------------------------+
| MariaDB |
+---------------------------------+

See Also
GROUP_CONCAT()
Oracle mode from MariaDB 10.3

1.2.2.13 CONCAT_WS
Syntax
CONCAT_WS(separator,str1,str2,...)

Description
CONCAT_WS() stands for Concatenate With Separator and is a special form of CONCAT() . 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 .

929/3812
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()

1.2.2.14 CONVERT
Syntax
CONVERT(expr,type), CONVERT(expr USING transcoding_name)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The CONVERT() and CAST() functions take a value of one type and produce a value of another type.
The type can be one of the following values:
BINARY
CHAR
DATE
DATETIME
DECIMAL[(M[,D])]
DOUBLE
FLOAT (from MariaDB 10.4.5)
INTEGER
930/3812
Short for SIGNED INTEGER
SIGNED [INTEGER]
UNSIGNED [INTEGER]
TIME
VARCHAR (in Oracle mode, from MariaDB 10.3)
Note that in MariaDB, INT and INTEGER are the same thing.
BINARY produces a string with the BINARY 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() and CONVERT() is that CONVERT(expr,type) is ODBC syntax while
CAST(expr as type) and CONVERT(... USING ...) are SQL92 syntax.
CONVERT() with USING is used to convert data between different character sets. 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 to string to permit the LOWER 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

1.2.2.15 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 ,
MariaDB rounds it to the nearest INTEGER . 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() function.

Examples

931/3812
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() function. Returns the position of a string in a set of strings.
FIELD() function. Returns the index position of a string in a list.

1.2.2.16 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 |
+------------------------------+

1.2.2.17 EXTRACTVALUE
Syntax
EXTRACTVALUE(xml_frag, xpath_expr)

932/3812
Contents
1. Syntax
2. Description
1. Invalid Arguments
2. Explicit text() Expressions
3. Count Matches
4. Matches
3. Examples

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.

933/3812
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>[email protected]</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 |
+------+------+------+------+---------+

1.2.2.18 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() function.

Examples

934/3812
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() function. Returns the N'th element from a set of strings.

1.2.2.19 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 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() function. Returns the N'th element from a set of strings.

935/3812
1.2.2.20 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 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 |
+----------------+

1.2.2.21 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 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.

936/3812
SELECT TO_BASE64('Maria') AS 'Input';
+-----------+
| Input |
+-----------+
| TWFyaWE= |
+-----------+

SELECT FROM_BASE64('TWFyaWE=') AS 'Output';


+--------+
| Output |
+--------+
| Maria |
+--------+

1.2.2.22 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 ) number. This is equivalent to CONV(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() function.

MariaDB starting with 10.5.0


HEX() with an INET6 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:

SELECT HEX(CAST('2001:db8::ff00:42:8329' AS INET6));


+----------------------------------------------+
| HEX(CAST('2001:db8::ff00:42:8329' AS INET6)) |
+----------------------------------------------+
| 20010DB8000000000000FF0000428329 |
+----------------------------------------------+

See Also
937/3812
Hexadecimal literals
UNHEX()
CONV()
BIN()
OCT()

1.2.2.23 INSTR
Syntax
INSTR(str,substr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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(), 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() ; Returns the position of a string within a string
SUBSTRING_INDEX() ; Returns the substring from string before count occurrences of a delimiter

1.2.2.24 LCASE
Syntax
LCASE(str)

Description
LCASE() is a synonym for LOWER().

1.2.2.25 LEFT
Syntax
938/3812
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 |
+--------------------+

1.2.2.26 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 |
+-------------------------------------+

1.2.2.27 LENGTH
Syntax
LENGTH(str)

939/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns the length of the string str .
In the default mode, when Oracle mode from MariaDB 10.3 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() returns 5.
When running Oracle mode from MariaDB 10.3, the length is measured in characters, and LENGTH is a synonym for
CHAR_LENGTH().
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 from MariaDB 10.3 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:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');


+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π') | LENGTH('π') | LENGTHB('π') | OCTET_LENGTH('π') |
+-------------------+--------------+---------------+--------------------+
| 1 | 1 | 2 | 2 |
+-------------------+--------------+---------------+--------------------+

See Also
CHAR_LENGTH()
LENGTHB()
OCTET_LENGTH()
Oracle mode from MariaDB 10.3

1.2.2.28 LENGTHB
MariaDB starting with 10.3.1
Introduced in MariaDB 10.3.1 as part of the Oracle compatibility enhancements.

Syntax
LENGTHB(str)

Description
LENGTHB() returns the length of the given string, in bytes. When Oracle mode is not set, this is a synonym for
LENGTH.
940/3812
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() 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 from MariaDB 10.3 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:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');


+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π') | LENGTH('π') | LENGTHB('π') | OCTET_LENGTH('π') |
+-------------------+--------------+---------------+--------------------+
| 1 | 1 | 2 | 2 |
+-------------------+--------------+---------------+--------------------+

See Also
CHAR_LENGTH()
LENGTH()
OCTET_LENGTH()

1.2.2.29 LIKE
Syntax
expr LIKE pat [ESCAPE 'escape_char']
expr NOT LIKE pat [ESCAPE 'escape_char']

Contents
1. Syntax
2. Description
3. Examples
4. Optimizing LIKE
5. See Also

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 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 , or coerce either of them to a
BINARY string using CAST . Use SHOW COLLATION 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 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
941/3812
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 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)

942/3812
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, one can set the optimizer_use_condition_selectivity variable to 5. If this is done, then
the optimizer will read 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 indexes.
For more complex searches and operations on strings, you can use regular expressions, which were enhanced in
MariaDB 10 (see PCRE Regular Expressions).

1.2.2.30 LOAD_FILE
1.2.2.31 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() is the same as the two-argument form of LOCATE() , except that the order of the arguments is reversed.

Examples

943/3812
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() ; Returns the position of a string withing a string
SUBSTRING_INDEX() ; Returns the substring from string before count occurrences of a delimiter

1.2.2.32 LOWER
Syntax
LOWER(str)

Contents
1. Syntax
2. Description
3. Examples

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() ) are ineffective when applied to binary strings ( BINARY , VARBINARY , BLOB ). To perform
lettercase conversion, CONVERT 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 |
+----------------+-----------------------------------+

1.2.2.33 LPAD
944/3812
Syntax
LPAD(str, len [,padstr])

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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, 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 with SQL_MODE=Oracle, 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, with the pad string defaulting to space.

SELECT LPAD('hello',10);
+------------------+
| LPAD('hello',10) |
+------------------+
| hello |
+------------------+

Oracle mode version from MariaDB 10.3.6:

SELECT LPAD('',0),LPAD_ORACLE('',0);
+------------+-------------------+
| LPAD('',0) | LPAD_ORACLE('',0) |
+------------+-------------------+
| | NULL |
+------------+-------------------+

See Also
RPAD - Right-padding instead of left-padding.

1.2.2.34 LTRIM
Syntax
LTRIM(str)

945/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

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
with SQL_MODE=Oracle, 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:

SELECT LTRIM(''),LTRIM_ORACLE('');
+-----------+------------------+
| LTRIM('') | LTRIM_ORACLE('') |
+-----------+------------------+
| | NULL |
+-----------+------------------+

See Also
RTRIM - trailing spaces removed
TRIM - removes all given prefixes or suffixes

1.2.2.35 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

946/3812
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')) |
+--------------------------------+
| '' |
+--------------------------------+

1.2.2.36 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 for a full description, and Full-text Indexes 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 |
+----+-------------------------------------+-----------------+

1.2.2.37 Full-Text Index Stopwords


947/3812
1.2.2.38 MID
Syntax
MID(str,pos,len)

Description
MID(str,pos,len) is a synonym for SUBSTRING(str,pos,len).

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 |
+------------------+

1.2.2.39 NATURAL_SORT_KEY
MariaDB starting with 10.7.0
NATURAL_SORT_KEY was added in MariaDB 10.7.0.

Syntax
NATURAL_SORT_KEY(str)

Contents
1. Syntax
2. Description
3. Examples
1. Strings and Numbers
2. IPs
3. Generated Columns
4. Leading Zeroes

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.

948/3812
You can use also use NATURAL_SORT_KEY with generated columns. 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 .

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 |
+---------+

949/3812
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:

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:

950/3812
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 |
+------+

951/3812
1.2.2.40 NOT LIKE
Syntax
expr NOT LIKE pat [ESCAPE 'escape_char']

Description
This is the same as NOT (expr LIKE pat [ESCAPE 'escape_char']).

1.2.2.41 NOT REGEXP


1.2.2.42 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(), and, when
Oracle mode from MariaDB 10.3 is not set, a synonym for LENGTH().
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() 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 from MariaDB 10.3 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:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');


+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π') | LENGTH('π') | LENGTHB('π') | OCTET_LENGTH('π') |
+-------------------+--------------+---------------+--------------------+
| 1 | 1 | 2 | 2 |
+-------------------+--------------+---------------+--------------------+

See Also
CHAR_LENGTH()
LENGTH()
LENGTHB()
Oracle mode from MariaDB 10.3

1.2.2.43 ORD
Syntax
ORD(str)

952/3812
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() function.

Examples
SELECT ORD('2');
+----------+
| ORD('2') |
+----------+
| 50 |
+----------+

See Also
ASCII() - Return ASCII value of first character
CHAR() - Create a character from an integer value

1.2.2.44 POSITION
Syntax
POSITION(substr IN str)

Description
POSITION(substr IN str) is a synonym for LOCATE(substr,str).
It's part of ODBC 3.0.

1.2.2.45 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

953/3812
SELECT QUOTE("Don't!");
+-----------------+
| QUOTE("Don't!") |
+-----------------+
| 'Don\'t!' |
+-----------------+

SELECT QUOTE(NULL);
+-------------+
| QUOTE(NULL) |
+-------------+
| NULL |
+-------------+

1.2.2.46 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 ' |
+------------------------------------+

1.2.2.47 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 |
+---------------------------------------+

1.2.2.48 REVERSE
Syntax
954/3812
REVERSE(str)

Description
Returns the string str with the order of the characters reversed.

Examples
SELECT REVERSE('desserts');
+---------------------+
| REVERSE('desserts') |
+---------------------+
| stressed |
+---------------------+

1.2.2.49 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 |
+---------------------+

1.2.2.50 RPAD
Syntax
RPAD(str, len [, padstr])

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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, 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 with SQL_MODE=Oracle, NULL.
The Oracle mode version of the function can be accessed outside of Oracle mode by using RPAD_ORACLE as the
function name.

955/3812
Examples
SELECT RPAD('hello',10,'.');
+----------------------+
| RPAD('hello',10,'.') |
+----------------------+
| hello..... |
+----------------------+

SELECT RPAD('hello',2,'.');
+---------------------+
| RPAD('hello',2,'.') |
+---------------------+
| he |
+---------------------+

From MariaDB 10.3.1, with the pad string defaulting to space.

SELECT RPAD('hello',30);
+--------------------------------+
| RPAD('hello',30) |
+--------------------------------+
| hello |
+--------------------------------+

Oracle mode version from MariaDB 10.3.6:

SELECT RPAD('',0),RPAD_ORACLE('',0);
+------------+-------------------+
| RPAD('',0) | RPAD_ORACLE('',0) |
+------------+-------------------+
| | NULL |
+------------+-------------------+

See Also
LPAD - Left-padding instead of right-padding.

1.2.2.51 RTRIM
Syntax
RTRIM(str)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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
with SQL_MODE=Oracle, NULL.
The Oracle mode version of the function can be accessed outside of Oracle mode by using RTRIM_ORACLE as the
function name.

Examples

956/3812
SELECT QUOTE(RTRIM('MariaDB '));
+-----------------------------+
| QUOTE(RTRIM('MariaDB ')) |
+-----------------------------+
| 'MariaDB' |
+-----------------------------+

Oracle mode version from MariaDB 10.3.6:

SELECT RTRIM(''),RTRIM_ORACLE('');
+-----------+------------------+
| RTRIM('') | RTRIM_ORACLE('') |
+-----------+------------------+
| | NULL |
+-----------+------------------+

See Also
LTRIM - leading spaces removed
TRIM - removes all given prefixes or suffixes

1.2.2.52 SFORMAT
MariaDB starting with 10.7.0
SFORMAT was added in MariaDB 10.7.0.

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 use the fmtlib library 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 |
+----------------------------------------------------------------------------------------+

957/3812
See Also
10.7 preview feature: Python-like string formatting

1.2.2.53 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()

1.2.2.54 SOUNDS LIKE


Syntax
958/3812
expr1 SOUNDS LIKE expr2

Description
This is the same as SOUNDEX(expr1) = SOUNDEX(expr2) .

Example
SELECT givenname, surname FROM users WHERE givenname SOUNDS LIKE "robert";
+-----------+---------+
| givenname | surname |
+-----------+---------+
| Roberto | Castro |
+-----------+---------+

1.2.2.55 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)) |
+-----------------+
| ' ' |
+-----------------+

1.2.2.56 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

959/3812
SELECT STRCMP('text', 'text2');
+-------------------------+
| STRCMP('text', 'text2') |
+-------------------------+
| -1 |
+-------------------------+

SELECT STRCMP('text2', 'text');


+-------------------------+
| STRCMP('text2', 'text') |
+-------------------------+
| 1 |
+-------------------------+

SELECT STRCMP('text', 'text');


+------------------------+
| STRCMP('text', 'text') |
+------------------------+
| 0 |
+------------------------+

1.2.2.57 SUBSTR
Description
SUBSTR() is a synonym for SUBSTRING() .

1.2.2.58 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)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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, from MariaDB 10.3.3, 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

960/3812
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:

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() - Returns the position of a string within a string
LOCATE() - Returns the position of a string within a string
961/3812
SUBSTRING_INDEX() - Returns a string based on substring

1.2.2.59 SUBSTRING_INDEX
Syntax
SUBSTRING_INDEX(str,delim,count)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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() - Returns the position of a string within a string
LOCATE() - Returns the position of a string within a string
SUBSTRING() - Returns a string based on position

1.2.2.60 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.

962/3812
The reverse function, FROM_BASE64(), 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= |
+--------------------+

1.2.2.61 TO_CHAR
MariaDB starting with 10.6.1
The TO_CHAR function was introduced in MariaDB 10.6.1 to enhance Oracle compatibility.

Syntax
TO_CHAR(expr[, fmt])

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The TO_CHAR function converts an expr of type date, datetime, time or timestamp 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

963/3812
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

1.2.2.62 TRIM
Syntax
TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr FROM] str)

From MariaDB 10.3.6

TRIM_ORACLE([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr FROM] str)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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
with SQL_MODE=Oracle, 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.
964/3812
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, with SQL_MODE=Oracle not set:

SELECT TRIM(''),TRIM_ORACLE('');
+----------+-----------------+
| TRIM('') | TRIM_ORACLE('') |
+----------+-----------------+
| | NULL |
+----------+-----------------+

From MariaDB 10.3.6, with SQL_MODE=Oracle set:

SELECT TRIM(''),TRIM_ORACLE('');
+----------+-----------------+
| TRIM('') | TRIM_ORACLE('') |
+----------+-----------------+
| NULL | NULL |
+----------+-----------------+

See Also
LTRIM - leading spaces removed
RTRIM - trailing spaces removed

1.2.2.63 TRIM_ORACLE
MariaDB starting with 10.3.6
TRIM_ORACLE is a synonym for the Oracle mode version of the TRIM function, and is available in all modes.

1.2.2.64 UCASE
Syntax
UCASE(str)

Description
UCASE() is a synonym for UPPER() .

1.2.2.65 UNCOMPRESS
Syntax
UNCOMPRESS(string_to_uncompress)

965/3812
Description
Uncompresses a string compressed by the COMPRESS() 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 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 |
+------------------------+

1.2.2.66 UNCOMPRESSED_LENGTH
Syntax
UNCOMPRESSED_LENGTH(compressed_string)

Description
Returns the length that the compressed string had before being compressed with COMPRESS() .
UNCOMPRESSED_LENGTH() returns NULL or an incorrect result if the string is not compressed.
Until MariaDB 10.3.1, returns MYSQL_TYPE_LONGLONG , or bigint(10), in all cases. From MariaDB 10.3.1, returns
MYSQL_TYPE_LONG , or int(10), when the result would fit within 32-bits.

Examples
SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
+-----------------------------------------------+
| UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30))) |
+-----------------------------------------------+
| 30 |
+-----------------------------------------------+

1.2.2.67 UNHEX
Syntax
UNHEX(str)

Description
Performs the inverse operation of HEX(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
966/3812
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
HEX()
CONV()

1.2.2.68 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)

967/3812
1.2.2.69 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 , VARBINARY , BLOB ). The description of LOWER() shows
how to perform lettercase conversion of binary strings.

1.2.2.70 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, VARCHAR or TEXT), WEIGHT_STRING returns the string's collation weight. If
str is a binary string (BINARY, VARBINARY or BLOB), 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() function to represent non-printable results in hexadecimal format.
968/3812
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 |
+----------------------------------------------+

1.2.2.71 Type Conversion


Contents
1. Rules for Conversion on Comparison
1. Comparison Examples
2. Rules for Conversion on Dyadic
Arithmetic Operations
1. Arithmetic Examples

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 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 <=> 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. 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 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).
969/3812
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:

970/3812
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 (+,-,*,/). MariaDB chooses the minimum data
type that is guaranteed to fit the result and converts both arguments to the result data type.
For addition (+), subtraction (-) and multiplication (*), 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 (/), 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() or DATE_SUB() functions, or an
INTERVAL expression as the second argument:

971/3812
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 |
+--------------------+

1.2.3 Date & Time Functions


Functions for handling date and time, e.g. TIME, DATE, DAYNAME etc.
Microseconds in MariaDB
3 Microseconds have been supported since MariaDB 5.3.

Date and Time Units


Date or time units

ADD_MONTHS
Adds a number of months to a date.

ADDDATE
Add days or another interval to a date.

ADDTIME
2 Adds a time to a time or datetime.

CONVERT_TZ
Converts a datetime from one time zone to another.

CURDATE
Returns the current date.

CURRENT_DATE
Synonym for CURDATE().

CURRENT_TIME
Synonym for CURTIME().

CURRENT_TIMESTAMP
Synonym for NOW().

CURTIME
Returns the current time.
972/3812
DATE FUNCTION
Extracts the date portion of a datetime.

DATEDIFF
Difference in days between two date/time values.

DATE_ADD
1 Date arithmetic - addition.

DATE_FORMAT
3 Formats the date value according to the format string.

DATE_SUB
Date arithmetic - subtraction.

DAY
Synonym for DAYOFMONTH().

DAYNAME
Return the name of the weekday.

DAYOFMONTH
Returns the day of the month.

DAYOFWEEK
Returns the day of the week index.

DAYOFYEAR
Returns the day of the year.

EXTRACT
Extracts a portion of the date.

FROM_DAYS
Returns a date given a day.

FROM_UNIXTIME
7 Returns a datetime from a Unix timestamp.

GET_FORMAT
Returns a format string.

HOUR
Returns the hour.

LAST_DAY
Returns the last day of the month.

LOCALTIME
Synonym for NOW().

LOCALTIMESTAMP
Synonym for NOW().

MAKEDATE
Returns a date given a year and day.

MAKETIME
Returns a time.

MICROSECOND
Returns microseconds from a date or datetime.

MINUTE
2 Returns a minute from 0 to 59.

MONTH
Returns a month from 1 to 12.

973/3812
MONTHNAME
Returns the full name of the month.

NOW
Returns the current date and time.

PERIOD_ADD
Add months to a period.

PERIOD_DIFF
Number of months between two periods.

QUARTER
Returns year quarter from 1 to 4.

SECOND
Returns the second of a time.

SEC_TO_TIME
Converts a second to a time.

STR_TO_DATE
3 Converts a string to date.

SUBDATE
Subtract a date unit or number of days.

SUBTIME
Subtracts a time from a date/time.

SYSDATE
Returns the current date and time.

TIME Function
Extracts the time.

TIMEDIFF
Returns the difference between two date/times.

TIMESTAMP FUNCTION
Return the datetime, or add a time to a date/time.

TIMESTAMPADD
Add interval to a date or datetime.

TIMESTAMPDIFF
Difference between two datetimes.

TIME_FORMAT
Formats the time value according to the format string.

TIME_TO_SEC
Returns the time argument, converted to seconds.

TO_DAYS
Number of days since year 0.

TO_SECONDS
Number of seconds since year 0.

UNIX_TIMESTAMP
3 Returns a Unix timestamp.

UTC_DATE
Returns the current UTC date.

UTC_TIME
Returns the current UTC time.

974/3812
UTC_TIMESTAMP
Returns the current UTC date and time.

WEEK
Returns the week number.

WEEKDAY
Returns the weekday index.

WEEKOFYEAR
Returns the calendar week of the date as a number in the range from 1 to 53.

YEAR
Returns the year for the given date.

YEARWEEK
Returns year and week for a date.

There are 5 related questions .

1.2.3.1 Microseconds in MariaDB


Contents
1. Additional Information
2. MySQL 5.6 Microseconds
3. See Also

The TIME, DATETIME, and TIMESTAMP types, along with the temporal functions, CAST and dynamic columns,
support microseconds. The datetime precision of a column can be specified when creating the table with CREATE
TABLE, 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, DATE_FORMAT and FROM_UNIXTIME
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 , or TIMESTAMP ), both values are
compared as temporal values, not as strings.
The INFORMATION_SCHEMA.COLUMNS table has a new column DATETIME_PRECISION
NOW(), CURTIME(), UTC_TIMESTAMP(), UTC_TIME(), CURRENT_TIME(), CURRENT_TIMESTAMP(),
975/3812
LOCALTIME() and LOCALTIMESTAMP() now accept datetime precision as an optional argument. For example:
SELECT CURTIME(4);
--> 10:11:12.3456

TIME_TO_SEC() and UNIX_TIMESTAMP() preserve microseconds of the argument. These functions will return a
decimal number if the result non-zero datetime precision and an integer 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 table and the start_time , query_time , and lock_time fields in
the mysql.slow_log 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 has been added to the INFORMATION_SCHEMA.PROCESSLIST table, as well
as to the output of SHOW FULL PROCESSLIST .

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. Since MariaDB 10.1,
MariaDB has defaulted to the MySQL format, by means of the --mysql56-temporal-format variable. The MySQL version
requires slightly more storage but has some advantages in permitting the eventual support of negative dates, and in
replication.

See Also
Data Type Storage Requirements

1.2.3.2 Date and Time Units


The INTERVAL keyword can be used to add or subtract a time interval of time to a DATETIME , DATE or TIME value.
The syntax is:

INTERVAL time_quantity time_unit

For example, the SECOND unit is used below by the DATE_ADD() 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:

976/3812
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 + or a - operator;
with the following DATE or TIME functions: ADDDATE() , SUBDATE() , DATE_ADD() , DATE_SUB() ,
TIMESTAMPADD() , TIMESTAMPDIFF() , EXTRACT() ;
in the ON SCHEDULE clause of CREATE EVENT and ALTER EVENT .
when defining a partitioning BY SYSTEM_TIME

See also
Date and time literals

1.2.3.3 ADD_MONTHS
MariaDB starting with 10.6.1
The ADD_MONTHS function was introduced in MariaDB 10.6.1 to enhance Oracle compatibility. Similar functionality
can be achieved with the DATE_ADD function.

Syntax
ADD_MONTHS(date, months)

977/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
ADD_MONTHS adds an integer months to a given date (DATE, DATETIME or TIMESTAMP), 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

1.2.3.4 ADDDATE
Syntax
ADDDATE(date,INTERVAL expr unit), ADDDATE(expr,days)

978/3812
Description
When invoked with the INTERVAL form of the second argument, ADDDATE() is a synonym for DATE_ADD() . The related
function SUBDATE() is a synonym for DATE_SUB() . For information on the INTERVAL unit argument, see the discussion
for DATE_ADD() .
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 |
+---------------------+------------------------------+

1.2.3.5 ADDTIME
Syntax
979/3812
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 |
+-----------------------------------------------+

1.2.3.6 CONVERT_TZ
Syntax
CONVERT_TZ(dt,from_tz,to_tz)

Description
CONVERT_TZ() converts a datetime value dt from the time zone 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).
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 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:

980/3812
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 |
+-----------------------------------------------------+

1.2.3.7 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 |
+----------------------------+

1.2.3.8 CURRENT_DATE
Syntax
CURRENT_DATE, CURRENT_DATE()

Description
CURRENT_DATE and CURRENT_DATE() are synonyms for CURDATE().

1.2.3.9 CURRENT_TIME
981/3812
Syntax
CURRENT_TIME
CURRENT_TIME([precision])

Description
CURRENT_TIME and CURRENT_TIME() are synonyms for CURTIME() .

See Also
Microseconds in MariaDB

1.2.3.10 CURRENT_TIMESTAMP
Syntax
CURRENT_TIMESTAMP
CURRENT_TIMESTAMP([precision])

Description
CURRENT_TIMESTAMP and CURRENT_TIMESTAMP() are synonyms for NOW() .

See Also
Microseconds in MariaDB
The TIMESTAMP data type

1.2.3.11 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.
The optional precision determines the microsecond precision. See Microseconds in MariaDB.

Examples
SELECT CURTIME();
+-----------+
| CURTIME() |
+-----------+
| 12:45:39 |
+-----------+

SELECT CURTIME() + 0;
+---------------+
| CURTIME() + 0 |
+---------------+
| 124545.000000 |
+---------------+

With precision:

982/3812
SELECT CURTIME(2);
+-------------+
| CURTIME(2) |
+-------------+
| 09:49:08.09 |
+-------------+

See Also
Microseconds in MariaDB

1.2.3.12 DATE FUNCTION


Syntax
DATE(expr)

Description
Extracts the date part of the date or datetime expression expr.

Examples
SELECT DATE('2013-07-18 12:21:32');
+-----------------------------+
| DATE('2013-07-18 12:21:32') |
+-----------------------------+
| 2013-07-18 |
+-----------------------------+

Error Handling
Until MariaDB 5.5.32 , some versions of MariaDB returned 0000-00-00 when passed an invalid date. From 5.5.32,
NULL is returned.

1.2.3.13 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 |
+----------------------------------------------+

983/3812
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 |
+---------------------+-------------------+

1.2.3.14 DATE_ADD
Syntax
DATE_ADD(date,INTERVAL expr unit)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 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 |
+-------------------------------+

984/3812
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
ADD_MONTHS

1.2.3.15 DATE_FORMAT
Syntax
DATE_FORMAT(date, format[, locale])

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 system variable. See server locale for
more on the supported locales.

985/3812
The options that can be used by DATE_FORMAT(), as well as its inverse STR_TO_DATE() and the
FROM_UNIXTIME() function, are:

Option Description
%a Short weekday name in current locale (Variable lc_time_names).
Short form month name in current locale. For locale en_US this is one of:
%b
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 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).
%m Month with 2 digits.
%p AM/PM according to current locale (Variable 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).
%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(), skip all numbers.
%. For str_to_date(), skip all punctation characters.
%@ For str_to_date(), skip all alpha characters.
%% A literal % character.

To get a date in one of the standard formats, GET_FORMAT() can be used.

Examples

986/3812
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 |
+---------------------------------+

MariaDB starting with 10.3.2


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:
SELECT DATE_FORMAT('2006-01-01', '%W', 'el_GR');
+------------------------------------------+
| DATE_FORMAT('2006-01-01', '%W', 'el_GR') |
+------------------------------------------+
| Κυριακή |
+------------------------------------------+

See Also
STR_TO_DATE()
FROM_UNIXTIME()

1.2.3.16 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
987/3812
negative intervals. unit is a keyword indicating the units in which the expression should be interpreted. See Date and
Time Units for a complete list of permitted units.
See also DATE_ADD() .

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 |
+----------------------------------------------------------------+

1.2.3.17 DAY
Syntax
DAY(date)

Description
DAY() is a synonym for DAYOFMONTH() .

1.2.3.18 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 system variable. See server locale 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");

988/3812
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 |
+-----------------------+

1.2.3.19 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 |
+---------------------+

1.2.3.20 DAYOFWEEK
989/3812
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() 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 |
+---------------------+------------+--------------+------------+

1.2.3.21 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 |
+-------------------------+

1.2.3.22 EXTRACT
990/3812
Syntax
EXTRACT(unit FROM date)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
The EXTRACT() function extracts the required unit from the date. See Date and Time Units for a complete list of
permitted units.
In MariaDB 10.0.7 and MariaDB 5.5.35 , EXTRACT (HOUR FROM ...) was changed to return a value from 0 to 23,
adhering to the SQL standard. Until MariaDB 10.0.6 and MariaDB 5.5.34 , and in all versions of MySQL at least as
of MySQL 5.7, it could return a value > 23. HOUR() 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 and MariaDB 5.5.35 , 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 Literals
HOUR()

1.2.3.23 FROM_DAYS
991/3812
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() function.

Examples
SELECT FROM_DAYS(730669);
+-------------------+
| FROM_DAYS(730669) |
+-------------------+
| 2000-07-03 |
+-------------------+

1.2.3.24 FROM_UNIXTIME
Syntax
FROM_UNIXTIME(unix_timestamp), FROM_UNIXTIME(unix_timestamp,format)

Contents
1. Syntax
2. Description
3. Performance Considerations
4. Examples
5. See Also

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. unix_timestamp is an internal timestamp value such as is produced by the
UNIX_TIMESTAMP() 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() 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 as a storage type if you require dates beyond this.

The options that can be used by FROM_UNIXTIME(), as well as DATE_FORMAT() and STR_TO_DATE(), are:

Option Description
%a Short weekday name in current locale (Variable lc_time_names).
Short form month name in current locale. For locale en_US this is one of:
%b
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.

992/3812
%f Microseconds 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).
%m Month with 2 digits.
%p AM/PM according to current locale (Variable 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).
%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(), skip all numbers.
%. For str_to_date(), skip all punctation characters.
%@ For str_to_date(), skip all alpha characters.
%% A literal % character.

Performance Considerations
If your session 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 for details on how to do this.

Examples

993/3812
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()
DATE_FORMAT()
STR_TO_DATE()

1.2.3.25 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() and the STR_TO_DATE()
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
994/3812
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 |
+--------------------------------------------------+

1.2.3.26 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 ...) (>= MariaDB 10.0.7 and MariaDB 5.5.35 ) 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 Literals
EXTRACT()

995/3812
1.2.3.27 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'

1.2.3.28 LOCALTIME
Syntax
LOCALTIME
LOCALTIME([precision])

Description
LOCALTIME and LOCALTIME() are synonyms for NOW() .

See Also
Microseconds in MariaDB

1.2.3.29 LOCALTIMESTAMP
Syntax
996/3812
LOCALTIMESTAMP
LOCALTIMESTAMP([precision])

Description
LOCALTIMESTAMP and LOCALTIMESTAMP() are synonyms for NOW() .

See Also
Microseconds in MariaDB

1.2.3.30 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 |
+------------------+

1.2.3.31 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

997/3812
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' |
+---------+------+-----------------------------------------------+

1.2.3.32 MICROSECOND
Syntax
MICROSECOND(expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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

998/3812
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

1.2.3.33 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 |
+---------------------+

1.2.3.34 MONTH
999/3812
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 |
+---------------------+

1.2.3.35 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 system variable. See server locale 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 |
+-------------------------+

1.2.3.36 NOW
Syntax

1000/3812
NOW([precision])
CURRENT_TIMESTAMP
CURRENT_TIMESTAMP([precision])
LOCALTIME, LOCALTIME([precision])
LOCALTIMESTAMP
LOCALTIMESTAMP([precision])

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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.
The optional precision determines the microsecond precision. See Microseconds in MariaDB.
NOW() (or its synonyms) can be used as the default value for TIMESTAMP columns as well as, since MariaDB 10.0.1
, DATETIME columns. Before MariaDB 10.0.1 , 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 table, a default CURRENT TIMESTAMP is displayed as
CURRENT_TIMESTAMP up until MariaDB 10.2.2 , and as current_timestamp() from MariaDB 10.2.3 , due to to
MariaDB 10.2 accepting expressions in the DEFAULT clause.

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 :

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

1001/3812
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
timestamp server system variable

1.2.3.37 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 |
+--------------------+

1.2.3.38 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.
1002/3812
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 |
+------------------------+

1.2.3.39 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 |
+-----------------------+

1.2.3.40 SECOND
Syntax
SECOND(time)

Description
Returns the second for a given time (which can include microseconds), in the range 0 to 59, or NULL if not given a
valid time value.

Examples
1003/3812
SELECT SECOND('10:05:03');
+--------------------+
| SECOND('10:05:03') |
+--------------------+
| 3 |
+--------------------+

SELECT SECOND('10:05:01.999999');
+---------------------------+
| SECOND('10:05:01.999999') |
+---------------------------+
| 1 |
+---------------------------+

1.2.3.41 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. 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' |
+---------+------+-------------------------------------------+

1.2.3.42 STR_TO_DATE
Syntax
STR_TO_DATE(str,format)

1004/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
This is the inverse of the DATE_FORMAT() 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.
The options that can be used by STR_TO_DATE(), as well as its inverse DATE_FORMAT() and the
FROM_UNIXTIME() function, are:

Option Description
%a Short weekday name in current locale (Variable lc_time_names).
Short form month name in current locale. For locale en_US this is one of:
%b
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 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).
%m Month with 2 digits.
%p AM/PM according to current locale (Variable 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).
%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(), skip all numbers.
1005/3812
%. For str_to_date(), skip all punctation characters.
%@ For str_to_date(), 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()
FROM_UNIXTIME()

1.2.3.43 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() . See Date
and Time Units 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

1006/3812
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 |
+---------------------+--------------------------------+

1.2.3.44 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

1007/3812
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 |
+-----------------------------------------------+

1.2.3.45 SYSDATE
Syntax
SYSDATE([precision])

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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.
SYSDATE() returns the time at which it executes. This differs from the behavior for NOW(), 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 with a SET timestamp statement affects the value returned by
NOW() but not by SYSDATE(). This means that timestamp settings in the binary log 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 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.

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:

1008/3812
SELECT SYSDATE(4);
+--------------------------+
| SYSDATE(4) |
+--------------------------+
| 2018-07-10 10:17:13.1689 |
+--------------------------+

See Also
Microseconds in MariaDB
timestamp server system variable

1.2.3.46 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 |
+------------------------------------+

1.2.3.47 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

1009/3812
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 |
+----------------------------------------------------------------------+

1.2.3.48 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 |
+--------------------------------------------+

1.2.3.49 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, FRAC_SECOND was permitted as a synonym for MICROSECOND.

Examples

1010/3812
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 |
+-----------------------------------+

1.2.3.50 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() 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:

1011/3812
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 |
+---------+---------------+------+

1.2.3.51 TIME_FORMAT
Syntax
TIME_FORMAT(time,format)

Description
This is used like the DATE_FORMAT() 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 |
+--------------------------------------------+

1.2.3.52 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 . Before MariaDB 5.3 (and MySQL 5.6), the type was INT . The
1012/3812
returned value preserves microseconds of the argument. See also Microseconds in MariaDB.

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)

1.2.3.53 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() 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 |
+-----------------+

1.2.3.54 TO_SECONDS
1013/3812
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.

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 |
+--------------------+

1.2.3.55 UNIX_TIMESTAMP
Contents
1. Syntax
2. Description
1. Error Handling
2. Compatibility
3. Examples
4. See Also

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) 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 string, a DATETIME string, a TIMESTAMP , or a number in the format
YYMMDD or YYYYMMDD. The server interprets date as a value in the current time zone and converts it to an internal
value in UTC. Clients can set their time zone as described in time zones.
1014/3812
The inverse function of UNIX_TIMESTAMP() is FROM_UNIXTIME()
UNIX_TIMESTAMP() supports microseconds.

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 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 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(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()

1.2.3.56 UTC_DATE
Syntax
UTC_DATE, UTC_DATE()

Description
1015/3812
Returns the current UTC date 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 |
+------------+----------------+

1.2.3.57 UTC_TIME
Syntax
UTC_TIME
UTC_TIME([precision])

Description
Returns the current UTC 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 optional precision determines the microsecond precision. See Microseconds in MariaDB.

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

1.2.3.58 UTC_TIMESTAMP
Syntax
UTC_TIMESTAMP
UTC_TIMESTAMP([precision])

Description
Returns the current UTC 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.

1016/3812
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
Microseconds in MariaDB

1.2.3.59 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 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

1017/3812
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 |
+---------------------+-----------+-----------+

1.2.3.60 WEEKDAY
Syntax
WEEKDAY(date)

Description
1018/3812
Returns the weekday index for date ( 0 = Monday, 1 = Tuesday, ... 6 = Sunday).
This contrasts with DAYOFWEEK() 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 |
+---------------------+

1.2.3.61 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) .

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");

1019/3812
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 |
+---------------------+---------------+-----------+

1.2.3.62 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 |
+---------------------+

1020/3812
SELECT YEAR('1987-01-01');
+--------------------+
| YEAR('1987-01-01') |
+--------------------+
| 1987 |
+--------------------+

See Also
YEAR data type

1.2.3.63 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(). 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)

1.2.4 Aggregate Functions


1021/3812
The following functions (also called aggregate functions) can be used with the GROUP BY clause:
Stored Aggregate Functions
Custom aggregate functions.

AVG
Returns the average value.

BIT_AND
Bitwise AND.

BIT_OR
Bitwise OR.

BIT_XOR
Bitwise XOR.

COUNT
Returns count of non-null values.

COUNT DISTINCT
1 Returns count of number of different non-NULL values.

GROUP_CONCAT
Returns string with concatenated values from a group.

JSON_ARRAYAGG
3 Returns a JSON array containing an element for each value in a given set of JSON or SQL values.

JSON_OBJECTAGG
Returns a JSON object containing key-value pairs.

MAX
Returns the maximum value.

MIN
Returns the minimum value.

STD
Population standard deviation.

STDDEV
Population standard deviation.

STDDEV_POP
Returns the population standard deviation.

STDDEV_SAMP
1 Standard deviation.

SUM
Sum total.

VARIANCE
Population standard variance.

VAR_POP
Population standard variance.

VAR_SAMP
Returns the sample variance.

1.2.4.1 Stored Aggregate Functions


MariaDB starting with 10.3.3
The ability to create stored aggregate functions was added in MariaDB 10.3.3.

1022/3812
Contents
1. Standard Syntax
1. Using SQL/PL
2. Examples
1. SQL/PL Example
3. See Also

Aggregate functions 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 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 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:

1023/3812
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;


1024/3812
See Also
Stored Function Overview
CREATE FUNCTION
SHOW CREATE FUNCTION
DROP FUNCTION
Stored Routine Privileges
SHOW FUNCTION STATUS
Information Schema ROUTINES Table

1.2.4.2 AVG
Syntax
AVG([DISTINCT] expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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, and so can be used with the GROUP BY clause.
AVG() returns NULL if there were no matching rows.
AVG() can be used as a window function.

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 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 |
+---------+------------+

1025/3812
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:

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 (maximum)
MIN (minimum)
SUM (sum total)

1.2.4.3 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) precision. It is an
aggregate function, and so can be used with the GROUP BY 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 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:
1026/3812
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_XOR

1.2.4.4 BIT_OR
Syntax
BIT_OR(expr) [over_clause]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns the bitwise OR of all bits in expr . The calculation is performed with 64-bit (BIGINT) precision. It is an
aggregate function, and so can be used with the GROUP BY 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 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:

1027/3812
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_XOR

1.2.4.5 BIT_XOR
Syntax
BIT_XOR(expr) [over_clause]

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns the bitwise XOR of all bits in expr . The calculation is performed with 64-bit (BIGINT) precision. It is an
aggregate function, and so can be used with the GROUP BY 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 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:

1028/3812
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_OR

1.2.4.6 COUNT
Syntax
COUNT(expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns a count of the number of non-NULL values of expr in the rows retrieved by a SELECT statement. The result is
a BIGINT value. It is an aggregate function, and so can be used with the GROUP BY 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.

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 |
+----------+

1029/3812
COUNT(DISTINCT) example:

SELECT COUNT(DISTINCT (name)) FROM student;


+------------------------+
| COUNT(DISTINCT (name)) |
+------------------------+
| 4 |
+------------------------+

As a window function

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
COUNT DISTINCT
Window Functions

1.2.4.7 COUNT DISTINCT


Syntax
COUNT(DISTINCT expr,[expr...])

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 , COUNT can be used as a window function, COUNT DISTINCT cannot be.

Examples

1030/3812
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
COUNT

1.2.4.8 GROUP_CONCAT
Syntax
GROUP_CONCAT(expr)

Contents
1. Syntax
2. Description
1. LIMIT
3. Examples
4. See Also

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 variable, which
defaults to 1M (>= MariaDB 10.2.4 ) or 1K (<= MariaDB 10.2.3 ).
If group_concat_max_len <= 512, the return type is VARBINARY or VARCHAR; otherwise, the return type is BLOB or
TEXT. 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 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

1031/3812
Until MariaDB 10.3.2, it was not possible to use the LIMIT clause with GROUP_CONCAT . This restriction was lifted in
MariaDB 10.3.3.

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 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 (which sorts the concatenated
hosts), and the SELECT 's ORDER BY (which sorts the rows).
From MariaDB 10.3.3, LIMIT 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_WS()
SELECT
ORDER BY

1.2.4.9 JSON_ARRAYAGG
MariaDB starting with 10.5.0
JSON_ARRAYAGG was added in MariaDB 10.5.0.

Syntax
1032/3812
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.
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] |
+------------------+------------------+

1.2.4.10 JSON_OBJECTAGG
MariaDB starting with 10.5.0
JSON_OBJECTAGG was added in MariaDB 10.5.0.

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.

Examples

1033/3812
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"} |
+----------------------------------------+

1.2.4.11 MAX
Syntax
MAX([DISTINCT] expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 and ENUM 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, and so can be used with the GROUP BY clause.
MAX() can be used as a window function.
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:

1034/3812
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:

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 (average)
MIN (minimum)
SUM (sum total)
MIN/MAX optimization used by the optimizer
GREATEST() returns the largest value from a list

1.2.4.12 MIN
Syntax
1035/3812
MIN([DISTINCT] expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 and ENUM 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, and so can be used with the GROUP BY clause.
MIN() can be used as a window function.
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():

1036/3812
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:

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 (average)
MAX (maximum)
SUM (sum total)
MIN/MAX optimization used by the optimizer
LEAST() returns the smallest value from a list.

1.2.4.13 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() can be used instead.

It is an aggregate function, and so can be used with the GROUP BY clause.


STD() can be used as a window function.
This function returns NULL if there were no matching rows.

Examples
As an aggregate function:

1037/3812
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:

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 (equivalent, standard SQL)
STDDEV (equivalent, Oracle-compatible non-standard SQL)
VAR_POP (variance)
STDDEV_SAMP (sample standard deviation)

1.2.4.14 STDDEV
Syntax
STDDEV(expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns the population standard deviation of expr . This function is provided for compatibility with Oracle. The standard
SQL function STDDEV_POP() can be used instead.
It is an aggregate function, and so can be used with the GROUP BY clause.
STDDEV() can be used as a window function.
This function returns NULL if there were no matching rows.

Examples
1038/3812
As an aggregate function:

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:

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 (equivalent, standard SQL)
STD (equivalent, non-standard SQL)
VAR_POP (variance)
STDDEV_SAMP (sample standard deviation)

1.2.4.15 STDDEV_POP
Syntax
STDDEV_POP(expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns the population standard deviation of expr (the square root of VAR_POP() ). You can also use STD() or
STDDEV() , which are equivalent but not standard SQL.

It is an aggregate function, and so can be used with the GROUP BY clause.


STDDEV_POP() can be used as a window function.
STDDEV_POP() returns NULL if there were no matching rows.

1039/3812
Examples
As an aggregate function:

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:

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 (equivalent, non-standard SQL)
STDDEV (equivalent, Oracle-compatible non-standard SQL)
VAR_POP (variance)
STDDEV_SAMP (sample standard deviation)

1.2.4.16 STDDEV_SAMP
Syntax
STDDEV_SAMP(expr)

Description
Returns the sample standard deviation of expr (the square root of VAR_SAMP()).
It is an aggregate function, and so can be used with the GROUP BY clause.
STDDEV_SAMP() can be used as a window function.
STDDEV_SAMP() returns NULL if there were no matching rows.

1.2.4.17 SUM
Syntax
1040/3812
SUM([DISTINCT] expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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, 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 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 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:

1041/3812
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 (average)
MAX (maximum)
MIN (minimum)

1.2.4.18 VARIANCE
Syntax
VARIANCE(expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns the population standard variance of expr . This is an extension to standard SQL. The standard SQL function
VAR_POP() 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, and so can be used with the GROUP BY clause.
VARIANCE() can be used as a window function.
VARIANCE() returns NULL if there were no matching rows.

Examples

1042/3812
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:

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:

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 (equivalent, standard SQL)
STDDEV_POP (population standard deviation)
STDDEV_SAMP (sample standard deviation)

1.2.4.19 VAR_POP
Syntax
VAR_POP(expr)

1043/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

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(), 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, and so can be used with the GROUP BY clause.
VAR_POP() can be used as a window function.
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:

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:

1044/3812
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 (equivalent, non-standard SQL)
STDDEV_POP (population standard deviation)
STDDEV_SAMP (sample standard deviation)

1.2.4.20 VAR_SAMP
Syntax
VAR_SAMP(expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns the sample variance of expr . That is, the denominator is the number of rows minus one.
It is an aggregate function, and so can be used with the GROUP BY clause.
VAR_SAMP() can be used as a window function.
VAR_SAMP() returns NULL if there were no matching rows.

Examples
As an aggregate function:

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:
1045/3812
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 (variance)
STDDEV_POP (population standard deviation)

1.2.5 Numeric Functions


Functions dealing with numerals, including ABS, CEIL, DIV, EXP, PI, SIN, etc.
Addition Operator (+)
Addition.

Subtraction Operator (-)


Subtraction and unary minus.

Division Operator (/)


2 Division.

Multiplication Operator (*)


Multiplication.

Modulo Operator (%)


Modulo operator. Returns the remainder of N divided by M.

DIV
Integer division.

ABS
Returns an absolute value.

ACOS
Returns an arc cosine.

ASIN
Returns the arc sine.

ATAN
Returns the arc tangent.

ATAN2
Returns the arc tangent of two variables.

CEIL
Synonym for CEILING().

CEILING
Returns the smallest integer not less than X.

1046/3812
CONV
Converts numbers between different number bases.

COS
Returns the cosine.

COT
Returns the cotangent.

CRC32
Computes a cyclic redundancy check (CRC) value.

CRC32C
Computes a cyclic redundancy check (CRC) value using the Castagnoli polynomial.

DEGREES
Converts from radians to degrees.

EXP
e raised to the power of the argument.

FLOOR
Largest integer value not greater than the argument.

GREATEST
1 Returns the largest argument.

LEAST
Returns the smallest argument.

LN
Returns natural logarithm.

LOG
Returns the natural logarithm.

LOG10
Returns the base-10 logarithm.

LOG2
Returns the base-2 logarithm.

MOD
Modulo operation. Remainder of N divided by M.

OCT
Returns octal value.

PI
Returns the value of π (pi).

POW
Returns X raised to the power of Y.

POWER
Synonym for POW().

RADIANS
Converts from degrees to radians.

RAND
Random floating-point value.

ROUND
Rounds a number.

SIGN
Returns 1, 0 or -1.
1047/3812
SIN
Returns the sine.

SQRT
Square root.

TAN
Returns the tangent.

TRUNCATE
The TRUNCATE function truncates a number to a specified number of decimal places.

1.2.5.1 Addition Operator (+)


1.2.5.2 Subtraction Operator (-)
1.2.5.3 Division Operator (/)
1.2.5.4 Multiplication Operator (*)
1.2.5.5 Modulo Operator (%)
1.2.5.6 DIV
Syntax
DIV

Description
Integer division. Similar to FLOOR(), but is safe with BIGINT values. Incorrect results may occur for non-integer
operands that exceed BIGINT range.
If the ERROR_ON_DIVISION_BY_ZERO SQL_MODE is used, a division by zero produces an error. Otherwise, it returns
NULL.
The remainder of a division can be obtained using the MOD operator.

Examples
SELECT 300 DIV 7;
+-----------+
| 300 DIV 7 |
+-----------+
| 42 |
+-----------+

SELECT 300 DIV 0;


+-----------+
| 300 DIV 0 |
+-----------+
| NULL |
+-----------+

1.2.5.7 ABS
Syntax
ABS(X)

1048/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

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()

1.2.5.8 ACOS
Syntax
ACOS(X)

Contents
1. Syntax
2. Description
3. Examples

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

1049/3812
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 |
+------------------+

1.2.5.9 ASIN
Syntax
ASIN(X)

Contents
1. Syntax
2. Description
3. Examples

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' |
+---------+------+-----------------------------------------+

1.2.5.10 ATAN
1050/3812
Syntax
ATAN(X)

Contents
1. Syntax
2. Description
3. Examples

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 |
+---------------------+

1.2.5.11 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 |
+--------------------+

1.2.5.12 CEIL
Syntax
CEIL(X)

1051/3812
Description
CEIL() is a synonym for CEILING().

1.2.5.13 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 |
+----------------+

1.2.5.14 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() , OCT() , HEX() , UNHEX() . Also, MariaDB allows binary
literal values and hexadecimal literal values.

Examples

1052/3812
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 |
+------------------------------+

1.2.5.15 COS
Syntax
COS(X)

Description
Returns the cosine of X, where X is given in radians.

Examples
SELECT COS(PI());
+-----------+
| COS(PI()) |
+-----------+
| -1 |
+-----------+

1.2.5.16 COT
Syntax
COT(X)

Description
Returns the cotangent of X.

Examples

1053/3812
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)'

1.2.5.17 CRC32
Syntax
<= MariaDB 10.7

CRC32(expr)

From MariaDB 10.8

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 introduced the CRC32C() function,
which uses the alternate Castagnoli polynomia.

MariaDB starting with 10.8


Often, CRC is computed in pieces. To facilitate this, MariaDB 10.8.0 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

SELECT CRC32(CRC32('Maria'),'DB');
+----------------------------+
| CRC32(CRC32('Maria'),'DB') |
+----------------------------+
| 4227209140 |
+----------------------------+

1054/3812
See Also
CRC32C()

1.2.5.18 CRC32C
MariaDB starting with 10.8
Introduced in MariaDB 10.8.0 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() 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 |
+------------------------------+

1.2.5.19 DEGREES
Syntax
DEGREES(X)

Description
Returns the argument X , converted from radians to degrees.
This is the converse of the RADIANS() function.

Examples

1055/3812
SELECT DEGREES(PI());
+---------------+
| DEGREES(PI()) |
+---------------+
| 180 |
+---------------+

SELECT DEGREES(PI() / 2);


+-------------------+
| DEGREES(PI() / 2) |
+-------------------+
| 90 |
+-------------------+

SELECT DEGREES(45);
+-----------------+
| DEGREES(45) |
+-----------------+
| 2578.3100780887 |
+-----------------+

1.2.5.20 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()
(using a single argument only) or LN().
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 |
+-----------+

1.2.5.21 FLOOR
Syntax
1056/3812
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 |
+--------------+

1.2.5.22 GREATEST
1.2.5.23 LEAST
1.2.5.24 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() .

Examples
SELECT LN(2);
+-------------------+
| LN(2) |
+-------------------+
| 0.693147180559945 |
+-------------------+

SELECT LN(-2);
+--------+
| LN(-2) |
+--------+
| NULL |
+--------+

1.2.5.25 LOG
Syntax
LOG(X), LOG(B,X)

1057/3812
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() 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 |
+----------+

1.2.5.26 LOG10
Syntax
LOG10(X)

Description
Returns the base-10 logarithm of X.

1058/3812
Examples
SELECT LOG10(2);
+-------------------+
| LOG10(2) |
+-------------------+
| 0.301029995663981 |
+-------------------+

SELECT LOG10(100);
+------------+
| LOG10(100) |
+------------+
| 2 |
+------------+

SELECT LOG10(-100);
+-------------+
| LOG10(-100) |
+-------------+
| NULL |
+-------------+

1.2.5.27 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 |
+------------+

1.2.5.28 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.
1059/3812
If the ERROR_ON_DIVISION_BY_ZERO SQL_MODE is used, any number modulus zero produces an error. Otherwise, it
returns NULL.
The integer part of a division can be obtained using DIV.

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 |
+----------+

1.2.5.29 OCT
Syntax
OCT(N)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns a string representation of the octal value of N, where N is a longlong (BIGINT) number. This is equivalent to
CONV(N,10,8). Returns NULL if N is NULL.

Examples

1060/3812
SELECT OCT(34);
+---------+
| OCT(34) |
+---------+
| 42 |
+---------+

SELECT OCT(12);
+---------+
| OCT(12) |
+---------+
| 14 |
+---------+

See Also
CONV()
BIN()
HEX()

1.2.5.30 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 |
+-------------------------------+

1.2.5.31 POW
Syntax
POW(X,Y)

Description
Returns the value of X raised to the power of Y.
POWER() is a synonym.

Examples

1061/3812
SELECT POW(2,3);
+----------+
| POW(2,3) |
+----------+
| 8 |
+----------+

SELECT POW(2,-2);
+-----------+
| POW(2,-2) |
+-----------+
| 0.25 |
+-----------+

1.2.5.32 POWER
Syntax
POWER(X,Y)

Description
This is a synonym for POW(), which returns the value of X raised to the power of Y.

1.2.5.33 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() 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 |
+------------------+

1062/3812
1.2.5.34 RAND
Contents
1. Syntax
2. Description
3. Practical uses
4. Examples
5. See Also

Syntax
RAND(), RAND(N)

Description
Returns a random DOUBLE 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.

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:


1063/3812
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
rand_seed1 and rand_seed2 system variables

1.2.5.35 ROUND
Syntax
ROUND(X), ROUND(X,D)

Description
Rounds the argument X to D decimal places. The rounding algorithm depends on the data type of X . 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.

Examples

1064/3812
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 |
+-------------------+

1.2.5.36 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

1065/3812
SELECT SIGN(-32);
+-----------+
| SIGN(-32) |
+-----------+
| -1 |
+-----------+

SELECT SIGN(0);
+---------+
| SIGN(0) |
+---------+
| 0 |
+---------+

SELECT SIGN(234);
+-----------+
| SIGN(234) |
+-----------+
| 1 |
+-----------+

See Also
ABS()

1.2.5.37 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 |
+------------------+

1.2.5.38 SQRT
Syntax
SQRT(X)

Description
1066/3812
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 |
+------------+

1.2.5.39 TAN
Syntax
TAN(X)

Description
Returns the tangent of X, where X is given in radians.

Examples

1067/3812
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 |
+--------------------+

1.2.5.40 TRUNCATE
This page documents the TRUNCATE function. See TRUNCATE TABLE for the DDL statement.

Syntax
TRUNCATE(X,D)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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

1068/3812
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

1.2.6 Control Flow Functions


Built-In functions for assessing data to determine what results to return.
CASE OPERATOR
Returns the result where value=compare_value or for the first condition that is true.

DECODE
Decrypts a string encoded with ENCODE(), or, in Oracle mode, matches expressions.

DECODE_ORACLE
Synonym for the Oracle mode version of DECODE().

IF Function
If expr1 is TRUE, returns expr2; otherwise it returns expr3.

IFNULL
Check whether an expression is NULL.

NULLIF
Returns NULL if expr1 = expr2.

NVL
Synonym for IFNULL.

NVL2
Returns a value based on whether a specified expression is NULL or not.
1069/3812
There are 1 related questions .

1.2.6.1 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

Contents
1. Syntax
2. Description
3. Examples

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, 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 |
+-----------------------------------------------------+

1.2.6.2 DECODE
Syntax
DECODE(crypt_str,pass_str)

In Oracle mode from MariaDB 10.3.2:

DECODE(expr, search_expr, result_expr [, search_expr2, result_expr2 ...] [default_expr])

In all modes from MariaDB 10.3.2:

DECODE_ORACLE(expr, search_expr, result_expr [, search_expr2, result_expr2 ...] [default_expr])

1070/3812
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(). The resulting string will be the original string only if pass_str is the same.
In Oracle mode from MariaDB 10.3.2, 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:

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 |
+----------------------------------------------------------------------------+

1.2.6.3 DECODE_ORACLE
MariaDB starting with 10.3.2
DECODE_ORACLE is a synonym for the Oracle mode version of the DECODE function, and is available in all modes.

1.2.6.4 IF Function
Syntax
IF(expr1,expr2,expr3)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
1071/3812
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 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, which differs from the IF() function described above.

1.2.6.5 IFNULL
Syntax
IFNULL(expr1,expr2)
NVL(expr1,expr2)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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, NVL() is an alias for IFNULL().

Examples

1072/3812
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
IS NULL operator
IS NOT NULL operator
COALESCE function
NULLIF function
CONNECT data types

1.2.6.6 NULLIF
Syntax
NULLIF(expr1,expr2)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Returns NULL if expr1 = expr2 is true, otherwise returns expr1. This is the same as CASE 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 |
+-------------+

1073/3812
See Also
NULL values
IS NULL operator
IS NOT NULL operator
COALESCE function
IFNULL function
CONNECT data types

1.2.6.7 NVL
MariaDB starting with 10.3
From MariaDB 10.3, NVL is a synonym for IFNULL.

1.2.6.8 NVL2
MariaDB starting with 10.3
The NLV2 function was introduced in MariaDB 10.3.0.

Syntax
NVL2(expr1,expr2,expr3)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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)

1.2.7 Pseudo Columns


MariaDB has pseudo columns that can be used for different purposes.
_rowid
_rowid is an alias for the primary key column

1074/3812
1.2.7.1 _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 |
+---+-------+

1.2.8 Secondary Functions


These are commonly used functions, but they are not primary functions.
Bit Functions and Operators
Operators for comparison and setting of values, and related functions.

Encryption, Hashing and Compression Functions


Functions used for encryption, hashing and compression.

Information Functions
Functions which return information on the server, the user, or a given query.

Miscellaneous Functions
Functions for very singular and specific needs.

1.2.8.1 Bit Functions and Operators


Operators for comparison and setting of values, and related functions.
Operator Precedence
Precedence of SQL operators

&
Bitwise AND

<<
Left shift

1075/3812
>>
Shift right

BIT_COUNT
Returns the number of set bits

^
Bitwise XOR

|
Bitwise OR

~
Bitwise NOT

Parentheses
Parentheses modify the precedence of other operators in an expression

TRUE FALSE
TRUE and FALSE evaluate to 1 and 0

1.2.8.1.1 Operator Precedence


1.2.8.1.2 &
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.

Examples
SELECT 2&1;
+-----+
| 2&1 |
+-----+
| 0 |
+-----+

SELECT 3&1;
+-----+
| 3&1 |
+-----+
| 1 |
+-----+

SELECT 29 & 15;


+---------+
| 29 & 15 |
+---------+
| 13 |
+---------+

1.2.8.1.3 <<
Syntax
1076/3812
value1 << value2

Description
Converts a longlong (BIGINT) number (value1) to binary and shifts value2 units to the left.

Examples
SELECT 1 << 2;
+--------+
| 1 << 2 |
+--------+
| 4 |
+--------+

1.2.8.1.4 >>
Syntax
value1 >> value2

Description
Converts a longlong (BIGINT) number (value1) to binary and shifts value2 units to the right.

Examples
SELECT 4 >> 2;
+--------+
| 4 >> 2 |
+--------+
| 1 |
+--------+

1.2.8.1.5 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 |
+---------------+----------------------+

1.2.8.1.6 ^
1077/3812
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 |
+--------+

1.2.8.1.7 |
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.

Examples
SELECT 2|1;
+-----+
| 2|1 |
+-----+
| 3 |
+-----+

SELECT 29 | 15;
+---------+
| 29 | 15 |
+---------+
| 31 |
+---------+

1.2.8.1.8 ~
1078/3812
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 |
+--------+

1.2.8.1.9 Parentheses
Parentheses are sometimes called precedence operators - this means that they can be used to change the other
operator's precedence 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 flag.

Other uses
Parentheses must always be used to enclose subqueries.
Parentheses can also be used in a JOIN 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 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:

1079/3812
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.

1.2.8.1.10 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 |
+------+------+-------+-------+

1.2.8.2 Encryption, Hashing and Compression


Functions
Encryption, hashing and compression functions, such as ENCRYPT, DECRYPT, COMPRESS, PASSWORD etc.
AES_DECRYPT
Decryption data encrypted with AES_ENCRYPT

AES_ENCRYPT
3 Encrypts a string with the AES algorithm.

COMPRESS
Returns a binary, compressed string.

DECODE
Decrypts a string encoded with ENCODE(), or, in Oracle mode, matches expressions.

DES_DECRYPT
Decrypts a string encrypted with DES_ENCRYPT().

DES_ENCRYPT
Encrypts a string using the Triple-DES algorithm.

ENCODE
Encrypts a string.

ENCRYPT
Encrypts a string with Unix crypt().

MD5
MD5 checksum.

OLD_PASSWORD
Pre MySQL 4.1 password implementation.

PASSWORD
Calculates a password string.

RANDOM_BYTES
Generates a binary string of random bytes.

1080/3812
SHA1
Calculates an SHA-1 checksum.

SHA2
Calculates an SHA-2 checksum.

UNCOMPRESS
Uncompresses string compressed with COMPRESS().

UNCOMPRESSED_LENGTH
Returns length of a string before being compressed with COMPRESS().

There are 1 related questions .

1.2.8.2.1 AES_DECRYPT
Syntax
AES_DECRYPT(crypt_str,key_str)

Description
This function allows decryption of data using the official AES (Advanced Encryption Standard) algorithm. For more
information, see the description of AES_ENCRYPT() .

1.2.8.2.2 AES_ENCRYPT
Syntax
AES_ENCRYPT(str,key_str)

Description
AES_ENCRYPT() and AES_DECRYPT() 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, but you can
extend it up to 256 bits by modifying the source. We chose 128 bits because it is much faster and it 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.

Examples
INSERT INTO t VALUES (AES_ENCRYPT('text',SHA2('password',512)));

1.2.8.2.3 COMPRESS
1081/3812
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() .
The 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 |
+----------------------------------+

1.2.8.2.4 DECODE
1.2.8.2.5 DES_DECRYPT
DES_DECRYPT has been deprecated from MariaDB 10.10.0, and will be removed in a future release.

Syntax
DES_DECRYPT(crypt_str[,key_str])

Description
Decrypts a string encrypted with DES_ENCRYPT() . If an error occurs, this function returns NULL .
This function works only if MariaDB has been configured with TLS support.
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.

1082/3812
1.2.8.2.6 DES_ENCRYPT
DES_ENCRYPT has been deprecated from MariaDB 10.10.0, 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.
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()

1.2.8.2.7 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() .
1083/3812
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().

Examples
ENCODE('not so secret text', CONCAT('random_salt','password'))

1.2.8.2.8 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 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 |
+-----------------------+

1.2.8.2.9 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, is a nonbinary string in the connection character set
and collation, determined by the values of the character_set_connection and collation_connection system variables.
Before 5.5, the return value was a binary string.
NULL is returned if the argument was NULL.

Examples

1084/3812
SELECT MD5('testing');
+----------------------------------+
| MD5('testing') |
+----------------------------------+
| ae2b1fca515949e5d54fb22b8ed95575 |
+----------------------------------+

1.2.8.2.10 OLD_PASSWORD
Syntax
OLD_PASSWORD(str)

Contents
1. Syntax
2. Description
3. See Also

Description
OLD_PASSWORD() was added to MySQL when the implementation of PASSWORD() 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, the return value is a nonbinary string in the connection character set and collation, determined by
the values of the character_set_connection and 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()
MySQL manual on password hashing

1.2.8.2.11 PASSWORD
Syntax
PASSWORD(str)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 ) if the argument was NULL.
The return value is a nonbinary string in the connection character set and collation, determined by the values of the
character_set_connection and 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
(see privileges), usually used with the SET PASSWORD statement. It is not intended for use in other applications.
Until MariaDB 10.3, the return value is 41-bytes in length, and the first character is always '*'. From MariaDB 10.4, the
1085/3812
function takes into account the authentication plugin where applicable (A CREATE USER or SET PASSWORD
statement). For example, when used in conjunction with a user authenticated by the ed25519 plugin, 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 system variable. If this is set to 1 ( 0 is
default), MariaDB reverts to using the mysql_old_password authentication plugin 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 - permits the setting of basic criteria for passwords
OLD_PASSWORD() - pre-MySQL 4.1 password function

1.2.8.2.12 RANDOM_BYTES
MariaDB starting with 10.10.0
The RANDOM_BYTES function generates a binary string of random bytes. It was added in MariaDB 10.10.0.

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 , a cryptographically secure pseudo random generator (CSPRNG) is used.
Statements containing the RANDOM_BYTES function are unsafe for replication.
An error occurs if length is outside the range 1 to 1024.

1086/3812
1.2.8.2.13 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, the return
value is a nonbinary string in the connection character set and collation, determined by the values of the
character_set_connection and 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 |
+------------------------------------------+

1.2.8.2.14 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
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, determined by the values of the
character_set_connection and 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.

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 |
+------------------------------------------------------------------+

1087/3812
1.2.8.2.15 UNCOMPRESS
1.2.8.2.16 UNCOMPRESSED_LENGTH
1.2.8.3 Information Functions
General information functions, including BENCHMARK, CHARSET, DATABASE, USER, VERSION, etc.
BENCHMARK
Executes an expression repeatedly.

BINLOG_GTID_POS
Returns a string representation of the corresponding GTID position.

CHARSET
Returns the character set.

COERCIBILITY
Returns the collation coercibility value.

COLLATION
Collation of the string argument.

CONNECTION_ID
1 Connection ID.

CURRENT_ROLE
1 Current role name.

CURRENT_USER
1 Username/host that authenticated the current client.

DATABASE
Current default database.

DECODE_HISTOGRAM
Returns comma separated numerics corresponding to a probability distribution.

DEFAULT
Returns column default.

FOUND_ROWS
Number of (potentially) returned rows.

LAST_INSERT_ID
Last inserted auto_increment value.

LAST_VALUE
Returns the last value in a list or set of values.

PROCEDURE ANALYSE
1 Suggests optimal data types for each column.

ROWNUM
Function that returns the number of accepted rows so far.

ROW_COUNT
Number of rows affected by previous statement.

SCHEMA
Synonym for DATABASE().

SESSION_USER
Synonym for USER().

1088/3812
SYSTEM_USER
Synonym for USER().

USER
Current user/host.

VERSION
3 MariaDB server version.

There are 1 related questions .

1.2.8.3.1 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 mysql
client, 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)

1.2.8.3.2 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 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.

Examples
SELECT BINLOG_GTID_POS("master-bin.000001", 600);

See Also
SHOW BINLOG EVENTS - Show events and their positions in the binary log

1.2.8.3.3 CHARSET
Syntax
1089/3812
CHARSET(str)

Description
Returns the character set 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.

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 |
+-----------------+

1.2.8.3.4 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

1090/3812
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 |
+---------------------+

1.2.8.3.5 COLLATION
Syntax
COLLATION(str)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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.
See Character Sets and Collations.

Examples
SELECT COLLATION('abc');
+-------------------+
| COLLATION('abc') |
+-------------------+
| latin1_swedish_ci |
+-------------------+

SELECT COLLATION(_utf8'abc');
+-----------------------+
| COLLATION(_utf8'abc') |
+-----------------------+
| utf8_general_ci |
+-----------------------+

See Also
String literals
CAST()
CONVERT()

1.2.8.3.6 CONNECTION_ID
Syntax
1091/3812
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, returns MYSQL_TYPE_LONGLONG , or bigint(10), in all cases. From MariaDB 10.3.1, returns
MYSQL_TYPE_LONG , or int(10), when the result would fit within 32-bits.

Examples
SELECT CONNECTION_ID();
+-----------------+
| CONNECTION_ID() |
+-----------------+
| 3 |
+-----------------+

See Also
SHOW PROCESSLIST
INFORMATION_SCHEMA.PROCESSLIST

1.2.8.3.7 CURRENT_ROLE
Syntax
CURRENT_ROLE, CURRENT_ROLE()

Description
Returns the current role name. This determines your access privileges. The return value is a string in the utf8 character
set.
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 table.
USER() returns the combination of user and host used to login. CURRENT_USER() 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 |
+--------------+

1.2.8.3.8 CURRENT_USER
Syntax
1092/3812
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.
The value of CURRENT_USER() can differ from the value of USER(). CURRENT_ROLE() 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()
CREATE PROCEDURE

1.2.8.3.9 DATABASE
Syntax
DATABASE()

Description
Returns the default (current) database name as a string in the utf8 character set. If there is no default database,
DATABASE() returns NULL. Within a stored routine, 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 statement can be run. Another way to set the default database is specifying its
name at mysql command line client startup.

Examples
SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| NULL |
+------------+

USE test;
Database changed

SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| test |
+------------+

1093/3812
1.2.8.3.10 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.
See Histogram Based Statistics for details.

Examples

1094/3812
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 |

1.2.8.3.11 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, 0 is returned.
When using DEFAULT as a value to set in an INSERT or UPDATE statement, you can use the bare keyword DEFAULT
1095/3812
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;

1096/3812
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
1097/3812
CREATE TABLE DEFAULT Clause

1.2.8.3.12 FOUND_ROWS
Syntax
FOUND_ROWS()

Description
A SELECT statement may include a 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 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 which does not contain a
LIMIT clause. In this case you don't need to use the SQL_CALC_FOUND_ROWS option. This can be useful for
example in a stored procedure.
Also, this function works with some other statements which return a resultset, including SHOW, DESC and HELP. For
DELETE ... RETURNING you should use ROW_COUNT(). It also works as a prepared statement, 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 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.

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 |
+--------------+
1098/3812
See Also
ROW_COUNT()

1.2.8.3.13 LAST_INSERT_ID
Syntax
LAST_INSERT_ID(), LAST_INSERT_ID(expr)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
LAST_INSERT_ID() (no arguments) returns the first automatically generated value successfully inserted for an
AUTO_INCREMENT 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 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 or UPDATE 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, 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 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 and triggers 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))
1099/3812
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 | 1100/3812
| 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
AUTO_INCREMENT
AUTO_INCREMENT handling in InnoDB
Sequences - an alternative to auto_increment available from MariaDB 10.3

1.2.8.3.14 LAST_VALUE
Syntax
LAST_VALUE(expr,[expr,...])

LAST_VALUE(expr) OVER (
[ PARTITION BY partition_expression ]
[ ORDER BY order_list ]
)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
LAST_VALUE() evaluates all expressions and returns the last.
This is useful together with setting user variables to a value with @var:=expr, 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.
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:

1101/3812
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 f_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 f_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 f_1f2f
FROM t1;

+------+------+------+--------+--------+--------+--------+--------+--------+
| i | f_1f | l_1f | f_1p1f | f_1p1f | f_2p1p | f_2p1p | f_1f2f | f_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

1102/3812
1.2.8.3.15 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 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
SELECT

1.2.8.3.16 ROWNUM
MariaDB starting with 10.6.1
From MariaDB 10.6.1, the ROWNUM() function is supported.

Contents
1. Syntax
2. Description
3. Examples
4. Optimizations
5. Other Changes Related to ROWNUM
6. Other Considerations
7. See Also

Syntax
ROWNUM()

In Oracle mode 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 . For MariaDB native applications, we recommend the usage of LIMIT, 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
1103/3812
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
INSERT
UPDATE
DELETE
LOAD DATA INFILE
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 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
1104/3812
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 will use their own context, not the caller's context.

See Also
MDEV-24089 support oracle syntax: rownum
LIMIT clause

1.2.8.3.17 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 mysql client displays and the value from the mysql_affected_rows() C API function.
Generally:
For statements which return a result set (such as SELECT, SHOW, DESC or HELP), returns -1, even when the
result set is empty. This is also true for administrative statements, such as OPTIMIZE.
For DML statements other than SELECT and for ALTER TABLE, returns the number of affected rows.
For DDL statements (including TRUNCATE) and for other statements which don't return any result set (such as
USE, DO, SIGNAL or DEALLOCATE PREPARE ), returns 0.
For UPDATE, affected rows is by default the number of rows that were actually changed. If the
CLIENT_FOUND_ROWS flag to mysql_real_connect() is specified when connecting to mysqld, affected rows is
instead the number of rows matched by the WHERE clause.
For REPLACE, 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, 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 , because the row count for allocate prepare is always 0.
Warning: When used after a CALL 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, 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 .
Statements using the ROW_COUNT() function are not safe for replication.

Examples

1105/3812
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()

1.2.8.3.18 SCHEMA
Syntax
SCHEMA()

Description
This function is a synonym for DATABASE().

1.2.8.3.19 SESSION_USER
Syntax
SESSION_USER()

Description
SESSION_USER() is a synonym for USER().

1.2.8.3.20 SYSTEM_USER
1106/3812
Syntax
SYSTEM_USER()

Description
SYSTEM_USER() is a synonym for USER().

1.2.8.3.21 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.
Note that the value of USER() may differ from the value of CURRENT_USER(), which is the user used to authenticate
the current client. CURRENT_ROLE() 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.

Examples
shell> mysql --user="anonymous"

SELECT USER(),CURRENT_USER();
+---------------------+----------------+
| USER() | CURRENT_USER() |
+---------------------+----------------+
| anonymous@localhost | @localhost |
+---------------------+----------------+

To select only the IP address, use SUBSTRING_INDEX(),

SELECT SUBSTRING_INDEX(USER(), '@', -1);


+----------------------------------+
| SUBSTRING_INDEX(USER(), '@', -1) |
+----------------------------------+
| 192.168.0.101 |
+----------------------------------+

See Also
CURRENT_USER()

1.2.8.3.22 VERSION
Syntax
VERSION()

Description
Returns a string that indicates the MariaDB server version. The string uses the utf8 character set.

Examples
1107/3812
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 (libmysqld).
-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 .
From MariaDB 10.2, one can fool these applications by setting the version string from the command line or the my.cnf
files with --version=....

1.2.8.4 Miscellaneous Functions


Miscellaneous functions include DEFAULT, GET_LOCK, SLEEP, UUID, etc.
GET_LOCK
Obtain LOCK.

INET6_ATON
Given an IPv6 or IPv4 network address, returns a VARBINARY numeric value.

INET6_NTOA
Given an IPv6 or IPv4 network address, returns the address as a nonbinary string.

INET_ATON
Returns numeric value of IPv4 address.

INET_NTOA
Returns dotted-quad representation of IPv4 address.

IS_FREE_LOCK
Checks whether lock is free to use.

IS_IPV4
Whether or not an expression is a valid IPv4 address.

IS_IPV4_COMPAT
Whether or not an IPv6 address is IPv4-compatible.

IS_IPV4_MAPPED
Whether an IPv6 address is a valid IPv4-mapped address.

IS_IPV6
Whether or not an expression is a valid IPv6 address.

IS_USED_LOCK
Check if lock is in use.

MASTER_GTID_WAIT
Wait until slave reaches the GTID position.

MASTER_POS_WAIT
Blocks until the replica has applied all specified updates.

1108/3812
NAME_CONST
Returns the given value.

RELEASE_ALL_LOCKS
2 Releases all named locks held by the current session.

RELEASE_LOCK
Releases lock obtained with GET_LOCK().

SLEEP
Pauses for the given number of seconds.

SYS_GUID
Returns a globally unique identifier (GUID).

UUID
2 Returns a Universal Unique Identifier.

UUID_SHORT
Return short universal identifier.

VALUES / VALUE
4 Refer to columns in INSERT ... ON DUPLICATE KEY UPDATE.

There are 1 related questions .

1.2.8.4.1 GET_LOCK
Syntax
GET_LOCK(str,timeout)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 mysqladmin kill).
A lock is released with RELEASE_LOCK(), 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 function returns whether a specified lock a free or not, and the IS_USED_LOCK 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. From MariaDB 10.2.2 , timeout supports microseconds. Before then, it was rounded to the
closest integer.
If the metadata_lock_info plugin is installed, locks acquired with this function are visible in the Information Schema
METADATA_LOCK_INFO 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
1109/3812
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.
The patch to permit multiple locks was contributed by Konstantin "Kostja" Osipov (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 plugin:

1110/3812
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:
1111/3812
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
IS_FREE_LOCK
IS_USED_LOCK
RELEASE_ALL_LOCKS

1.2.8.4.2 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) or VARBINARY(4) for IPv6 and IPv4 addresses respectively.
Returns NULL if the argument is not understood.

MariaDB starting with 10.5.0


From MariaDB 10.5.0, INET6_ATON can take INET6 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
1112/3812
INET6_NTOA()
INET_ATON()
INET6 Data Type

1.2.8.4.3 INET6_NTOA
Contents
1. Syntax
2. Description
3. Examples
4. See Also

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()
INET_NTOA()

1.2.8.4.4 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

1113/3812
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()
INET_NTOA()

1.2.8.4.5 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()
INET_ATON()

1.2.8.4.6 IS_FREE_LOCK
Syntax
IS_FREE_LOCK(str)

Contents
1. Syntax
2. Description
3. See Also

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 plugin is installed, the Information Schema metadata_lock_info table contains information
about locks of this kind (as well as metadata locks).
Statements using the IS_FREE_LOCK function are not safe for statement-based replication.
1114/3812
See Also
GET_LOCK
RELEASE_LOCK
IS_USED_LOCK
RELEASE_ALL_LOCKS

1.2.8.4.7 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(), but as strict as INET6_ATON(), 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 |
+--------------------------------------+

1.2.8.4.8 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(), is IPv4-compatible,
otherwise returns 0.

MariaDB starting with 10.5.0


From MariaDB 10.5.0, when the argument is not INET6, automatic implicit CAST 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, the function understood only binary(16) representation.

Examples

1115/3812
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 |
+-----------------------------------------------------------+

1.2.8.4.9 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(), is a valid IPv4-mapped
address, otherwise returns 0.

MariaDB starting with 10.5.0


From MariaDB 10.5.0, when the argument is not INET6, automatic implicit CAST 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, 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 |
+-----------------------------------------------+

1.2.8.4.10 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

1116/3812
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 data type
INET6_ATON
INET6_NTOA

1.2.8.4.11 IS_USED_LOCK
Syntax
IS_USED_LOCK(str)

Contents
1. Syntax
2. Description
3. See Also

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 plugin is installed, the Information Schema metadata_lock_info table contains information
about locks of this kind (as well as metadata locks).
Statements using the IS_USED_LOCK function are not safe for statement-based replication.

See Also
GET_LOCK
RELEASE_LOCK
IS_FREE_LOCK
RELEASE_ALL_LOCKS

1.2.8.4.12 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 (similar to the value of, for
example, gtid_binlog_pos). It waits until the value of 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.

1117/3812
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, 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 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 session variable. This is
useful in a read-scaleout replication 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 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). 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() works only against a specific connection. This also means that while
MASTER_POS_WAIT() aborts if its master connection is terminated with STOP SLAVE 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 is recommended, as this will
prevent any such out-of-order sequence numbers from ever being replicated on a slave.

1.2.8.4.13 MASTER_POS_WAIT
Syntax
MASTER_POS_WAIT(log_name,log_pos[,timeout,["connection_name"]])

Description
This function is useful in replication 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. If you don't specify it, it's set to the value of
the default_master_connection system variable.
Statements using the MASTER_POS_WAIT() function are not safe for replication.

1118/3812
1.2.8.4.14 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 |
+--------+

1.2.8.4.15 RELEASE_ALL_LOCKS
MariaDB until 10.5.2
RELEASE_ALL_LOCKS was added in MariaDB 10.5.2.

Syntax
RELEASE_ALL_LOCKS()

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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.

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 |
+---------------------+

1119/3812
See Also
GET_LOCK
IS_FREE_LOCK
IS_USED_LOCK
RELEASE_LOCK

1.2.8.4.16 RELEASE_LOCK
Syntax
RELEASE_LOCK(str)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Releases the lock named by the string str that was obtained with GET_LOCK(). 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.
The DO statement 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 , it is possible to hold the same lock recursively. This example is viewed using the
metadata_lock_info plugin:

1120/3812
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
IS_FREE_LOCK
IS_USED_LOCK
RELEASE_ALL_LOCKS

1.2.8.4.17 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.

Example

1121/3812
SELECT SLEEP(5.5);
+------------+
| SLEEP(5.5) |
+------------+
| 0 |
+------------+
1 row in set (5.50 sec)

1.2.8.4.18 SYS_GUID
MariaDB starting with 10.6.1
The SYS_GUID function was introduced in MariaDB 10.6.1 to enhance Oracle compatibility. Similar functionality can
be achieved with the UUID function.

Syntax
SYS_GUID()

Description
Returns a 16-byte globally unique identifier (GUID), similar to the UUID function, but without the - character.

Example
SELECT SYS_GUID();
+----------------------------------+
| SYS_GUID() |
+----------------------------------+
| 2C574E45BA2811EBB265F859713E4BE4 |
+----------------------------------+

See Also
UUID
UUID_SHORT
UUID data type

1.2.8.4.19 UUID
Syntax
UUID()

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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.

1122/3812
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.
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 ).

Examples
SELECT UUID();
+--------------------------------------+
| UUID() |
+--------------------------------------+
| cd41294a-afb0-11df-bc9b-00241dd75637 |
+--------------------------------------+

See Also
UUID_SHORT() - Return short (64 bit) Universal Unique Identifier
SYS_GUID - UUID without the - character for Oracle compatibility
UUID data type

1.2.8.4.20 UUID_SHORT
Syntax
UUID_SHORT()

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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() 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.

Examples
1123/3812
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() ; Return full (128 bit) Universally Unique Identifier
AUTO_INCREMENT
Sequences - an alternative to auto_increment available from MariaDB 10.3
SYS_GUID - UUID without the - character for Oracle compatibility
UUID data type

1.2.8.4.21 VALUES / VALUE


Syntax
MariaDB starting with 10.3.3

VALUE(col_name)

MariaDB until 10.3.2

VALUES(col_name)

Description
In an INSERT ... ON DUPLICATE KEY UPDATE statement, you can use the VALUES(col_name) function in the
UPDATE clause to refer to column values from the INSERT 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 this function was renamed to VALUE() , because it's incompatible with the standard Table Value
Constructors syntax, implemented in MariaDB 10.3.3.
The VALUES() function can still be used even from MariaDB 10.3.3, but only in INSERT ... ON DUPLICATE KEY UPDATE
statements; it's a syntax error otherwise.

Examples
MariaDB starting with 10.3.3

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

1124/3812
INSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

1.2.9 Special Functions


There are many commonly used built-in functions. These are lesser used function for specific needs.
Dynamic Columns Functions
Functions for storing key/value pairs of data within a column.

Galera Functions
Built-in functions related to Galera.

Geographic Functions
Geographic, as well as geometric functions.

JSON Functions
Built-in functions related to JSON.

SEQUENCE Functions
Functions that can be used on SEQUENCEs.

Spider Functions
User-defined functions available with the Spider storage engine.

Window Functions
Window functions for performing calculations on a set of rows related to the current row.

1.2.9.1 Dynamic Columns Functions


1.2.9.2 Galera Functions
The following functions are for use with Galera.
WSREP_LAST_SEEN_GTID
Returns the Global Transaction ID of the most recent write transaction observed by the client.

WSREP_LAST_WRITTEN_GTID
Returns the Global Transaction ID of the most recent write transaction performed by the client.

WSREP_SYNC_WAIT_UPTO_GTID
Blocks the client until the transaction specified by the given GTID is applied and committed.

1.2.9.2.1 WSREP_LAST_SEEN_GTID
MariaDB starting with 10.4.2
WSREP_LAST_SEEN_GTID was added as part of Galera 4 in MariaDB 10.4.2.

Syntax
WSREP_LAST_SEEN_GTID()

Description
Returns the Global Transaction ID 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 for waiting and
unblocking purposes.

1125/3812
1.2.9.2.2 WSREP_LAST_WRITTEN_GTID
MariaDB starting with 10.4.2
WSREP_LAST_WRITTEN_GTID was added as part of Galera 4 in MariaDB 10.4.2.

Syntax
WSREP_LAST_WRITTEN_GTID()

Description
Returns the Global Transaction ID of the most recent write transaction performed by the client.

1.2.9.2.3 WSREP_SYNC_WAIT_UPTO_GTID
MariaDB starting with 10.4.2
WSREP_SYNC_WAIT_UPTO_GTID was added as part of Galera 4 in MariaDB 10.4.2.

Syntax
WSREP_SYNC_WAIT_UPTO_GTID(gtid[,timeout])

Description
Blocks the client until the transaction specified by the given Global Transaction ID 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 can be useful to determine the transaction to provide to
WSREP_SYNC_WAIT_UPTO_GTID for waiting and unblocking purposes.

1.2.9.3 Geographic Functions


Geographic and geometry functions. See Geographic Features for a full discussion of MariaDB's spatial extensions.
Geometry Constructors
Geometry constructors

Geometry Properties
Geometry properties

Geometry Relations
Geometry relations

LineString Properties
LineString properties

MBR (Minimum Bounding Rectangle)

Point Properties
Point properties

Polygon Properties
Polygon properties

1126/3812
WKB
Well-Known Binary format for geometric data

WKT
Well-Known Text geometry representation

There are 2 related questions .

1.2.9.3.1 Geometry Constructors


Geometry constructors
BUFFER
Synonym for ST_BUFFER.

CONVEXHULL
Synonym for ST_CONVEXHULL.

GEOMETRYCOLLECTION
Constructs a WKB GeometryCollection.

LINESTRING
Constructs a WKB LineString value from a number of WKB Point arguments.

MULTILINESTRING
Constructs a MultiLineString value.

MULTIPOINT
Constructs a WKB MultiPoint value.

MULTIPOLYGON
Constructs a WKB MultiPolygon.

POINT
Constructs a WKB Point.

PointOnSurface
Synonym for ST_PointOnSurface.

POLYGON
Constructs a WKB Polygon value from a number of WKB LineString arguments.

ST_BUFFER
A new geometry with a buffer added to the original geometry.

ST_CONVEXHULL
The minimum convex geometry enclosing all geometries within the set.

ST_INTERSECTION
The intersection, or shared portion, of two geometries.

ST_POINTONSURFACE
2 Returns a POINT guaranteed to intersect a surface.

ST_SYMDIFFERENCE
Portions of two geometries that don't intersect.

ST_UNION
Union of two geometries.

1.2.9.3.1.1 BUFFER
A synonym for ST_BUFFER.

1127/3812
1.2.9.3.1.2 CONVEXHULL
A synonym for ST_CONVEXHULL.

1.2.9.3.1.3 GEOMETRYCOLLECTION
Syntax
GeometryCollection(g1,g2,...)

Description
Constructs a WKB 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'));

1.2.9.3.1.4 LINESTRING
Syntax
LineString(pt1,pt2,...)

Description
Constructs a WKB LineString value from a number of WKB Point arguments. If any argument is not a WKB Point, the
return value is NULL . If the number of Point 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)))));

1.2.9.3.1.5 MULTILINESTRING
Syntax
MultiLineString(ls1,ls2,...)

1128/3812
Description
Constructs a WKB MultiLineString value using WKB LineString 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))))));

1.2.9.3.1.6 MULTIPOINT
Syntax
MultiPoint(pt1,pt2,...)

Description
Constructs a WKB MultiPoint value using WKB Point 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)))));

1.2.9.3.1.7 MULTIPOLYGON
Syntax
MultiPolygon(poly1,poly2,...)

Description
Constructs a WKB MultiPolygon value from a set of WKB Polygon 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)))))));

1.2.9.3.1.8 POINT
1129/3812
Syntax
Point(x,y)

Description
Constructs a WKB 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)'))));

1.2.9.3.1.9 PointOnSurface
A synonym for ST_PointOnSurface.

1.2.9.3.1.10 POLYGON
Syntax
Polygon(ls1,ls2,...)

Description
Constructs a WKB Polygon value from a number of WKB LineString 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() 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 |
+------------------+

1.2.9.3.1.11 ST_BUFFER
1130/3812
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 |
+---------------------------------+

1.2.9.3.1.12 ST_CONVEXHULL
MariaDB starting with 10.1.2
ST_ConvexHull() was introduced in MariaDB 10.1.2

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) |
+------------------------------+

1131/3812
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)) |
+----------------------------------------+

1.2.9.3.1.13 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) |
+----------------------------------+

1.2.9.3.1.14 ST_POINTONSURFACE
MariaDB starting with 10.1.2
ST_POINTONSURFACE() was introduced in MariaDB 10.1.2

Syntax
ST_PointOnSurface(g)
PointOnSurface(g)

Description
Given a geometry, returns a POINT guaranteed to intersect a surface. However, see MDEV-7514 .
ST_PointOnSurface() and PointOnSurface() are synonyms.

1.2.9.3.1.15 ST_SYMDIFFERENCE
1132/3812
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) |
+-----------------------------------+

1.2.9.3.1.16 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)) |
+------------------------------------------------+

1133/3812
1.2.9.3.2 Geometry Properties
Geometry properties
BOUNDARY
Synonym for ST_BOUNDARY.

DIMENSION
Synonym for ST_DIMENSION.

ENVELOPE
Synonym for ST_ENVELOPE.

GeometryN
Synonym for ST_GeometryN.

GeometryType
Synonym for ST_GeometryType.

IsClosed
Synonym for ST_IsClosed.

IsEmpty
Synonym for ST_IsEmpty.

IsRing
Synonym for ST_IsRing.

IsSimple
Synonym for ST_IsSimple.

NumGeometries
Synonym for ST_NumGeometries.

SRID
Synonym for ST_SRID.

ST_BOUNDARY
Returns a geometry that is the closure of a combinatorial boundary.

ST_DIMENSION
Inherent dimension of a geometry value.

ST_ENVELOPE
Returns the Minimum Bounding Rectangle for a geometry value.

ST_GEOMETRYN
Returns the N-th geometry in a GeometryCollection.

ST_GEOMETRYTYPE
Returns name of the geometry type of which a given geometry instance is a member.

ST_ISCLOSED
2 Returns true if a given LINESTRING's start and end points are the same.

ST_ISEMPTY
Indicated validity of geometry value.

ST_IsRing
Returns true if a given LINESTRING is both ST_IsClosed and ST_IsSimple.

ST_IsSimple
Returns true if the given Geometry has no anomalous geometric points.

ST_NUMGEOMETRIES
Number of geometries in a GeometryCollection.

ST_RELATE
Returns true if two geometries are related
1134/3812
ST_SRID
Returns a Spatial Reference System ID.

1.2.9.3.2.1 BOUNDARY
A synonym for ST_BOUNDARY.

1.2.9.3.2.2 DIMENSION
A synonym for ST_DIMENSION.

1.2.9.3.2.3 ENVELOPE
A synonym for ST_ENVELOPE.

1.2.9.3.2.4 GeometryN
A synonym for ST_GeometryN.

1.2.9.3.2.5 GeometryType
A synonym for ST_GeometryType.

1.2.9.3.2.6 IsClosed
A synonym for ST_IsClosed.

1.2.9.3.2.7 IsEmpty
A synonym for ST_IsEmpty.

1.2.9.3.2.8 IsRing
A synonym for ST_IsRing.

1.2.9.3.2.9 IsSimple
A synonym for ST_IsSImple.

1.2.9.3.2.10 NumGeometries
A synonym for ST_NumGeometries.

1.2.9.3.2.11 SRID
A synonym for ST_SRID.

1.2.9.3.2.12 ST_BOUNDARY
MariaDB starting with 10.1.2
The ST_BOUNDARY function was introduced in MariaDB 10.1.2

Syntax
1135/3812
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) |
+--------------------------------------------------------------------------+

1.2.9.3.2.13 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 |
+------------------------------------------------+

1.2.9.3.2.14 ST_ENVELOPE
Syntax
ST_ENVELOPE(g)
ENVELOPE(g)

1136/3812
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)) |
+----------------------------------------------------------+

1.2.9.3.2.15 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) |
+----------------------------------------+

1.2.9.3.2.16 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

1137/3812
SELECT GeometryType(GeomFromText('POINT(1 1)'));
+------------------------------------------+
| GeometryType(GeomFromText('POINT(1 1)')) |
+------------------------------------------+
| POINT |
+------------------------------------------+

1.2.9.3.2.17 ST_ISCLOSED
Syntax
ST_IsClosed(g)
IsClosed(g)

Description
Returns 1 if a given LINESTRING's start and end points are the same, or 0 if they are not the same. Before MariaDB
10.1.5 , returns NULL if not given a LINESTRING. After MariaDB 10.1.5 , 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 |
+--------------------------------+

1.2.9.3.2.18 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.

1.2.9.3.2.19 ST_IsRing
MariaDB starting with 10.1.2
The ST_IsRing function was introduced in MariaDB 10.1.2

Syntax
1138/3812
ST_IsRing(g)
IsRing(g)

Description
Returns true if a given LINESTRING is a ring, that is, both ST_IsClosed and ST_IsSimple. A simple curve does not pass
through the same point more than once. However, see MDEV-7510 .
St_IsRing() and IsRing() are synonyms.

1.2.9.3.2.20 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 |
+-------------------------------+

1.2.9.3.2.21 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 |
+----------------------------------+

1.2.9.3.2.22 ST_RELATE
1139/3812
MariaDB starting with 10.1.2
The ST_RELATE() function was introduced in MariaDB 10.1.2

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 .

1.2.9.3.2.23 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 |
+-----------------------------------------------+

1.2.9.3.3 Geometry Relations


Geometry relations
CONTAINS
Whether one geometry contains another.

CROSSES
Whether two geometries spatially cross

DISJOINT
Whether the two elements do not intersect.

EQUALS
Indicates whether two geometries are spatially equal.

INTERSECTS
Indicates whether two geometries spatially intersect.

OVERLAPS
Indicates whether two elements spatially overlap.

ST_CONTAINS
Whether one geometry is contained by another.

1140/3812
ST_CROSSES
Whether two geometries spatially cross.

ST_DIFFERENCE
Point set difference.

ST_DISJOINT
Whether one geometry is spatially disjoint from another.

ST_DISTANCE
The distance between two geometries.

ST_DISTANCE_SPHERE
Spherical distance between two geometries (point or multipoint) on a sphere.

ST_EQUALS
Whether two geometries are spatoially equal.

ST_INTERSECTS
Whether two geometries spatially intersect.

ST_LENGTH
Length of a LineString value.

ST_OVERLAPS
Whether two geometries overlap.

ST_TOUCHES
Whether one geometry g1 spatially touches another.

ST_WITHIN
Whether one geometry is within another.

TOUCHES
Whether two geometries spatially touch.

WITHIN
Indicate whether a geographic element is spacially within another.

1.2.9.3.3.1 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() uses object shapes.
This tests the opposite relationship to Within().

1.2.9.3.3.2 CROSSES
Syntax
Crosses(g1,g2)

Description
Returns 1 if g1 spatially crosses g2 . Returns NULL if g1 is a Polygon or a MultiPolygon, or if g2 is a Point or a
MultiPoint. Otherwise, returns 0 .
1141/3812
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() uses object shapes.

1.2.9.3.3.3 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().
DISJOINT() is based on the original MySQL implementation and uses object bounding rectangles, while
ST_DISJOINT() uses object shapes.

1.2.9.3.3.4 EQUALS
Syntax
Equals(g1,g2)

From MariaDB 10.2.3 :

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()
uses object shapes.
From MariaDB 10.2.3 , MBREQUALS is a synonym for Equals .

1.2.9.3.3.5 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() uses object shapes.
INTERSECTS() tests the opposite relationship to DISJOINT().

1.2.9.3.3.6 OVERLAPS
Syntax
1142/3812
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() uses object shapes.

1.2.9.3.3.7 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(), based on the original MySQL implementation, uses object
bounding rectangles.
ST_CONTAINS tests the opposite relationship to ST_WITHIN().

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 |
+----------------------+

1.2.9.3.3.8 ST_CROSSES
Syntax
ST_CROSSES(g1,g2)

Description
Returns 1 if geometry g1 spatially crosses geometry g2 . Returns NULL if g1 is a Polygon or a MultiPolygon, or if
g2 is a Point or a MultiPoint. 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
1143/3812
ST_CROSSES() uses object shapes, while CROSSES(), 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 |
+---------------------+

1.2.9.3.3.9 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) |
+------------------------------------+

1.2.9.3.3.10 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(), based on the original MySQL implementation, uses object
bounding rectangles.
ST_DISJOINT() tests the opposite relationship to ST_INTERSECTS().

Examples
1144/3812
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 |
+----------------------+

1.2.9.3.3.11 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 |
+------------------------------------+

1.2.9.3.3.12 ST_DISTANCE_SPHERE
MariaDB starting with 10.2.38
ST_DISTANCE_SPHERE was introduced in MariaDB 10.2.38 , MariaDB 10.3.29, MariaDB 10.4.19 and MariaDB
10.5.10.

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

1145/3812
1.2.9.3.3.13 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(), 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 |
+--------------------+

1.2.9.3.3.14 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(), based on the original MySQL implementation, uses
object bounding rectangles.
ST_INTERSECTS() tests the opposite relationship to ST_DISJOINT().

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 |
+------------------------+

1146/3812
SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 0, 0 2)');

SELECT ST_INTERSECTS(@g1,@g2);
+------------------------+
| ST_INTERSECTS(@g1,@g2) |
+------------------------+
| 0 |
+------------------------+

1.2.9.3.3.15 ST_LENGTH
Syntax
ST_LENGTH(ls)

Description
Returns as a double-precision number the length of the LineString 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 |
+---------------------------------+

1.2.9.3.3.16 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(), based on the original MySQL implementation, uses object
bounding rectangles.

1.2.9.3.3.17 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(), based on the original MySQL implementation, uses object
bounding rectangles.
1147/3812
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 |
+---------------------+

1.2.9.3.3.18 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_WITHIN() uses object shapes, while WITHIN(), 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 |
+--------------------+

1.2.9.3.3.19 TOUCHES
Syntax
Touches(g1,g2)

1148/3812
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() uses object shapes.

1.2.9.3.3.20 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() .
WITHIN() is based on the original MySQL implementation, and uses object bounding rectangles, while ST_WITHIN()
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 |
+-----------------+

1.2.9.3.4 LineString Properties


LineString properties
ENDPOINT
Synonym for ST_ENDPOINT.

GLENGTH
Length of a LineString value.

NumPoints
Synonym for ST_NumPoints.

PointN
Synonym for PointN.

STARTPOINT
Synonym for ST_StartPoint.

ST_ENDPOINT
Returns the endpoint of a LineString.

ST_NUMPOINTS
Returns the number of Point objects in a LineString.

1149/3812
ST_POINTN
Returns the N-th Point in the LineString.

ST_STARTPOINT
Returns the start point of a LineString

1.2.9.3.4.1 ENDPOINT
A synonym for ST_ENDPOINT.

1.2.9.3.4.2 GLENGTH
Syntax
GLength(ls)

Description
Returns as a double-precision number the length of the LineString 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() is the OpenGIS equivalent.

1.2.9.3.4.3 NumPoints
A synonym for ST_NumPoints.

1.2.9.3.4.4 PointN
A synonym for ST_PointN.

1.2.9.3.4.5 STARTPOINT
A synonym for ST_STARTPOINT.

1.2.9.3.4.6 ST_ENDPOINT
Syntax
ST_EndPoint(ls)
EndPoint(ls)

Description
Returns the Point that is the endpoint of the LineString value ls .
ST_EndPoint() and EndPoint() are synonyms.
1150/3812
Examples
SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(EndPoint(GeomFromText(@ls)));
+-------------------------------------+
| AsText(EndPoint(GeomFromText(@ls))) |
+-------------------------------------+
| POINT(3 3) |
+-------------------------------------+

1.2.9.3.4.7 ST_NUMPOINTS
Syntax
ST_NumPoints(ls)
NumPoints(ls)

Description
Returns the number of Point objects in the LineString 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 |
+------------------------------+

1.2.9.3.4.8 ST_POINTN
Syntax
ST_PointN(ls,N)
PointN(ls,N)

Description
Returns the N-th Point in the LineString 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) |
+-------------------------------------+

1.2.9.3.4.9 ST_STARTPOINT
1151/3812
Syntax
ST_StartPoint(ls)
StartPoint(ls)

Description
Returns the Point that is the start point of the LineString 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) |
+---------------------------------------+

1.2.9.3.5 MBR (Minimum Bounding Rectangle)


MBR Definition
Minimum Bounding Rectangle.

MBRContains
Indicates one Minimum Bounding Rectangle contains another.

MBRDisjoint
Indicates whether the Minimum Bounding Rectangles of two geometries are disjoint.

MBREqual
Whether the Minimum Bounding Rectangles of two geometries are the same.

MBRIntersects
Indicates whether the Minimum Bounding Rectangles of the two geometries intersect.

MBROverlaps
Whether the Minimum Bounding Rectangles of two geometries overlap.

MBRTouches
Whether the Minimum Bounding Rectangles of two geometries touch.

MBRWithin
Indicates whether one Minimum Bounding Rectangle is within another

1.2.9.3.5.1 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))

1.2.9.3.5.2 MBRContains
1152/3812
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().

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 |
+----------------------+----------------------+

1.2.9.3.5.3 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 |
+----------------------+

1.2.9.3.5.4 MBREqual
Syntax
MBREqual(g1,g2)

Description
1153/3812
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 |
+-------------------+

1.2.9.3.5.5 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 |
+------------------------+

1.2.9.3.5.6 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.

1154/3812
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 |
+----------------------+

1.2.9.3.5.7 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 |
+---------------------+

1155/3812
1.2.9.3.5.8 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().

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 |
+--------------------+--------------------+

1.2.9.3.6 Point Properties


Point properties
ST_X
1 X-coordinate value for a point.

ST_Y
1 Y-coordinate for a point.

X
Synonym for ST_X.

Y
Synonym for ST_Y.

1.2.9.3.6.1 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 |
+----------------------+

1156/3812
1.2.9.3.6.2 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 |
+----------------------+

1.2.9.3.6.3 X
A synonym for ST_X.

1.2.9.3.6.4 Y
A synonym for ST_Y.

1.2.9.3.7 Polygon Properties


Polygon properties
AREA
Synonym for ST_AREA.

CENTROID
Synonym for ST_CENTROID.

ExteriorRing
Synonym for ST_ExteriorRing.

InteriorRingN
Synonym for ST_InteriorRingN.

NumInteriorRings
Synonym for NumInteriorRings.

ST_AREA
Area of a Polygon.

ST_CENTROID
The mathematical centroid (geometric center) for a MultiPolygon.

ST_ExteriorRing
Returns the exterior ring of a Polygon as a LineString.

ST_InteriorRingN
Returns the N-th interior ring for a Polygon.

1157/3812
ST_NumInteriorRings
Number of interior rings in a Polygon.

1.2.9.3.7.1 AREA
A synonym for ST_AREA.

1.2.9.3.7.2 CENTROID
A synonym for ST_CENTROID.

1.2.9.3.7.3 ExteriorRing
A synonym for ST_ExteriorRing.

1.2.9.3.7.4 InteriorRingN
A synonym for ST_InteriorRingN.

1.2.9.3.7.5 NumInteriorRings
A synonym for ST_NumInteriorRings.

1.2.9.3.7.6 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 |
+---------------------------+

1.2.9.3.7.7 ST_CENTROID
Syntax
ST_Centroid(mpoly)
Centroid(mpoly)

Description
Returns a point reflecting the mathematical centroid (geometric center) for the MultiPolygon mpoly. The resulting point

1158/3812
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) |
+--------------+

1.2.9.3.7.8 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) |
+-------------------------------------------+

1.2.9.3.7.9 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) |
+----------------------------------------------+

1159/3812
1.2.9.3.7.10 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 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 |
+------------------+

1.2.9.3.8 WKB
WKB stands for Well-Known Binary, a standard representation for geometric values.
Well-Known Binary (WKB) Format
Well-Known Binary format for representing geometric data.

AsBinary
Synonym for ST_AsBinary.

AsWKB
Synonym for ST_AsBinary.

MLineFromWKB
Constructs a MULTILINESTRING.

MPointFromWKB
Constructs a MULTIPOINT value using its WKB representation and SRID.

MPolyFromWKB
Constructs a MULTIPOLYGON value using its WKB representation and SRID.

GeomCollFromWKB
Synonym for ST_GeomCollFromWKB.

GeometryCollectionFromWKB
Synonym for ST_GeomCollFromWKB.

1160/3812
GeometryFromWKB
Synonym for ST_GeomFromWKB.

GeomFromWKB
Synonym for ST_GeomFromWKB.

LineFromWKB
Synonym for ST_LineFromWKB.

LineStringFromWKB
Synonym for ST_LineFromWKB.

MultiLineStringFromWKB
A synonym for MLineFromWKB.

MultiPointFromWKB
Synonym for MPointFromWKB.

MultiPolygonFromWKB
Synonym for MPolyFromWKB.

PointFromWKB
Synonym for PointFromWKB.

PolyFromWKB
Synonym for ST_PolyFromWKB.

PolygonFromWKB
Synonym for ST_PolyFromWKB.

ST_AsBinary
Converts a value to its WKB representation.

ST_AsWKB
Synonym for ST_AsBinary.

ST_GeomCollFromWKB
Constructs a GEOMETRYCOLLECTION value from a WKB.

ST_GeometryCollectionFromWKB
Synonym for ST_GeomCollFromWKB.

ST_GeometryFromWKB
Synonym for ST_GeomFromWKB.

ST_GeomFromWKB
Constructs a geometry value using its WKB representation and SRID.

ST_LineFromWKB
Constructs a LINESTRING using its WKB and SRID.

ST_LineStringFromWKB
Synonym for ST_LineFromWKB.

ST_PointFromWKB
Constructs POINT using its WKB and SRID.

ST_PolyFromWKB
Constructs POLYGON value using its WKB representation and SRID.

ST_PolygonFromWKB
Synonym for ST_PolyFromWKB.

1.2.9.3.8.1 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.
1161/3812
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


000000000140000000000000004010000000000000
It's a POINT
000000000140000000000000004010000000000000
The X co-ordinate is 2.0
000000000140000000000000004010000000000000
The Y-co-ordinate is 4.0
000000000140000000000000004010000000000000

1.2.9.3.8.2 AsBinary
A synonym for ST_AsBinary().

1.2.9.3.8.3 AsWKB
A synonym for ST_AsBinary().

1.2.9.3.8.4 MLineFromWKB
Syntax
MLineFromWKB(wkb[,srid])
MultiLineStringFromWKB(wkb[,srid])

Description
Constructs a MULTILINESTRING value using its WKB representation and SRID.
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)) |
+--------------------------------------------------------+

1.2.9.3.8.5 MPointFromWKB
Syntax
MPointFromWKB(wkb[,srid])
MultiPointFromWKB(wkb[,srid])

Description
Constructs a MULTIPOINT value using its WKB representation and SRID.
MPointFromWKB() and MultiPointFromWKB() are synonyms.

1162/3812
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) |
+-----------------------------------------------------+

1.2.9.3.8.6 MPolyFromWKB
Syntax
MPolyFromWKB(wkb[,srid])
MultiPolygonFromWKB(wkb[,srid])

Description
Constructs a MULTIPOLYGON value using its WKB representation and SRID.
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)))

1.2.9.3.8.7 GeomCollFromWKB
A synonym for ST_GeomCollFromWKB.

1.2.9.3.8.8 GeometryCollectionFromWKB
A synonym for ST_GeomCollFromWKB.

1.2.9.3.8.9 GeometryFromWKB
A synonym for ST_GeomFromWKB.

1.2.9.3.8.10 GeomFromWKB
A synonym for ST_GeomFromWKB.

1.2.9.3.8.11 LineFromWKB
A synonym for ST_LineFromWKB.

1.2.9.3.8.12 LineStringFromWKB
A synonym for ST_LineFromWKB.

1.2.9.3.8.13 MultiLineStringFromWKB
1163/3812
A synonym for MLineFromWKB().

1.2.9.3.8.14 MultiPointFromWKB
A synonym for MPointFromWKB.

1.2.9.3.8.15 MultiPolygonFromWKB
Synonym for MPolyFromWKB.

1.2.9.3.8.16 PointFromWKB
A synonym for ST_PointFromWKB.

1.2.9.3.8.17 PolyFromWKB
A synonym for ST_PolyFromWKB.

1.2.9.3.8.18 PolygonFromWKB
A synonym for ST_PolyFromWKB.

1.2.9.3.8.19 ST_AsBinary
Syntax
ST_AsBinary(g)
AsBinary(g)
ST_AsWKB(g)
AsWKB(g)

Description
Converts a value in internal geometry format to its WKB 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)) |
+--------------------------------------------+

1.2.9.3.8.20 ST_AsWKB
A synonym for ST_AsBinary().

1.2.9.3.8.21 ST_GeomCollFromWKB
Syntax

1164/3812
ST_GeomCollFromWKB(wkb[,srid])
ST_GeometryCollectionFromWKB(wkb[,srid])
GeomCollFromWKB(wkb[,srid])
GeometryCollectionFromWKB(wkb[,srid])

Description
Constructs a GEOMETRYCOLLECTION value using its WKB 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)) |
+----------------------------------------------------------------+

1.2.9.3.8.22 ST_GeometryCollectionFromWKB
A synonym for ST_GeomCollFromWKB.

1.2.9.3.8.23 ST_GeometryFromWKB
A synonym for ST_GeomFromWKB.

1.2.9.3.8.24 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 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) |
+-------------------------------+

1.2.9.3.8.25 ST_LineFromWKB
Syntax
1165/3812
ST_LineFromWKB(wkb[,srid])
LineFromWKB(wkb[,srid])
ST_LineStringFromWKB(wkb[,srid])
LineStringFromWKB(wkb[,srid])

Description
Constructs a LINESTRING value using its WKB 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) |
+---------------------+

1.2.9.3.8.26 ST_LineStringFromWKB
A synonym for ST_LineFromWKB.

1.2.9.3.8.27 ST_PointFromWKB
Syntax
ST_PointFromWKB(wkb[,srid])
PointFromWKB(wkb[,srid])

Description
Constructs a POINT value using its WKB representation and SRID.
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) |
+------------+

1.2.9.3.8.28 ST_PolyFromWKB
Syntax
ST_PolyFromWKB(wkb[,srid])
ST_PolygonFromWKB(wkb[,srid])
PolyFromWKB(wkb[,srid])
PolygonFromWKB(wkb[,srid])

Description
1166/3812
Constructs a POLYGON value using its WKB representation and SRID.
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)) |
+----------------------------------------+

1.2.9.3.8.29 ST_PolygonFromWKB
A synonym for ST_PolyFromWKB.

1.2.9.3.9 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.
WKT Definition
Well-Known Text for exchanging geometry data in ASCII form.

AsText
Synonym for ST_AsText.

AsWKT
Synonym for ST_AsText.

GeomCollFromText
Synonym for ST_GeomCollFromText.

GeometryCollectionFromText
Synonym for ST_GeomCollFromText.

GeometryFromText
Synonym for ST_GeomFromText.

GeomFromText
Synonym for ST_GeomFromText.

LineFromText
Synonym for ST_LineFromText.

LineStringFromText
Synonym for ST_LineFromText.

MLineFromText
Constructs MULTILINESTRING using its WKT representation and SRID.

MPointFromText
Constructs a MULTIPOINT value using its WKT and SRID.

MPolyFromText
Constructs a MULTIPOLYGON value.

MultiLineStringFromText
Synonym for MLineFromText.

MultiPointFromText
Synonym for MPointFromText.

1167/3812
MultiPolygonFromText
Synonym for MPolyFromText.

PointFromText
Synonym for ST_PointFromText.

PolyFromText
Synonym for ST_PolyFromText.

PolygonFromText
Synonym for ST_PolyFromText.

ST_AsText
Converts a value to its WKT-Definition.

ST_ASWKT
Synonym for ST_ASTEXT().

ST_GeomCollFromText
Constructs a GEOMETRYCOLLECTION value.

ST_GeometryCollectionFromText
Synonym for ST_GeomCollFromText.

ST_GeometryFromText
Synonym for ST_GeomFromText.

ST_GeomFromText
Constructs a geometry value using its WKT and SRID.

ST_LineFromText
Creates a linestring value.

ST_LineStringFromText
Synonym for ST_LineFromText.

ST_PointFromText
Constructs a POINT value.

ST_PolyFromText
Constructs a POLYGON value.

ST_PolygonFromText
Synonym for ST_PolyFromText.

1.2.9.3.9.1 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
LINESTRING
POLYGON
MULTIPOINT
MULTILINESTRING
MULTIPOLYGON
GEOMETRYCOLLECTION
GEOMETRY

1168/3812
See Also
Geometry Types

1.2.9.3.9.2 AsText
A synonym for ST_AsText().

1.2.9.3.9.3 AsWKT
A synonym for ST_AsText().

1.2.9.3.9.4 GeomCollFromText
A synonym for ST_GeomCollFromText.

1.2.9.3.9.5 GeometryCollectionFromText
A synonym for ST_GeomCollFromText.

1.2.9.3.9.6 GeometryFromText
A synonym for ST_GeomFromText.

1.2.9.3.9.7 GeomFromText
A synonym for ST_GeomFromText.

1.2.9.3.9.8 LineFromText
A synonym for ST_LineFromText.

1.2.9.3.9.9 LineStringFromText
A synonym for ST_LineFromText.

1.2.9.3.9.10 MLineFromText
Syntax
MLineFromText(wkt[,srid])
MultiLineStringFromText(wkt[,srid])

Description
Constructs a MULTILINESTRING value using its WKT representation and SRID.
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))))));

1169/3812
1.2.9.3.9.11 MPointFromText
Syntax
MPointFromText(wkt[,srid])
MultiPointFromText(wkt[,srid])

Description
Constructs a MULTIPOINT value using its WKT representation and SRID.
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)))));

1.2.9.3.9.12 MPolyFromText
Syntax
MPolyFromText(wkt[,srid])
MultiPolygonFromText(wkt[,srid])

Description
Constructs a MULTIPOLYGON value using its WKT representation and SRID.
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)))))));

1.2.9.3.9.13 MultiLineStringFromText
A synonym for MLineFromText.

1.2.9.3.9.14 MultiPointFromText
A synonym for MPointFromText.

1.2.9.3.9.15 MultiPolygonFromText
A synonym for MPolyFromText.

1170/3812
1.2.9.3.9.16 PointFromText
A synonym for ST_PointFromText.

1.2.9.3.9.17 PolyFromText
A synonym for ST_PolyFromText.

1.2.9.3.9.18 PolygonFromText
A synonym for ST_PolyFromText.

1.2.9.3.9.19 ST_AsText
Syntax
ST_AsText(g)
AsText(g)
ST_AsWKT(g)
AsWKT(g)

Description
Converts a value in internal geometry format to its WKT 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) |
+--------------------------------+

1.2.9.3.9.20 ST_ASWKT
A synonym for ST_ASTEXT().

1.2.9.3.9.21 ST_GeomCollFromText
Syntax
ST_GeomCollFromText(wkt[,srid])
ST_GeometryCollectionFromText(wkt[,srid])
GeomCollFromText(wkt[,srid])
GeometryCollectionFromText(wkt[,srid])

Description
Constructs a GEOMETRYCOLLECTION value using its WKT representation and SRID.
ST_GeomCollFromText() , ST_GeometryCollectionFromText() , GeomCollFromText() and
GeometryCollectionFromText() are all synonyms.

Example
1171/3812
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'));

1.2.9.3.9.22 ST_GeometryCollectionFromText
A synonym for ST_GeomCollFromText.

1.2.9.3.9.23 ST_GeometryFromText
A synonym for ST_GeomFromText.

1.2.9.3.9.24 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 representation and SRID.
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))');

1.2.9.3.9.25 ST_LineFromText
Syntax
ST_LineFromText(wkt[,srid])
ST_LineStringFromText(wkt[,srid])
LineFromText(wkt[,srid])
LineStringFromText(wkt[,srid])

Description
Constructs a LINESTRING value using its WKT representation and SRID.
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)))));

1172/3812
1.2.9.3.9.26 ST_LineStringFromText
A synonym for ST_LineFromText.

1.2.9.3.9.27 ST_PointFromText
Syntax
ST_PointFromText(wkt[,srid])
PointFromText(wkt[,srid])

Description
Constructs a POINT value using its WKT representation and SRID.
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)'))));

1.2.9.3.9.28 ST_PolyFromText
Syntax
ST_PolyFromText(wkt[,srid])
ST_PolygonFromText(wkt[,srid])
PolyFromText(wkt[,srid])
PolygonFromText(wkt[,srid])

Description
Constructs a POLYGON value using its WKT representation and SRID.
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))'));

1.2.9.3.9.29 ST_PolygonFromText
A synonym for ST_PolyFromText.

1.2.9.4 JSON Functions


Functions relating to JSON, such as JSON_VALUE, JSON_ARRAY etc.
Differences between JSON_QUERY and JSON_VALUE
2 Comparison between and examples with JSON_QUERY and JSON_VALUE.

1173/3812
JSONPath Expressions
MariaDB JSONPath description and definition.

JSON_ARRAY
Returns a JSON array containing the listed values.

JSON_ARRAYAGG
3 Returns a JSON array containing an element for each value in a given set of JSON or SQL values.

JSON_ARRAY_APPEND
Appends values to the end of the given arrays within a JSON document.

JSON_ARRAY_INSERT
Inserts a value into a JSON document.

JSON_COMPACT
Removes all unnecessary spaces so the json document is as short as possible.

JSON_CONTAINS
Whether a value is found in a given JSON document or at a specified path within the document.

JSON_CONTAINS_PATH
Indicates whether the given JSON document contains data at the specified path or paths.

JSON_DEPTH
Maximum depth of a JSON document.

JSON_DETAILED
Represents JSON in the most understandable way emphasizing nested structures.

JSON_EQUALS
Checks if there is equality between two json objects.

JSON_EXISTS
2 Determines whether a specified JSON value exists in the given data.

JSON_EXTRACT
8 Extracts data from a JSON document.

JSON_INSERT
2 Inserts data into a JSON document.

JSON_KEYS
2 Returns keys from top-level value of a JSON object or top-level keys from the path.

JSON_LENGTH
3 Returns the length of a JSON document, or the length of a value within the document.

JSON_LOOSE
Adds spaces to a JSON document to make it look more readable.

JSON_MERGE
Merges the given JSON documents.

JSON_MERGE_PATCH
RFC 7396-compliant merge of the given JSON documents.

JSON_MERGE_PRESERVE
Synonym for JSON_MERGE.

JSON_NORMALIZE
5 Recursively sorts keys and removes spaces, allowing comparison of json documents for equality.

JSON_OBJECT
Returns a JSON object containing the given key/value pairs.

JSON_OBJECTAGG
Returns a JSON object containing key-value pairs.
1174/3812
JSON_OVERLAPS
Returns true if two json documents have at least one key-value pair or array element in common.

JSON_QUERY
1 Given a JSON document, returns an object or array specified by the path.

JSON_QUOTE
Quotes a string as a JSON value.

JSON_REMOVE
2 Removes data from a JSON document.

JSON_REPLACE
Replaces existing values in a JSON document.

JSON_SEARCH
3 Returns the path to the given string within a JSON document.

JSON_SET
2 Updates or inserts data into a JSON document.

JSON_TABLE
3 Given data from a JSON document, returns a representation of it as a relational table.

JSON_TYPE
2 Returns the type of a JSON value.

JSON_UNQUOTE
Unquotes a JSON value, returning a string.

JSON_VALID
2 Whether a value is a valid JSON document or not.

JSON_VALUE
3 Given a JSON document, returns the specified scalar.

There are 5 related questions .

1.2.9.4.1 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.

1175/3812
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 |
+----------------------------+----------------------------+

1.2.9.4.2 JSONPath Expressions


Contents
1. JSON Path Syntax
1. Object Member Selector
2. Array Element Selector
3. Wildcard
2. Compatibility

A number of JSON functions 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.
1176/3812
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
1177/3812
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 differences between MariaDB and MySQL's JSONPath are: MySQL supports
[last] and [M to N] as array element selectors; MySQL doesn't allow one to specify the mode explicitly (but uses
lax mode implicitly).

1.2.9.4.3 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, the CONNECT storage engine function

1.2.9.4.4 JSON_ARRAYAGG
1.2.9.4.5 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.

1178/3812
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]} |
+------------------------------------+

1.2.9.4.6 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

1179/3812
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]] |
+------------------------------------------------+

1.2.9.4.7 JSON_COMPACT
Syntax
JSON_COMPACT(json_doc)

Contents
1. Syntax
2. Description
3. Example
4. See Also

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 covering JSON_COMPACT.

1.2.9.4.8 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

1180/3812
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 |
+-----------------------------------------+

1.2.9.4.9 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 |
+------------------------------------------------+

1181/3812
1.2.9.4.10 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 |
+---------------------------------------+

1.2.9.4.11 JSON_DETAILED
Syntax
JSON_DETAILED(json_doc[, tab_size])

Contents
1. Syntax
2. Description
3. Example
4. See Also

Description
Represents JSON in the most understandable way emphasizing nested structures.

Example

1182/3812
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 covering JSON_DETAILED.

1.2.9.4.12 JSON_EQUALS
MariaDB starting with 10.7.0
JSON_EQUALS was added in MariaDB 10.7.0

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

1183/3812
1.2.9.4.13 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 |
+----------------------------------------------------------------+

1.2.9.4.14 JSON_EXTRACT
Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 as supported by MariaDB

Examples

1184/3812
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 covering JSON_EXTRACT.

1.2.9.4.15 JSON_INSERT
Syntax
JSON_INSERT(json_doc, path, val[, path, val] ...)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
Inserts data into a JSON document, returning the resulting document or NULL if any argument is null.
An error will occur if the JSON document is not invalid, or if any of the paths are invalid or contain a * or ** wildcard.
JSON_INSERT can only insert data while JSON_REPLACE can only update. JSON_SET 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 covering JSON_INSERT.

1.2.9.4.16 JSON_KEYS
Syntax
1185/3812
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"] |
+-----------------------------------------------------+

1.2.9.4.17 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

1.2.9.4.18 JSON_LOOSE
Syntax
JSON_LOOSE(json_doc)

1186/3812
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]} |
+-----------------------+--------------------+

1.2.9.4.19 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 , MariaDB 10.3.16 and MariaDB 10.4.5.
JSON_MERGE_PATCH is an RFC 7396-compliant replacement, and JSON_MERGE_PRESERVE 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_PRESERVE

1.2.9.4.20 JSON_MERGE_PATCH
MariaDB starting with 10.2.25
JSON_MERGE_PATCH was introduced in MariaDB 10.2.25 , MariaDB 10.3.16 and MariaDB 10.4.5.

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.
1187/3812
JSON_MERGE_PATCH is an RFC 7396-compliant replacement for JSON_MERGE, 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] |
+---------------------------------+------------------------------------+

1.2.9.4.21 JSON_MERGE_PRESERVE
MariaDB starting with 10.2.25
JSON_MERGE_PRESERVE was introduced in MariaDB 10.2.25 , MariaDB 10.3.16 and MariaDB 10.4.5.

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 , MariaDB 10.3.16 and MariaDB 10.4.5 as a synonym for
JSON_MERGE, 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

1.2.9.4.22 JSON_NORMALIZE
MariaDB starting with 10.7.0
JSON_NORMALIZE was added in MariaDB 10.7.0.

Syntax
JSON_NORMALIZE(json)

Description
Recursively sorts keys and removes spaces, allowing comparison of json documents for equality.

Examples
1188/3812
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

1.2.9.4.23 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, the CONNECT storage engine function

1.2.9.4.24 JSON_OBJECTAGG
1.2.9.4.25 JSON_OVERLAPS
MariaDB starting with 10.9
JSON_OVERLAPS was added in MariaDB 10.9.

1189/3812
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 |
+----------------------+

1.2.9.4.26 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

1190/3812
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] |
+-------------------------------------------------------+

1.2.9.4.27 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\"" |
+-----------------+-----------------+-------------------+

1.2.9.4.28 JSON_REMOVE
Syntax
JSON_REMOVE(json_doc, path[, path] ...)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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.
An error will occur if JSON document is invalid, the path is invalid or if the path 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

1191/3812
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 covering JSON_REMOVE.

1.2.9.4.29 JSON_REPLACE
Syntax
JSON_REPLACE(json_doc, path, val[, path, val] ...)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 can only insert. JSON_SET 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 covering JSON_REPLACE.

1.2.9.4.30 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

1192/3812
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" |
+---------------------------------+

1.2.9.4.31 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 can only update, and JSON_INSERT only insert.

Examples
SELECT JSON_SET(Priv, '$.locked', 'true') FROM mysql.global_priv

1.2.9.4.32 JSON_TABLE
MariaDB starting with 10.6.0
JSON_TABLE was added in MariaDB 10.6.0.

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][, ...]

1193/3812
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

Contents
1. Syntax
2. Description
1. Column Definitions
1. Path Columns
2. ORDINALITY Columns
3. EXISTS PATH Columns
4. NESTED PATHs
2. ON EMPTY and ON ERROR Clauses
3. Replication
4. Extracting a Subdocument into a
Column
3. See Also

Description
JSON_TABLE can be used in contexts where a table reference can be used; in the FROM clause of a SELECT
statement, and in multi-table UPDATE/DELETE 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 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.

1194/3812
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
1195/3812
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.
1196/3812
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 field, or a varchar 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) 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.

Extracting a Subdocument into a Column


MariaDB starting with 10.6.9
Prior to MariaDB 10.6.9, 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:


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 (video)

1.2.9.4.33 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:

1197/3812
Return
type Value Example

[1, 2, {"key":
ARRAY JSON array
"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
JSON null literal (this is returned as a string, not to be confused with the SQL
NULL null
NULL value!)
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 |
+---------------------------------------+

1.2.9.4.34 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 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

1198/3812
SELECT JSON_UNQUOTE('"Monty"');
+-------------------------+
| JSON_UNQUOTE('"Monty"') |
+-------------------------+
| Monty |
+-------------------------+

With the default SQL Mode:

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 |
+-----------------------------+

1.2.9.4.35 JSON_VALID
Syntax
JSON_VALID(value)

Contents
1. Syntax
2. Description
3. Examples
4. See Also

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, the JSON_VALID function is automatically used as a CHECK constraint for the JSON data type
alias 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 covering JSON_VALID.

1199/3812
1.2.9.4.36 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 |
+-----------+------+

1.2.9.5 SEQUENCE Functions


1.2.9.6 Spider Functions
The following UDFs are available with the Spider Storage Engine.
SPIDER_BG_DIRECT_SQL
Background SQL execution

SPIDER_COPY_TABLES
Copy table data

SPIDER_DIRECT_SQL
Execute SQL on the remote server

SPIDER_FLUSH_TABLE_MON_CACHE
Refreshing Spider monitoring server information

1.2.9.6.1 SPIDER_BG_DIRECT_SQL
Syntax
SPIDER_BG_DIRECT_SQL('sql', 'tmp_table_list', 'parameters')

1200/3812
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 installed with the Spider 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

1.2.9.6.2 SPIDER_COPY_TABLES
Syntax
SPIDER_COPY_TABLES(spider_table_name,
source_link_id, destination_link_id_list [,parameters])

Description
A UDF installed with the Spider Storage Engine, 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.

1.2.9.6.3 SPIDER_DIRECT_SQL
Syntax
SPIDER_DIRECT_SQL('sql', 'tmp_table_list', 'parameters')

1201/3812
Description
A UDF installed with the Spider Storage Engine, 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

1.2.9.6.4
SPIDER_FLUSH_TABLE_MON_CACHE
Syntax
SPIDER_FLUSH_TABLE_MON_CACHE()

Description
A UDF installed with the Spider Storage Engine, 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 |
+--------------------------------+

1.2.9.7 Window Functions


MariaDB starting with 10.2
Window functions were first introduced in MariaDB 10.2.0 .

Window functions perform calculations across a set of rows related to the current row
Window Functions Overview
4 Window functions perform calculations across a set of rows related to the current row.

AVG
Returns the average value.

BIT_AND
Bitwise AND.

BIT_OR
Bitwise OR.

1202/3812
BIT_XOR
Bitwise XOR.

COUNT
Returns count of non-null values.

CUME_DIST
Window function that returns the cumulative distribution of a given row.

DENSE_RANK
Rank of a given row with identical values receiving the same result, no skipping.

FIRST_VALUE
1 Returns the first result from an ordered set.

JSON_ARRAYAGG
3 Returns a JSON array containing an element for each value in a given set of JSON or SQL values.

JSON_OBJECTAGG
Returns a JSON object containing key-value pairs.

LAG
1 Accesses data from a previous row in the same result set without the need for a self-join.

LAST_VALUE
Returns the last value in a list or set of values.

LEAD
2 Accesses data from a following row in the same result set without the need for a self-join.

MAX
Returns the maximum value.

MEDIAN
Window function that returns the median value of a range of values.

MIN
Returns the minimum value.

NTH_VALUE
Returns the value evaluated at the specified row number of the window frame.

NTILE
Returns an integer indicating which group a given row falls into.

PERCENT_RANK
Window function that returns the relative percent rank of a given row.

PERCENTILE_CONT
Continuous percentile.

PERCENTILE_DISC
Discrete percentile.

RANK
1 Rank of a given row with identical values receiving the same result.

ROW_NUMBER
Row number of a given row with identical values receiving a different result.

STD
Population standard deviation.

STDDEV
Population standard deviation.

STDDEV_POP
Returns the population standard deviation.
1203/3812
STDDEV_SAMP
1 Standard deviation.

SUM
Sum total.

VAR_POP
Population standard variance.

VAR_SAMP
Returns the sample variance.

VARIANCE
Population standard variance.

Aggregate Functions as Window Functions


1 It is possible to use aggregate functions as window functions.

ColumnStore Window Functions


Summary of window function use with the ColumnStore engine

Window Frames
1 Some window functions operate on window frames.

1.2.9.7.1 Window Functions Overview


Contents
1. Introduction
1. Syntax
2. Description
2. Scope
3. Links
4. Examples
5. See Also

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 in that they perform calculations across a set of
rows. However, unlike aggregate functions, the output is not grouped into a single row.
1204/3812
Non-aggregate window functions include
CUME_DIST
DENSE_RANK
FIRST_VALUE
LAG
LAST_VALUE
LEAD
MEDIAN
NTH_VALUE
NTILE
PERCENT_RANK
PERCENTILE_CONT
PERCENTILE_DISC
RANK, ROW_NUMBER
Aggregate functions that can also be used as window functions include
AVG
BIT_AND
BIT_OR
BIT_XOR
COUNT
MAX
MIN
STD
STDDEV
STDDEV_POP
STDDEV_SAMP
SUM
VAR_POP
VAR_SAMP
VARIANCE
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:

1205/3812
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 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 )
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 )
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, RANK, DENSE_RANK,
Window functions that can be streamed once the number of rows in partition is known: PERCENT_RANK,
CUME_DIST, NTILE
Aggregate functions that are currently supported as window functions are: COUNT, SUM, AVG, BIT_OR,
BIT_AND, BIT_XOR.
Aggregate functions with the DISTINCT specifier (e.g. COUNT( DISTINCT x) ) are not supported as window
functions.

Links
MDEV-6115 is the main jira task for window functions development. Other tasks are are attached as sub-tasks
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:

1206/3812
CREATE TABLE users (
email VARCHAR(30),
first_name VARCHAR(30),
last_name VARCHAR(30),
account_type VARCHAR(30)
);

INSERT INTO users VALUES


('[email protected]', 'Admin', 'Boss', 'admin'),
('[email protected]', 'Bob', 'Carlsen', 'regular'),
('[email protected]', 'Eddie', 'Stevens', 'regular'),
('[email protected]', 'John', 'Smith', 'regular'),
('[email protected]', '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 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 | [email protected] | Admin | Boss | admin |
| 2 | [email protected] | Bob | Carlsen | regular |
| 3 | [email protected] | Eddie | Stevens | regular |
| 4 | [email protected] | John | Smith | regular |
| 5 | [email protected] | 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 | [email protected] | Admin | Boss | admin |
| 2 | [email protected] | Root | Chief | admin |
| 1 | [email protected] | Bob | Carlsen | regular |
| 2 | [email protected] | Eddie | Stevens | regular |
| 3 | [email protected] | 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:

1207/3812
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 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:

1208/3812
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
Introduction to Window Functions in MariaDB Server 10.2

1.2.9.7.2 AVG
1.2.9.7.3 BIT_AND
1.2.9.7.4 BIT_OR
1.2.9.7.5 BIT_XOR
1.2.9.7.6 COUNT
1.2.9.7.7 CUME_DIST
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Syntax
CUME_DIST() OVER (
[ PARTITION BY partition_expression ]
[ ORDER BY order_list ]
)

Description
CUME_DIST() is a window function 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

1209/3812
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
1210/3812
PERCENT_RANK()

1.2.9.7.8 DENSE_RANK
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Syntax
DENSE_RANK() OVER (
[ PARTITION BY partition_expression ]
[ ORDER BY order_list ]
)

Description
DENSE_RANK() is a window function that displays the number of a given row, starting at one and following the ORDER
BY sequence of the window function, with identical values receiving the same result. Unlike the RANK() function, there
are no skipped values if the preceding results are identical. It is also similar to the ROW_NUMBER() function except
that in that function, identical values will receive a different row number for each result.

Examples
The distinction between DENSE_RANK(), RANK() 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()
ROW_NUMBER()
ORDER BY

1.2.9.7.9 FIRST_VALUE

1211/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

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 |
+----+-----------+----------+------------+-----------+

1212/3812
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 f_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 f_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 f_1f2f
FROM t1;

+------+------+------+--------+--------+--------+--------+--------+--------+
| i | f_1f | l_1f | f_1p1f | f_1p1f | f_2p1p | f_2p1p | f_1f2f | f_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

1.2.9.7.10 JSON_ARRAYAGG
1.2.9.7.11 JSON_OBJECTAGG
1.2.9.7.12 LAG
Contents
1. Syntax
2. Description
3. Examples
4. See Also

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

1213/3812
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 - Window function to access a following row

1.2.9.7.13 LAST_VALUE
1.2.9.7.14 LEAD
Contents
1. Syntax
2. Description
3. Example
4. See Also

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

1214/3812
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 - Window function to access a previous row

1.2.9.7.15 MAX
1.2.9.7.16 MEDIAN
MariaDB starting with 10.3.3
The MEDIAN() window function was first introduced with in MariaDB 10.3.3.

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Syntax
MEDIAN(median expression) OVER (
[ PARTITION BY partition_expression ]
)

Description
MEDIAN() is a window function that returns the median value of a range of values.
It is a specific case of PERCENTILE_CONT, with an argument of 0.5 and the ORDER BY column the one in MEDIAN 's
argument.

1215/3812
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

1.2.9.7.17 MIN
1.2.9.7.18 NTH_VALUE
Syntax
NTH_VALUE (expr[, num_row]) OVER (
[ PARTITION BY partition_expression ]
[ ORDER BY order_list ]
)

Contents
1. Syntax
2. Description

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.

1.2.9.7.19 NTILE
Contents
1. Syntax
2. Description
3. Examples

Syntax

1216/3812
NTILE (expr) OVER (
[ PARTITION BY partition_expression ]
[ ORDER BY order_list ]
)

Description
NTILE() is a window function 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 |
+----+------+------+-----------------------------+

1.2.9.7.20 PERCENT_RANK

1217/3812
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Syntax
PERCENT_RANK() OVER (
[ PARTITION BY partition_expression ]
[ ORDER BY order_list ]
)

Description
PERCENT_RANK() is a window function 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

1218/3812
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
1219/3812
CUME_DIST()

1220/3812
1.2.9.7.21 PERCENTILE_CONT
MariaDB starting with 10.3.3
The PERCENTILE_CONT() window function was first introduced with in MariaDB 10.3.3.

Contents
1. Syntax
2. Description
3. Examples
4. See Also

Syntax
Description
PERCENTILE_CONT() (standing for continuous percentile) is a window function 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 is a specific case of PERCENTILE_CONT , equivalent to PERCENTILE_CONT(0.5) .

Examples

1221/3812
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() - a special case of PERCENTILE_CONT equivalent to PERCENTILE_CONT(0.5)

1222/3812
1.2.9.7.22 PERCENTILE_DISC
MariaDB starting with 10.3.3
The PERCENTILE_DISC() window function was first introduced with in MariaDB 10.3.3.

Syntax
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Description
PERCENTILE_DISC() (standing for discrete percentile) is a window function 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() >= function_argument.

Examples

1223/3812
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()

1.2.9.7.23 RANK
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Syntax

1224/3812
RANK() OVER (
[ PARTITION BY partition_expression ]
[ ORDER BY order_list ]
)

Description
RANK() is a window function that displays the number of a given row, starting at one and following the ORDER BY
sequence of the window function, with identical values receiving the same result. It is similar to the ROW_NUMBER()
function except that in that function, identical values will receive a different row number for each result.

Examples
The distinction between DENSE_RANK(), RANK() 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
DENSE_RANK()
ROW_NUMBER()
ORDER BY

1.2.9.7.24 ROW_NUMBER
Contents
1. Syntax
2. Description
3. Examples
4. See Also

Syntax
ROW_NUMBER() OVER (
[ PARTITION BY partition_expression ]
[ ORDER BY order_list ]
)

Description
ROW_NUMBER() is a window function that displays the number of a given row, starting at one and following the
ORDER BY sequence of the window function, with identical values receiving different row numbers. It is similar to the
RANK() and DENSE_RANK() functions except that in that function, identical values will receive the same rank for each
1225/3812
result.

Examples
The distinction between DENSE_RANK(), RANK() 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()
DENSE_RANK()
ORDER BY

1.2.9.7.25 STD
1.2.9.7.26 STDDEV
1.2.9.7.27 STDDEV_POP
1.2.9.7.28 STDDEV_SAMP
1.2.9.7.29 SUM
1.2.9.7.30 VARIANCE
1.2.9.7.31 VAR_POP
1.2.9.7.32 VAR_SAMP
1.2.9.7.33 Aggregate Functions as Window
Functions
It is possible to use aggregate functions as window functions. An aggregate function used as a window function must
have the OVER clause. For example, here's COUNT() used as a window function:

select COUNT(*) over (order by column) from table;

1226/3812
MariaDB currently allows these aggregate functions to be used as window functions:
AVG
BIT_AND
BIT_OR
BIT_XOR
COUNT
JSON_ARRAYAGG
JSON_OBJECTAGG
MAX
MIN
STD
STDDEV
STDDEV_POP
STDDEV_SAMP
SUM
VAR_POP
VAR_SAMP
VARIANCE

1.2.9.7.34 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:
1227/3812
{ 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.
Calculates the cumulative distribution, or relative rank, of the current row to other rows in the
CUME_DIST()
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.
The value evaluated at the row that is the first row of the window frame (counting from 1);
FIRST_VALUE()
null if no such row.
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
LAG()
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.
The value evaluated at the row that is the last row of the window frame (counting from 1);
LAST_VALUE()
null if no such row.
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
LEAD()
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.
An inverse distribution function that assumes a continuous distribution model. It takes a
MEDIAN() 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.
The value evaluated at the row that is the nth row of the window frame (counting from 1); null
NTH_VALUE()
if no such row.
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
NTILE()
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).

1228/3812
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
PERCENTILE_CONT()
that percentile value with respect to the sort specification. Nulls are ignored in the
calculation.
An inverse distribution function that assumes a discrete distribution model. It takes a
PERCENTILE_DISC() 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() Computes the population standard deviation and returns the square root of the population
STDDEV_POP() variance.
Computes the cumulative sample standard deviation and returns the square root of the
STDDEV_SAMP()
sample variance.
SUM() Sum of expression across all input values.
VARIANCE()
Population variance of the input values (square of the population standard deviation).
VAR_POP()
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


2016-10-
1 Browseblab Multi-lateral executive function Bob 26444.86 Negotiating
20
2016-11-
2 Mita Organic demand-driven benchmark Maria 477878.41 ClosedWon
28
2017-01-
3 Miboo De-engineered hybrid groupware Olivier 80181.78 ClosedWon
05
2016-07-
4 Youbridge Enterprise-wide bottom-line Graphic Interface Chris 946245.29 ClosedWon
02
Reverse-engineered fresh-thinking 2017-02-
5 Skyba Maria 696241.82 Negotiating
standardization 17
Fundamental well-modulated artificial 2016-08-
6 Eayo Bob 765605.52 Prospecting
intelligence 27
2017-01-
7 Yotz Extended secondary infrastructure Chris 319624.20 ClosedLost
06
2017-03-
8 Oloo Configurable web-enabled data-warehouse Chris 321016.26 ClosedLost
08
2017-01-
9 Kaymbo Multi-lateral web-enabled definition Bob 690881.01 Developing
02
2016-11-
10 Rhyloo Public-key coherent infrastructure Chris 965477.74 Prospecting
07

The schema, sample data, and queries are available as an attachment to this article.

1229/3812
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 ro
w) cumeWon,
max(amount) over (partition by owner order by CloseDate rows between unbounded preceding and current ro
w) 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()

1230/3812
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 betw
een unbounded preceding and current row) firstId,
last_value(id) over (partition by year(closeDate), quarter(closeDate) order by closeDate rows betwe
en 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


1231/3812
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 (partitio
n 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.

1232/3812
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

1.2.9.7.35 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 is described in Window Functions Overview. 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
BIT_AND
BIT_OR
BIT_XOR
COUNT
LEAD
MAX
MIN
NTILE
STD
STDDEV
STDDEV_POP
1233/3812
STDDEV_SAMP
SUM
VAR_POP
VAR_SAMP
VARIANCE
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 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:
1234/3812
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 |
+---------+--------+-------+-------------+

1.3 Clients & Utilities


mysql Client
The mysql command-line client.

Aria Clients and Utilities


Clients and utilities for working with Aria tables

Backup, Restore and Import Clients


Clients for taking backups or importing/restoring data

Graphical and Enhanced Clients


Incomplete list of graphical clients

MyISAM Clients and Utilities


Clients and utilities for working with MyISAM tables

dbdeployer
Installing and testing multiple MariaDB versions in isolation.

dbForge Studio for MySQL/MariaDB


IDE for the development, management, and administration of MariaDB & MySQL databases.
1235/3812
EXPLAIN Analyzer
6 The EXPLAIN Analyzer is an online tool for analyzing and optionally sharing...

EXPLAIN Analyzer API


2 The online EXPLAIN Analyzer tool has an open API to allow client applicatio...

innochecksum
Tool for printing checksums for InnoDB files.

msql2mysql
Description Initially, the MySQL C API was developed to be very similar to ...

my_print_defaults
Displays the options from option groups of option files

mysqladmin
1 Admin tool for monitoring, creating/dropping databases, stopping mysqld etc.

mysqlaccess
Tool for checking access privileges.

mysqlbinlog
mysqlbinlog utility for processing binary log files.

mysqlcheck
Tool for checking, repairing, analyzing and optimizing tables.

mysql_convert_table_format
Convert tables to use a particular storage engine by default.

mysqldumpslow
Display data from the slow query log.

mysql_embedded
mysql client statically linked to libmysqld, the embedded server.

mysql_find_rows
Read files containing SQL statements and extract statements that match a pattern.

mysql_fix_extensions
Converts the extensions for MyISAM (or ISAM) table files to their canonical forms.

mysql_install_db
1 Tool for creating the system tables in the mysql database.

mysql_plugin
Tool for enabling or disabling plugins.

mysqlreport
Creates a friendly report of important MariaDB status values.

MySQL Sandbox
Installing multiple MariaDB versions in isolation.

mysql_secure_installation
8 Improve the security of a MariaDB installation.

mysql_setpermission
Helps add users or databases or change passwords in MariaDB.

mysqlshow
Shows database structure.

mysqlslap
Tool for load-testing MariaDB.

mysql-stress-test
Perl script that performs stress-testing of the MariaDB server

1236/3812
mysql-test
Testing utility

mysql_tzinfo_to_sql
1 Load time zones to the mysql time zone tables.

mysql_upgrade
2 Update to the latest version.

mysql_waitpid
Terminate processes.

mysql_zap
Kill processes that match a pattern.

perror
Display descriptions for system or storage engine error codes

replace Utility
The replace utility program changes strings in place infiles or on the standard input

resolveip
Resolves IP addresses to host names and vice versa

resolve_stack_dump
Resolve numeric stack strace dump into symbols

xtstat
Used to monitor all internal activity of PBXT

mariadb-access
Symlink or new name for mysqlaccess.

mariadb-admin
Symlink or new name for mysqladmin.

mariadb-check
Symlink or new name for mysqlcheck.

mariadb-conv
Character set conversion utility for MariaDB.

mariadb-convert-table-format
Symlink or new name for mysql_convert_table_format.

mariadb-dumpslow
Symlink or new name for mysqldumpslow.

mariadb-embedded
Symlink or new name for mysql_embedded.

mariadb-find-rows
Symlink or new name for mysql_find_rows.

mariadb-fix-extensions
Symlink or new name for mysql_fix_extensions.

mariadb-install-db
Symlink to mysql_install_db.

mariadb-plugin
Symlink or new name for mysql_plugin.

mariadb-report
Symlink or new name for mysqlreport.

mariadb-secure-installation
Symlink or new name for mysql_secure_installation.

1237/3812
mariadb-setpermission
Symlink or new name for mysql_setpermission.

mariadb-show
Symlink or new name for mysqlshow.

mariadb-slap
Symlink or new name for mysqlslap.

mariadb-tzinfo-to-sql
Symlink or new name for mysql_tzinfo_to_sql.

mariadb-upgrade
Symlink or new name for mysql_upgrade.

mariadb-waitpid
Symlink or new name for mysql_waitpid.

There are 8 related questions .

1.3.1 mysql Client


The mysql (from MariaDB 10.4.6, also called mariadb) command-line client.
mysql Command-line Client
7 mysql is a simple SQL shell with GNU readline capabilities.

Delimiters
How to Change the Delimiter for the mysql Client.

mariadb Command-Line Client


Symlink or new name for mysql, the command-line client.

There are 2 related questions .

1.3.2 mysql Command-line Client


Contents
1. About the mysql Command-Line Client
2. Using mysql
1. Options
2. Option Files
1. Option Groups
3. How to Specify Which Protocol to Use
When Connecting to the mysqld Server
1. Linux/Unix
2. Windows
4. How to Test Which Protocol is Used
5. mysql Commands
6. The mysql_history File
7. prompt Command
8. mysql Tips
1. Displaying Query Results Vertically
2. Using the --safe-updates Option
3. Disabling mysql Auto-Reconnect
9. See Also

About the mysql Command-Line Client


mysql (from MariaDB 10.4.6, also called mariadb) is a simple SQL shell (with GNU readline capabilities). It 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 mysql to
1238/3812
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 mysql is very easy. Invoke it from the prompt of your command interpreter as follows:

mysql db_name

Or:

mysql --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 mysql to attempt to kill the current statement. If this cannot be done, or Control-C is typed
again before the statement is killed, mysql exits.
You can execute SQL statements in a script file (batch file) like this:

mysql db_name < script.sql > output.tab

From MariaDB 10.4.6, mariadb is available as a symlink to mysql .


From MariaDB 10.5.2, mysql is the symlink, and mariadb the binary name.

Using mysql
The command to use mysql and the general syntax is:

mysql <options>

Options
mysql supports the following options:

Option Description
-? , --help Display this help and exit.
-I , --help Synonym for -?
--abort-source-
Abort 'source filename' operations in case of errors.
on-error

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 mysql to start faster, but you must issue the rehash
--auto-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, mysql 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- No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a
rehash quicker start of mysql and disables rehashing on reconnect.
--auto-
Automatically switch to vertical output mode if the result is wider than the terminal width.
vertical-output

Print results using tab as the column separator, with each row on a new line. With this option,
mysql does not use the history file. Batch mode results in nontabular output format and escaping
-B , --batch
of special characters. Escaping may be disabled by using raw mode; see the description for the -
-raw option. (Enables --silent .)

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
--binary-mode
mode (for input piped to mysql or loaded using the 'source' command). This is necessary when
processing output from mysqlbinlog that may contain blobs.
--character-
Directory for character set files.
sets-dir=name

--column-names Write column names in results. (Defaults to on; use --skip-column-names to disable.)
--column-type-
Display column type information.
info

1239/3812
Preserve comments. Send comments to the server. The default is --skip-comments (discard
-c , --comments
comments), enable with --comments .
-C , --compress Compress all information sent between the client and the server if both support compression.
--connect-
Notify the server that this client is prepared to handle expired password sandbox mode even if --
expired-
batch was specified. From MariaDB 10.4.3.
password

--connect-
Number of seconds before connection timeout. Defaults to zero.
timeout=num

-D , --
Database to use.
database=name

-# [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[=options]

--debug-check Check memory and open file usage at exit.


-T , --debug-
Print some debug info at exit.
info

--default-
Default authentication client-side plugin to use.
auth=plugin

Set the default character set. A common issue that can occur when the operating system uses utf8
--default- or another multibyte character set is that output from the mysql client is formatted incorrectly, due
character- to the fact that the MariaDB client uses the latin1 character set by default. You can usually fix such
set=name 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-
Read this file after the global files are read. Must be given as the first option.
extra-file=file

--defaults-
Only read default options from the given file. Must be given as the first option.
file=file

--defaults-
group- In addition to the given groups, also read groups with this suffix.
suffix=suffix

--
Delimiter to be used. The default is the semicolon character (“;”).
delimiter=name

--enable-
cleartext- Obsolete option. Exists only for MySQL compatibility. From MariaDB 10.3.36.
plugin

-e , -- Execute statement and quit. Disables --force and history file. The default output format is like
execute=name that produced with --batch .
-f , --force Continue even if we get an SQL error. Sets --abort-source-on-error to 0.
-h , --
Connect to host.
host=name

-H , --html Produce HTML output.


-U , --i-am-a-
Synonym for option --safe-updates , -U .
dummy

Ignore space after function names. Allows one to have spaces (including tab characters and new
-i , --ignore-
line characters) between function name and '('. The drawback is that this causes built in functions
spaces
to become reserved words.
--init- SQL Command to execute when connecting to the MariaDB server. Will automatically be re-
command=str executed when reconnecting.
--line-numbers Write line numbers for errors. (Defaults to on; use --skip-line-numbers to disable.)
Enable or disable LOCAL capability for LOAD DATA INFILE. With no value, the option enables
--local-infile 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- The maximum packet length to send to or receive from server. The default is 16MB, the maximum
packet=num 1GB.
--max-join-
Automatic limit for rows in a join when using --safe-updates . Default is 1000000.
size=num
1240/3812
Enable named commands. Named commands mean mysql's internal commands (see below) .
When enabled, the named commands can be used from any line of the query, otherwise only from
-G , --named-
the first line, before an enter. Long-format commands are allowed, not just short-format
commands
commands. For example, quit and \q are both recognized. Disable with --disable-named-
commands . This option is disabled by default.

--net-buffer-
The buffer size for TCP/IP and socket communication. Default is 16KB.
length=num

-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.
Ignore statements except those those that occur while the default database is the one named on
-o , --one-
the command line. This filtering is limited, and based only on USE statements. This is useful for
database
skipping updates to other databases in the binary log.
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
--pager[=name]
help (\h) also. This option does not work in batch mode. Disable with --disable-pager . This
option is disabled by default.
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 --
-p , --
password or -p option on the command line, mysql prompts for one. Specifying a password on
password[=name]
the command line should be considered insecure. You can use an option file to avoid giving the
password on the command line.
--plugin-
Directory for client-side plugins.
dir=name

Port number to use for connection or 0 for default to, in order of preference, my.cnf,
-P , --port=num
$MYSQL_TCP_PORT, /etc/services, built-in default (3306).
--print-
Print the program argument list and exit. Must be given as the first option.
defaults

--progress- Get progress reports for long running commands (such as ALTER TABLE). (Defaults to on; use -
reports -skip-progress-reports to disable.)

--prompt=name Set the mysql prompt to this value. See prompt command for options.
--
The protocol to use for connection (tcp, socket, pipe, memory).
protocol=name

Don't cache result, print it row by row. This may slow down the server if the output is suspended.
-q , --quick
Doesn't use history file.
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
-r , --raw --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 if the connection is lost. This option is enabled by default. Disable with --disable-
--reconnect
reconnect or skip-reconnect .

Allow only those UPDATE and DELETE statements that specify which rows to modify by using
-U , --safe-
key values. If you have set this option in an option file, you can override it by using --safe-
updates
updates on the command line. See using the --safe-updates option for more.

Refuse client connecting to server if it uses old (pre-MySQL4.1.1) protocol. Defaults to false
--secure-auth
(unlike MySQL since 5,6, which defaults to true).
--select-
Automatic limit for SELECT when using --safe-updates. Default 1000.
limit=num

--server-
Send embedded server this as a parameter.
arg=name

--shared- Shared-memory name to use for Windows connections using shared memory to a local server
memory-base- (started with the --shared-memory option). Case-sensitive.
name=name

--show-
Show warnings after every statement. Applies to interactive and batch mode.
warnings

--sigint-
Ignore SIGINT signals (usually CTRL-C).
ignore

1241/3812
Be more silent. This option can be given multiple times to produce less and less output. This
-s , --silent 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-
Disable automatic rehashing. See --auto-rehash .
auto-rehash

-N , --skip-
Don't write column names in results. See --column-names .
column-names

-L , --skip-
Discard comments. Set by default, see --comments to enable.
comments

-L , --skip-
Don't write line number for errors. See --line-numbers .
line-numbers

-L , --skip-
progress- Disables getting progress reports for long running commands. See --progress-reports .
reports

-L , --skip-
Don't reconnect if the connection is lost. See --reconnect .
reconnect

-S , -- For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named
socket=name pipe to use.
Enables TLS. TLS is also enabled even without setting this option when certain other TLS options
are set. Starting with MariaDB 10.2, the --ssl option will not enable verifying the server
--ssl
certificate 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.

Defines a path to a PEM file that should contain one or more X509 certificates for trusted
Certificate Authorities (CAs) to use for TLS. This option requires that you use the absolute path,
--ssl-ca=name
not a relative path. See Secure Connections Overview: Certificate Authorities (CAs) for more
information. This option implies the --ssl 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) to use for TLS. This option requires that
you use the absolute path, not a relative path. The directory specified by this option needs to be
--ssl- run through the openssl rehash command. See Secure Connections Overview: Certificate
capath=name 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 for more information about
which libraries are used on which platforms. This option implies the --ssl option.
--ssl- Defines a path to the X509 certificate file to use for TLS. This option requires that you use the
cert=name absolute path, not a relative path. This option implies the --ssl option.
--ssl-
List of permitted ciphers or cipher suites to use for TLS. This option implies the --ssl option.
cipher=name

Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for
TLS. This option requires that you use the absolute path, not a relative path. See Secure
Connections Overview: Certificate Revocation Lists (CRLs) for more information. This option is
--ssl-crl=name
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 for more information about which libraries are used on which platforms.
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. 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
--ssl- command. See Secure Connections Overview: Certificate Revocation Lists (CRLs) for more
crlpath=name 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 for more information about which libraries are used on
which platforms.
Defines a path to a private key file to use for TLS. This option requires that you use the absolute
--ssl-key=name
path, not a relative path. This option implies the --ssl option.
--ssl-verify-
Enables server certificate verification. This option is disabled by default.
server-cert

Display output in table format. This is the default for interactive use, but can be used to produce
-t , --table
table output in batch mode.
Append everything into outfile. See interactive help (\h) also. Does not work in batch mode.
--tee=name
Disable with --disable-tee . This option is disabled by default.
1242/3812
This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will
--tls- only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. See
version=name Secure Connections Overview: TLS Protocol Versions for more information. This option was
added in MariaDB 10.4.6.
-n , --
unbuffered Flush buffer after each query.

-u , --
User for login if not current user.
user=name

-v , --verbose Write more. (-v -v -v gives the table output format).


-V , --version Output version information and exit.
Print the output of a query (rows) vertically. Use the \G delimiter to apply to a particular statement
-E , --vertical
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 mysqldump --xml option for more.

Option Files
In addition to reading options from the command-line, mysql can also read options from option files. If an unknown
option is provided to mysql 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 and later, mysql is linked with MariaDB Connector/C . 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 for more information.

Option Groups
mysql reads options from the following option groups from option files:

Group Description
[mysql] Options read by mysql , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysql . Available starting with MariaDB 10.4.6.
client]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and MySQL
[client]
clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

How to Specify Which Protocol to Use When


Connecting to the mysqld Server
You can force which protocol to be used to connect to the mysqld 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, command line connection properties that do not force protocol are
ignored.
From MariaDB 10.6.1, a connection property specified via the command line (e.g. --port=3306 ) will force its type. The

1243/3812
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 mysqld
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> mysql 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

mysql 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 mysql server, display result vertically.
exit , \q Exit mysql. Same as quit.
go , \g Send command to mysql server.
help , \h Display this help.
nopager , \n Disable pager, print to stdout.

1244/3812
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 mysql prompt. See prompt command for options.
quit , \q Quit mysql.
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 mysql 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).

1245/3812
\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.

mysql Tips
This section describes some techniques that can help you use mysql 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:

mysql> 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: [email protected]
mail_to: "Thimble Smith" <[email protected]>
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, mysql 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 statement has the following effects:


You are not allowed to execute an UPDATE or DELETE statement unless you specify a key constraint in the
WHERE clause or provide a LIMIT clause (or both). For example:

1246/3812
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:

mysql --safe-updates --select_limit=500 --max_join_size=10000

Disabling mysql Auto-Reconnect


If the mysql 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 mysql 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:

mysql> SET @a=1;


Query OK, 0 rows affected (0.05 sec)
mysql> 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)
mysql> 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 mysql terminate with an error if the connection has been lost, you can start the mysql client with the --skip-
reconnect option.

See Also
Troubleshooting Connection Issues
Readline commands and configuration

1.3.3 Delimiters
The default delimiter in the mysql client (from MariaDB 10.4.6, also called mariadb) is the semicolon.
When creating stored programs from the command-line, it is likely you will need to differentiate between the regular
delimiter and a delimiter inside a BEGIN END 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 mysql 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
1247/3812
further confusion. // is a common choice, and used throughout the knowledgebase.
Here's how the function could be successfully entered from the mysql 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.

1.3.4 mariadb Command-Line Client


MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb is a symlink to mysql , the command-line client.
See mysql Command-Line Client for details.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb is the name of the command-line client, with mysql a symlink .

1.3.5 Aria Clients and Utilities


Clients and utilities for working with the Aria storage engine
aria_chk
Used for checking, repairing, optimizing and sorting Aria tables.

aria_pack
Tool for compressing Aria tables.

aria_read_log
1 Tool for displaying and applying log records from an Aria transaction log.

aria_s3_copy
Copies an Aria table to and from S3.

There are 4 related questions .

1.3.5.1 aria_chk
Contents
1. Options and Variables
1. Global Options
2. Main Arguments
3. Check Options (--check is the Default
Action for aria_chk):
4. Recover (Repair) Options (When
Using '--recover' or '--safe-recover'):
5. Other Options
6. Variables
2. Usage

aria_chk is used to check, repair, optimize, sort and get information about Aria tables.
With the MariaDB server you can use CHECK TABLE, REPAIR TABLE and OPTIMIZE TABLE to do similar things.

1248/3812
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
-# , -
Output debug log. Often this is 'd:t:o,filename'.
- debug=...

-H , -- HELP Display this help and exit.


-? , -- help Display this help and exit.
-
Path for control file (and logs if --logdir not used).
- datadir=path

-- ignore-
Don't open the control file. Only use this if you are sure the tables are not used by another program
control-file

-
Path for log files.
- logdir=path

-- require-
Abort if we can't find/read the maria_log_control file
control-file

-s , -- silent Only print errors. One can use two -s to make aria_chk very silent.
-t , - Path for temporary files. Multiple paths can be specified, separated by colon (:) on Unix or
- tmpdir=path semicolon (;) on Windows. They will be used in a round-robin fashion.
-v , - Print more information. This can be used with --description and --check . Use many -v for more
- verbose verbosity.
-V , -
Print version and exit.
- version

-w , -- wait Wait if table is locked.

Check Options (--check is the Default Action for aria_chk):


Option Description
-c , -
Check table for errors.
- check

1249/3812
-e , -
Check the table VERY throughly. Only use this in extreme cases as aria_chk should normally be able
- extend-
to find out if the table is ok even without this switch.
check

-F , -- fast Check only tables that haven't been closed properly.


-C , -
- check-only- Check only tables that have changed since last check.
changed

-f , -
Restart with ' -r ' if there are any errors in the table. States will be updated as with ' --update-state '.
- force

-i , -
Print statistics information about table that is checked.
- information

-m , -
- medium- Faster than extend-check, and finds 99.99% of all errors. Should be good enough for most cases.
check

Mark tables as crashed if any errors were found and clean if check didn't find any errors but table
-U , -
was marked as 'not clean' before. This allows one to get rid of warnings like 'table not properly
- update-
closed'. If table was updated, update also the timestamp for when the check was made. This option is
state
on by default! Use --skip-update-state to disable.
-T , -- read-
Don't mark table as checked.
only

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-
Correct checksum information for table.
checksum

-D , -- data-
Max length of data file (when recreating data file when it's full).
file-length= #

-e , - Try to recover every possible row from the data file Normally this will also find a lot of garbage
- extend-check rows; Don't use this option if you are not totally desperate.
-f , -- force Overwrite old temporary files.
-k , -- keys- Tell MARIA to update only some specific keys. # is a bit mask of which keys to use. This can be
used= # used to get faster inserts.
-- max-record-
Skip rows bigger than this if aria_chk can't allocate memory to hold it.
length= #

-r , -
Can fix almost anything except unique keys that aren't unique.
- recover

-n , -- sort-
Forces recovering with sorting even if the temporary file would be very big.
recover

-p , -
- parallel- Uses the same technique as '-r' and '-n', but creates all the keys in parallel, in different threads.
recover

-o , -- safe- Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that
recover it can't fix the data file.
-
Log repair command to transaction log. This is needed if one wants to use the maria_read_log to
- transaction-
repeat the repair.
log

-- character-
Directory where character sets are.
sets-dir=...

-- set-
Change the collation used by the index.
collation=name

Faster repair by not modifying the data file. One can give a second ' -q ' to force aria_chk to modify
-q , -- quick the original datafile in case of duplicate keys. NOTE: Tables where the data file is currupted can't
be fixed with this option.

1250/3812
-u , -- unpack Unpack file packed with aria_pack.

Other Options
Option Description
Analyze distribution of keys. Will make some joins in MariaDB faster. You can check the
-a , -- analyze
calculated distribution by using ' --description --verbose table_name '.
- Specifies how index statistics collection code should treat NULLs. Possible values of name are
- stats_method=name "nulls_unequal" (default for 4.1/5.0), "nulls_equal" (emulate 4.0), and "nulls_ignored".
-d , -
Prints some information about table.
- description

-A , -- set-auto- Force auto_increment to start at this or higher value If no value is given, then sets the next
increment[=value] 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- Sort records according to an index. This makes your data much more localized and may speed
records= # up things (It may be VERY slow to do a sort the first time!).
-b , -- block-
Find a record, a block at given offset belongs to.
search= #

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
-z , -- zerofill
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-
Like --zerofill but does not zero out LSN of data/index pages.
lsn

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

1.3.5.2 aria_pack
1251/3812
Contents
1. Options
2. Unpacking
3. Example
4. See Also

aria_pack is a tool for compressing Aria 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 (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 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
-#, --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.
-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.
-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 option.

Example

1252/3812
> 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
myisamchk

1.3.5.3 aria_read_log
aria_read_log is a tool for displaying and applying log records from an Aria transaction log.
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 file.

Option Description
Apply log to tables: modifies tables! you should make a backup first! Displays a lot of
-a, --apply
information if not run with --silent.
--character-sets-
Directory where character sets are.
dir=name
-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 to the directory where to store transactional log
path=name
-P, --page-buffer-
The size of the buffer used for index blocks for Aria tables.
size=#
-l, --print-log-control-
Print the content of the aria_log_control_file. From MariaDB 10.4.1.
file
-o, --start-from-lsn=# Start reading log from this lsn.
-C, --start-from-
Start applying from last checkpoint.
checkpoint
-s, --silent Print less information during apply/undo phase.
-T, --tables-to- List of comma-separated tables that we should apply REDO on. Use this if you only want to
redo=name recover some tables.
-t, --tmpdir=name Path for temporary files. Multiple paths can be specified, separated by colon (:)
--translog-buffer-
The size of the buffer used for transaction log for Aria tables.
size=#

1253/3812
Apply UNDO records to tables. (disable with --disable-undo) (Defaults to on; use --skip-undo
-u, --undo
to disable.)
-v, --verbose Print more information during apply/undo phase.
-V, --version Print version and exit.

1.3.5.4 aria_s3_copy
1.3.6 Backup, Restore and Import Clients
Clients for taking backups or importing/restoring data
Mariabackup
Physical backups, supports Data-at-Rest and InnoDB compression.

Percona XtraBackup
Open source tool for performing hot backups of MariaDB, MySQL and Percona Server databases.

mariadb-dump
Symlink or new name for mysqldump.

mariadb-dump/mysqldump
9 Dump a database or a collection of databases in a portable format.

mariadb-hotcopy
Symlink or new name for mysqlhotcopy.

mariadb-import
Symlink or new name for mysqlimport.

mysqlhotcopy
4 Fast backup program on local machine. Deprecated.

mysqlimport
1 Loads tables from text files in various formats.

There are 5 related questions .

1.3.6.1 Mariabackup
1.3.6.2 mariadb-dump
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-dump is a symlink to mysqldump , the backup tool.
See mysqldump for details.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-dump is the name of the tool, with mysqldump a symlink .

1.3.6.3 mariadb-dump/mysqldump

1254/3812
Contents
1. Performance
2. Usage
1. Row by Row vs. Buffering
2. mysqldump in MariaDB 10.3 and
Higher
3. mysqldump and Old Versions of
MySQL
4. Options
1. Group Options
2. Special Characters in Option
Values
5. Option Files
1. Option Groups
6. NULL, ´NULL´, and Empty Values in
XML
7. Restoring
3. Variables
4. Examples
5. See Also

MariaDB starting with 10.4.6


From MariaDB 10.4.6, mariadb-dump is a symlink to mysqldump .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-dump is the name of the command-line client, with mysqldump a symlink .

The mysqldump client 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, mysqldump 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 tables, consider using mysqlhotcopy instead
because it can accomplish faster backups and faster restores.
mysqldump dumps triggers along with tables, as these are part of the table definition. However, stored procedures,
views, and events are not, and need extra parameters to be recreated explicitly (for example, --routines and --
events ). Procedures and functions are however also part of the system tables (for example mysql.proc).

mysqldump supports the enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT.

Performance
mysqldump 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 mysqldump 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 mysqldump :

shell> mysqldump [options] db_name [tbl_name ...]


shell> mysqldump [options] --databases db_name ...
shell> mysqldump [options] --all-databases
shell> mysqldump [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.
mysqldump does not dump the INFORMATION_SCHEMA (or PERFORMANCE_SCHEMA, if enabled) database by
1255/3812
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 mysqldump supports, execute mysqldump --help .

Row by Row vs. Buffering


mysqldump 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 .

mysqldump in MariaDB 10.3 and Higher


mysqldump in MariaDB 10.3 includes logic to cater for the mysql.transaction_registry table. mysqldump from an earlier
MariaDB release cannot be used on MariaDB 10.3 and beyond.

mysqldump and Old Versions of MySQL


If you are using a recent version of mysqldump 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
mysqldump 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 a DROP DATABASE before each create. Typically used in conjunction with the --all-databases or --databases
--add-drop-database
option because no CREATE DATABASE statements are written unless one of those options is specified.
--add-drop-table Add a DROP TABLE before each create.
--add-drop-trigger Add a DROP TRIGGER statement before each CREATE TRIGGER. From MariaDB 10.2.6 .
Add locks around INSERT statements, which results in faster inserts when the dump file is reloaded. Use --skip-add-
--add-locks
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-
Adds STOP SLAVE prior to CHANGE MASTER and START SLAVE to bottom of dump.
statements

--as-of Dump system versioned table as of specified timestamp. From MariaDB 10.7.0.
--character-sets-
Directory for character set files.
dir=name

Write additional information in the dump file such as program version, server version, and host. Disable with --skip-
-i , --comments
comments .

Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables the
--compact --skip-add-drop-table , --skip-add-locks , --skip-comments , --skip-disable-keys , and --skip-set-charset
options.
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.

--compatible=name
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 statements that include column names.


-C , --compress Use compression in server/client protocol. Both client and server must support compression for this to work.
By default S3 tables are ignored. With this option set, the result file will contain a CREATE statement for a similar Aria
--copy-s3-tables
table, followed by the table data and ending with an ALTER TABLE xxx ENGINE=S3 . From MariaDB 10.5.0.
Include all MariaDB and/or MySQL specific create options in CREATE TABLE statements. Use --skip-create-options to
-a , --create-options
disable.

Dump several databases. Normally, mysqldump treats the first name argument on the command line as a database name
-B , --databases and following names as table names. With this option, it treats all name arguments as database names. CREATE
DATABASE and USE statements are included in the output before each new database.
If using a debug version of MariaDB, write a debugging log. A typical debug_options string is ´d:t:o,file_name´. The
-#, --debug[=#]
default value is ´d:t:o,/tmp/mysqldump.trace´. If using a non-debug version, mysqldump will catch this and exit.
--debug-check Check memory and open file usage at exit.

1256/3812
--debug-info Print some debug info at exit.
--default-auth=name Default authentication client-side plugin to use.
--default-character- Set the default character set to name. If no character set is specified, until MariaDB 10.3.11, mysqldump uses utf8, and
set=name from MariaDB 10.3.11, uses utf8mb4.
--defaults-extra-
Read the file name after the global files are read. Must be given as the first argument.
file=name

--defaults-file=name Only read default options from the given file name. Must be given as the first argument.
--defaults-group- Also read groups with a suffix of str. For example, since mysqldump normally reads the [client] and [mysqldump] groups, -
suffix=str -defaults-group-suffix=x would cause it to also read the groups [mysqldump_x] and [client_x].
--delayed-insert Insert rows with INSERT DELAYED instead of INSERT.
On a primary replication server, delete the binary logs by sending a PURGE BINARY LOGS statement to the server after
--delete-master-logs
performing the dump operation. This option automatically enables --master-data .
'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put
-K , --disable-keys 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 .
If the --comments option and this option are given, mysqldump produces a comment at the end of the dump of the
following form:
-- Dump completed on DATE
--dump-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. From MariaDB 10.11.0


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 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 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-
--dump-slave[=value]
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 mysqldump to stop the replica SQL
thread before beginning the dump, and restart it again after completion.
-E, --events Include Event Scheduler events for the dumped databases in the output.
Use multiple-row INSERT syntax that include several VALUES lists. This results in a smaller dump file and speeds up
-e , --extended-insert
inserts when the file is reloaded. Defaults to on; use --skip-extended-insert to disable.
--fields-terminated- Fields in the output file are terminated by the given string. Used with the --tab option and has the same meaning as the
by=name corresponding FIELDS clause for LOAD DATA INFILE.

--fields-enclosed- Fields in the output file are enclosed by the given character. Used with the --tab option and has the same meaning as
by=name the corresponding FIELDS clause for LOAD DATA INFILE.

--fields-optionally- Fields in the output file are optionally enclosed by the given character. Used with the --tab option and has the same
enclosed-by=name meaning as the corresponding FIELDS clause for LOAD DATA INFILE.
--fields-escaped- Fields in the output file are escaped by the given character. Used with the --tab option and has the same meaning as
by=name the corresponding FIELDS clause for LOAD DATA INFILE.
--first-slave Removed in MariaDB 5.5. Use --lock-all-tables instead.
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
-F , --flush-logs 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 .
Send a FLUSH PRIVILEGES statement to the server after dumping the mysql database. This option should be used any
--flush-privileges time the dump contains the mysql database and any other database that depends on the data in the mysql database for
proper restoration.
Continue even if an SQL error occurs during a table dump.

One use for this option is to cause mysqldump to continue executing even when it encounters a view that has become
-f , --force
invalid because the definition refers to a table that has been dropped. Without --force in this example, mysqldump
exits with an error message. With --force , mysqldump prints the error message, but it also writes an SQL comment
containing the view definition to the dump output and continues executing.
Used together with --master-data and --dump-slave to more conveniently set up a new GTID replica. It causes those
options to output SQL statements that configure the replica to use the global transaction ID to connect to the primary
--gtid
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.
Dump binary strings in hexadecimal format (for example, ´abc´ becomes 0x616263 ). The affected data types are
--hex-blob
BINARY, VARBINARY, the BLOB types, and BIT.
-h name , --host=name Connect to and dump data from the MariaDB or MySQL server on the given host. The default host is localhost .
Do not dump the specified database. To specify more than one database to ignore, use the directive multiple times, once
--ignore-database=name
for each database. Only takes effect when used together with --all-databases or -A . Added in MariaDB 10.3.7.
Do not dump the specified table. To specify more than one table to ignore, use the directive multiple times, once for each
--ignore-table=name 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.
Do not dump the specified table data (only the structure). To specify more than one table to ignore, use the directive
--ignore-table-
multiple times, once for each table. Each table must be specified with both database and table names. From MariaDB
data=name
10.1.46 , MariaDB 10.2.33 , MariaDB 10.3.24, MariaDB 10.4.14 and MariaDB 10.5.3. See also --no-data .

1257/3812
--include-master-host- Add the MASTER_HOST and MASTER_PORT options for the CHANGE MASTER TO statement when using the --dump-slave
port option for a replica dump.
--insert-ignore Insert rows with INSERT IGNORE instead of INSERT .
--lines-terminated- Lines in the output file are terminated by the given string. This option is used with the --tab option and has the same
by=name meaning as the corresponding LINES clause for LOAD DATA INFILE.
Lock all tables across all databases. This is achieved by acquiring a global read lock for the duration of the whole dump
-x , --lock-all-tables by executing FLUSH TABLES WITH READ LOCK. This option automatically turns off --single-transaction and --
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 tables. For transactional tables such as InnoDB, --single-
transaction is a much better option than --lock-tables because it does not need to lock the tables at all.
-l , --lock-tables
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.
When restoring the dump, the server will, if logging is turned on, log the queries to the general and slow query log.
--log-queries
Defaults to on; use --skip-log-queries to disable. Added in MariaDB 10.1.1 .
Causes the binary log 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 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 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 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:
mysql> STOP SLAVE SQL_THREAD;
mysql> SHOW SLAVE STATUS;
--master-data[=#]

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> mysqldump --master-data=2 --all-databases > dumpfile

3. Restart the replica:


mysql> START SLAVE;

4. On the new replica, load the dump file:


shell> mysql < dumpfile

5. On the new replica, set the replication coordinates to those of the primary server obtained earlier:
mysql> 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))
The initial buffer size for client/server TCP/IP and socket communication. This can be used to limit the size of rows in the
--net-buffer-length=# dump. When creating multiple-row INSERT statements (as with the --extended-insert or --opt option), mysqldump
creates rows up to net_buffer_length length.
--no-autocommit Enclose the INSERT statements for each dumped table within SET autocommit = 0 and COMMIT statements.
This option suppresses the CREATE DATABASE ... IF EXISTS statement that normally is output for each dumped
-n , --no-create-db
database if --all-databases or --databases is given.
-t , --no-create-info Do not write CREATE TABLE statements which re-create each dumped table.
Do not write any table row information (that is, do not dump table contents). This is useful if you want to dump only the
-d , --no-data CREATE TABLE statement for the table (for example, to create an empty copy of the table by loading the dump file). See
also --ignore-table-data .
Do not dump rows for engines that manage external data (i.e. MRG_MyISAM, MRG_ISAM, CONNECT, OQGRAPH,
--no-data-med Spider, VP, Federated). 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 .
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
--opt 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 .

1258/3812
Sorts each table's rows by primary key, or first unique key, if such a key exists. This is useful when dumping a MyISAM
--order-by-primary
table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.
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,
--order-by-size
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.
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
-p[passwd] , -- command line, mysqldump prompts for one.
password[=passwd
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.
On Windows, connect to the server via a named pipe. This option applies only if the server supports named-pipe
-W , --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.
The connection protocol to use for connecting to the server (TCP, SOCKET, PIPE, MEMORY). It is useful when the other
--protocol=name
connection parameters normally would cause a protocol to be used other than the one you want.
This option is useful for dumping large tables. It forces mysqldump to retrieve rows for a table from the server a row at a
-q , --quick 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.
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 -
-Q , --quote-names
-skip-quote-names , but this option should be given after any option such as --compatible that may enable --quote-
names .

--replace Use REPLACE INTO statements instead of INSERT INTO statements.


Direct output to a given file. This option should be used on Windows to prevent newline "\n" characters from being
-r , --result-
converted to "\r\n" carriage return/newline sequences. The result file is created and its previous contents overwritten,
file=name
even if an error occurs while generating the dump.
Include stored routines (procedures and functions) for the dumped databases in the output. Use of this option requires
the SELECT privilege for the mysql.proc table. The output generated using --routines contains CREATE PROCEDURE
and CREATE FUNCTION 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.
-R , --routines

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 table directly, using a MariaDB account which has appropriate privileges for
the mysql database.

Add 'SET NAMES default_character_set' to the output in order to set the character set. Enabled by default; suppress
set-charset
with --skip-set-charset .
-O, --set- Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --
variable=name variable-name=value .

--shared-memory-base- Shared-memory name to use for Windows connections using shared memory to a local server (started with the --
name shared-memory option). Case-sensitive. Defaults to MYSQL .

This option sends a START TRANSACTION SQL statement to the server before dumping data. It is useful only with
transactional tables such as InnoDB, 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 , MyISAM or MEMORY tables dumped while using this option may still change state.

--single-transaction 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, CREATE TABLE, DROP TABLE,
RENAME TABLE, or TRUNCATE TABLE. 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 mysqldump 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
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.
Disable the --opt option (disables --add-drop-table , --add-locks , --create-options , --quick , --extended-
--skip-opt
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.

1259/3812
--skip-tz-utc Disable the --tz-utc option.
-S name , --
For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use.
socket=name

Enables TLS. TLS is also enabled even without setting this option when certain other TLS options are set. Starting with
--ssl MariaDB 10.2, the --ssl option will not enable verifying the server certificate by default. In order to verify the server
certificate, the user must specify the --ssl-verify-server-cert option.
Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to
--ssl-ca=name use for TLS. This option requires that you use the absolute path, not a relative path. See Secure Connections Overview:
Certificate Authorities (CAs) for more information. This option implies the --ssl 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) to use for TLS. 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 command. See Secure
--ssl-capath=name Connections Overview: 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 for more information about which libraries are used on which platforms.
This option implies the --ssl option.
Defines a path to the X509 certificate file to use for TLS. This option requires that you use the absolute path, not a
--ssl-cert=name relative path. This option implies the --ssl option.

--ssl-cipher=name List of permitted ciphers or cipher suites to use for TLS. This option implies the --ssl option.
Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for TLS. This option
requires that you use the absolute path, not a relative path. See Secure Connections Overview: Certificate Revocation
--ssl-crl=name 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 for more information about which libraries are used on which platforms.
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. 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 command. See Secure Connections Overview: Certificate
--ssl-crlpath=name
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 for more information about which libraries are used on which platforms.
Defines a path to a private key file to use for TLS. This option requires that you use the absolute path, not a relative
--ssl-key=name
path. This option implies the --ssl option.
--ssl-verify-server-
Enables server certificate verification. This option is disabled by default.
cert

Dump the database's system tables in a logical form. With this option, the mysql database tables are dumped as
-- CREATE USER, CREATE SERVER and other forms of logical portable SQL statements. The option values here are from
system=option[,option]] the set of all , users , plugins , udfs , servers , stats , timezones . From MariaDB 10.2.37 , MariaDB 10.3.28,
MariaDB 10.4.18 and MariaDB 10.5.9.
Produce tab-separated text-format data files. With this option, for each dumped table mysqldump 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 mysqldump/ is run on the same machine as the mysqld server. You must have
-T , --tab=name 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.
This option overrides the --databases ( -B ) option. mysqldump regards all name arguments following the option as
--tables
table names.
This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is
--tls-version=name present in this list. All other TLS protocol versions will not be permitted. See Secure Connections Overview: TLS Protocol
Versions for more information. This option was added in MariaDB 10.4.6.
--triggers Include triggers for each dumped table in the output. This option is enabled by default; disable it with --skip-triggers .
This option enables TIMESTAMP columns to be dumped and reloaded between servers in different time zones.
mysqldump sets its connection time zone to UTC and adds SET TIME_ZONE=´+00:00´ to the dump file. Without this
--tz-utc 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.
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.

-w cond , --where=cond Examples:


--where="user=´jimf´"
-w"userid>1"
-w"userid<1"

-X , --xml Dump a database as well formed XML.

Group Options
Some mysqldump options are shorthand for groups of other options:

1260/3812
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, mysqldump can also read options from option files. If an unknown
option is provided to mysqldump 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 and later, mysqldump is linked with MariaDB Connector/C . 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 for more information.

Option Groups
mysqldump reads options from the following option groups from option files:

Group Description
[mysqldump] Options read by mysqldump , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysqldump . Available starting with MariaDB 10.4.6.
dump]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and MySQL
[client]
clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

NULL, ´NULL´, and Empty Values in XML


1261/3812
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 mysql client when run using the --xml option also follows the preceding rules.
XML output from mysqldump includes the XML namespace, as shown here :

shell> mysqldump --xml -u root world City


<?xml version="1.0"?>
<mysqldump 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>
</mysqldump>

Restoring
To restore a backup created with mysqldump, use the mysql client to import the dump, for example:

mysql 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

1262/3812
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
1263/3812
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 mysqldump is for making a backup of an entire database:

shell> mysqldump db_name > backup-file.sql

You can load the dump file back into the server like this:

shell> mysql db_name < backup-file.sql

Or like this:

shell> mysql -e "source /path-to-backup/backup-file.sql" db_name

mysqldump is also very useful for populating databases by copying data from one MariaDB server to another:

shell> mysqldump --opt db_name | mysql --host=remote_host -C db_name

It is possible to dump several databases with one command:

shell> mysqldump --databases db_name1 [db_name2 ...] > my_databases.sql

To dump all databases, use the --all-databases option:

1264/3812
shell> mysqldump --all-databases > all_databases.sql

For InnoDB tables, mysqldump provides a way of making an online backup:

shell> mysqldump --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 or at least know the binary log
coordinates to which the dump corresponds:

shell> mysqldump --all-databases --master-data=2 > all_databases.sql

Or:

shell> mysqldump --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
MariaDB point-in-time recovery (video)
MariaDB Enterprise Backup
Upgrading to a newer major version of MariaDB (video)

1.3.6.4 mariadb-hotcopy
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-hotcopy is a symlink to mysqlhotcopy , the deprecated backup script.
See mysqlhotcopy for details.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-hotcopy is the name of the script, with mysqlhotcopy a symlink .

1.3.6.5 mariadb-import
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-import is a symlink to mysqlimport , the tool for loading tables from text files in
various formats.
See mysqlimport for details.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-import is the name of the script, with mysqlimport a symlink .

1.3.6.6 mysqlhotcopy
mysqlhotcopy is currently deprecated.

1265/3812
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-hotcopy is a symlink to mysqlhotcopy .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-hotcopy is the name of the script, with mysqlhotcopy a symlink .

mysqlhotcopy is a Perl script that was originally written and contributed by Tim Bunce. It uses FLUSH TABLES, LOCK
TABLES, 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. mysqlhotcopy > works only for
backing up MyISAM and ARCHIVE tables. It runs on Unix and NetWare.
To use mysqlhotcopy , you must have read access to the files for the tables that you are backing up, the SELECT
privilege 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> mysqlhotcopy db_name [/path/to/new_directory]


shell> mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory

Back up tables in the given database that match a regular expression:

shell> mysqlhotcopy db_name./regex/

The regular expression for the table name can be negated by prefixing it with a tilde (“ ~ ”):

shell> mysqlhotcopy db_name./~regex/

mysqlhotcopy supports the following options, which can be specified on the command line or in the [ mysqlhotcopy ]
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.
Insert checkpoint entries into the specified database db_name and table
--checkpoint=db_name.tbl_name
tbl_name .

Base directory of the chroot jail in which mysqld operates. The path value
--chroot=path
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.
The host name of the local host to use for making a TCP/IP connection to the
--host=host_name , -h host_name 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.
Do not include full index files for MyISAM tables in the backup. This makes the
--noindices backup smaller and faster. The indexes for reloaded tables can be
reconstructed later with myisamchk -rq.

Connect to old MySQL-server (before v5.5) which doesn't have FLUSH


--old-server
TABLES WITH READ LOCK fully implemented.
The password to use when connecting to the server. The password value is not
optional for this option, unlike for other MariaDB programs.
--password=password , -
ppassword
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.

1266/3812
-- Record master and slave status in the specified database db_name and table
record_log_pos=db_name.tbl_name 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 mysqlhotcopy documentation, including information about the structure of the tables needed
for the --checkpoint and --record_log_pos options:

shell> perldoc mysqlhotcopy

See Also
mysqldump
Mariabackup

1.3.6.7 mysqlimport
Contents
1. Using mysqlimport
1. Options
2. Option Files
1. Option Groups
3. Default Values

MariaDB starting with 10.4.6


From MariaDB 10.4.6, mariadb-import is a symlink to mysqlimport .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-import is the name of the script, with mysqlimport a symlink .

mysqlimport 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 is used to import the
rows.

Using mysqlimport
The command to use mysqlimport and the general syntax is:

mysqlimport [OPTIONS] database textfile1 [textfile2 ...]

Options
mysqlimport supports the following options:

variable Description
--character-sets-
Directory for character set files.
dir=name

-c cols , -- Use only these columns to import the data to. Give the column names in a comma separated
columns=cols list. This is same as giving columns to LOAD DATA INFILE.
-C , --compress Use compression in server/client protocol.

1267/3812
-# [options] , -
Output debug log. Often this is d:t:o,filename . The default is d:t:o .
-debug[=options]

--debug-check Check memory and open file usage at exit.


--debug-info Print some debug info at exit.
--default-
Default authentication client-side plugin to use.
auth=plugin

--default-
character- Set the default character set.
set=name

--defaults-extra-
Read this file after the global files are read. Must be given as the first option.
file=name

--defaults-
Only read default options from the given file name Must be given as the first option.
file=name

--defaults-group-
In addition to the given groups, also read groups with this suffix.
suffix=name

-d , --delete First delete all rows from table.


--fields-
terminated- Fields in the input file are terminated by the given string.
by=name

--fields-
Fields in the import file are enclosed by the given character.
enclosed-by=name

--fields-
optionally- Fields in the input file are optionally enclosed by the given character.
enclosed-by=name

--fields-escaped-
Fields in the input file are escaped by the given character.
by=name

-f , --force Continue even if we get an SQL error.


-? , --help Displays this help and exits.
-h name , --
Connect to host.
host=name

-i , --ignore If duplicate unique key was found, keep old row.


k , --ignore- Disable foreign key checks while importing the data. From MariaDB 10.3.16, MariaDB 10.2.25
foreign-keys and MariaDB 10.1.41 .
--ignore-lines=n Ignore first n lines of data infile.
--lines-
terminated- Lines in the input file are terminated by the given string.
by=name

-L , --local Read all files through the client.


-l , --lock-
Lock all tables for write (this disables threads).
tables

--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.
Password to use when connecting to server. If password is not given it's asked from the
-p[passwd] , --
terminal. Specifying a password on the command line should be considered insecure. You can
password[=passwd]
use an option file to avoid giving the password on the command line.
On Windows, connect to the server via a named pipe. This option applies only if the server
--pipe , -W
supports named-pipe connections.
--plugin-dir Directory for client-side plugins.
-P num , -- Port number to use for connection or 0 for default to, in order of preference, my.cnf, the
port=num MYSQL_TCP_PORT environment variable, /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.
1268/3812
--shared-memory- Shared-memory name to use for Windows connections using shared memory to a local server
base-name (started with the --shared-memory option). Case-sensitive.
-s , --silent Silent mode. Produce output only when errors occur.
-S , -- For connections to localhost, the Unix socket file to use, or, on Windows, the name of the
socket=name named pipe to use.
Enables TLS. TLS is also enabled even without setting this option when certain other TLS
options are set. Starting with MariaDB 10.2, the --ssl option will not enable verifying the
--ssl
server certificate by default. In order to verify the server certificate, the user must specify the --
ssl-verify-server-cert option.

Defines a path to a PEM file that should contain one or more X509 certificates for trusted
Certificate Authorities (CAs) to use for TLS. This option requires that you use the absolute path,
--ssl-ca=name
not a relative path. See Secure Connections Overview: Certificate Authorities (CAs) for more
information. This option implies the --ssl 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) to use for TLS. This option requires that
you use the absolute path, not a relative path. The directory specified by this option needs to be
--ssl- run through the openssl rehash command. See Secure Connections Overview:
capath=name 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 for more information
about which libraries are used on which platforms. This option implies the --ssl option.
Defines a path to the X509 certificate file to use for TLS. This option requires that you use the
--ssl-cert=name
absolute path, not a relative path. This option implies the --ssl option.
--ssl-
List of permitted ciphers or cipher suites to use for TLS. This option implies the --ssl option.
cipher=name

Defines a path to a PEM file that should contain one or more revoked X509 certificates to use
for TLS. This option requires that you use the absolute path, not a relative path. See Secure
Connections Overview: Certificate Revocation Lists (CRLs) for more information. This option is
--ssl-crl=name
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 for more information about which libraries are used on which platforms.

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. 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
--ssl- rehash command. See Secure Connections Overview: Certificate Revocation Lists (CRLs)
crlpath=name 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 for more information about which libraries are
used on which platforms.
Defines a path to a private key file to use for TLS. This option requires that you use the
--ssl-key=name
absolute path, not a relative path. This option implies the --ssl option.
--ssl-verify-
Enables server certificate verification. This option is disabled by default.
server-cert

This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version
--tls- will only be enabled if it is present in this list. All other TLS protocol versions will not be
version=name permitted. See Secure Connections Overview: TLS Protocol Versions for more information. This
option was added in MariaDB 10.4.6.
--use-
Load files in parallel. The argument is the number of threads to use for loading data.
threads=num

-u name , --
User for login if not current user.
user=name

-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, mysqlimport can also read options from option files. If an
unknown option is provided to mysqlimport 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:
1269/3812
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 and later, mysqlimport is linked with MariaDB Connector/C . Therefore, it may be helpful to see
Configuring MariaDB Connector/C with Option Files for more information on how MariaDB Connector/C handles
option files.

Option Groups
mysqlimport reads options from the following option groups from option files:

Group Description
[mysqlimport] Options read by mysqlimport , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysqlimport . Available starting with MariaDB 10.4.6.
import]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and
[client]
MySQL clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

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

1270/3812
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

1.3.7 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 .
dbForge Studio for MariaDB
2 Universal GUI Tool for Management & Administration, Development for MariaDB and MySQL

DBeaver
Free convenient cross-platform and cross-database Java GUI client

ERBuilder Data Modeler


1 A data modeling tool for multiple databases platforms including MariaDB, MySQL, and more ...

SQLyog: Community Edition


SQLyog Community Edition

HeidiSQL
Windows GUI client for MariaDB and MySQL.

Navicat
1 Graphical front-end for MariaDB

Querious
Mac OS X tool for database administration

TablePlus
A modern, native GUI client for multiple databases

Database Workbench
Database development environment for multiple database systems including MySQL and MariaDB

Moon Modeler
Moon Modeler is a database design tool for MariaDB. Draw ER diagrams, visua...

SQL Diagnostic Manager & SQLyog


Graphical MariaDB manager and monitor

mycli
Command line interface with auto-completion and syntax highlighting

ocelotgui
Linux client for MySQL and MariaDB

phpMyAdmin
1 Web-based MariaDB administration tool

Sequel Pro
1 Database management tool running on Mac

1271/3812
SQLTool Pro Database Editor
Android SQL client

dbForge Data Compare


A tool for MariaDB & MySQL data comparison and synchronization of data betw...

dbForge Data Generator


A tool for generation of large volumes of meaningful test table data.

dbForge Documenter for MariaDB and MySQL


dbForge Documenter is a useful tool for MariaDB and MySQL database for the ...

dbForge Fusion: MySQL & MariaDB Plugin for VS


Visual Studio plugin designed to simplify database development and management.

dbForge Query Builder for MySQL & MariaDB


A tool for visual query creation without code typing.

dbForge Schema Compare for MariaDB & MySQL


A tool for comparison and synchronization of DDL differences between database objects.

DbSchema
Mariadb Diagram Designer & Admin GUI Tool

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 d...

OmniDB
Browser-based IDE for MariaDB Administration

TOAD Edge
Windows GUI for MySQL. SQL Syntax Check. Freeware (Basic Features) & Payware (Extended Features).

TOAD for MySQL


1 Windows GUI for MySQL. Compatible with MariaDB. Freeware. SQL syntax check.

SQLPro Studio
SQLPro Studio is a fully native database client for macOS and iOS.

SB Data Generator
A tool to generate and populate selected tables or entire databases with realistic test data.

Beekeeper Studio
Open source and free GUI with a focus on usability. Mac, Linux, and Windows

LibreOffice Base
8 An open source RDBMS front-end tool to create and manage various databases

Valentina Studio
Free, advanced MariaDB GUI native on macOS, Windows & Linux, with advanced commercial version

DbVisualizer
Cross-platform universal database tool supporting MariaDB, PostgreSQL, MySQL and more

There are 5 related questions .

1.3.8 MyISAM Clients and Utilities


Clients and utilities for working with the MyISAM storage engine
myisamchk
Utility for checking, repairing and optimizing MyISAM tables.

Memory and Disk Use With myisamchk


myisamchk's performance can be dramatically enhanced for larger tables
1272/3812
myisamchk Table Information
myisamchk can be used to obtain information about MyISAM tables

myisamlog
Process the MyISAM log

myisampack
Tool for compressing MyISAM tables

myisam_ftdump
A tool for displaying information on MyISAM FULLTEXT indexes.

1.3.8.1 myisamchk
Contents
1. General Options
2. Checking Tables
3. Repairing Tables
4. Other Actions
5. Examples
6. See Also

myisamchk is a commandline tool for checking, repairing and optimizing non-partitioned MyISAM 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 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.
-
Write a debugging log. A typical debug_options string is ´d:t:o,file_name´. The default is
debug=options,
´d:t:o,/tmp/myisamchk.trace´. (Available in debug builds only)
-# options
Path for temporary files. Multiple paths can be specified, separated by colon (:) on Unix and
-t path, --
semicolon (;) on Windows. They will be used in a round-robin fashion. If not set, the TMPDIR
tmpdir=path
environment variable is used.
-s, --silent Only print errors. One can use two -s (-ss) to make myisamchk very silent.
Print more information. This can be used with --description and --check. Use many -v for more
-v, --verbose
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.

1273/3812
--defaults- Only read default options from the given file filename, which can be the full path, or the path relative
file=filename to the current directory.
--defaults-
Read the file filename, which can be the full path, or the path relative to the current directory, after
extra-
the global files are read.
file=filename
--defaults- Also read groups with a suffix of str. For example, --defaults-group-suffix=x would read the
group-suffix=str 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 tables without shutting
down or restricting access to the server by using CHECK TABLE instead.
The following check options are available:

Option Description
Check table for errors. This is the default operation if you specify no option that selects an operation type
-c, --check
explicitly.
-e, -- Check the table VERY throughly. Only use this in extreme cases as it may be slow, and myisamchk
extend- should normally be able to find out if the table has errors even without this switch. Increasing the
check key_buffer_size can help speed the process up.
-F, --fast Check only tables that haven't been closed properly.
-C, --
check-
Check only tables that have changed since last check.
only-
changed
Restart with '-r' (recover) if there are any errors in the table. States will be updated as with '--update-
-f, --force
state'.
-i, --
Print statistics information about the table that is checked.
information
-m, --
medium- Faster than extend-check, but only finds 99.99% of all errors. Should be good enough for most cases.
check
-U -- Mark tables as crashed if you find any errors. This should be used to get the full benefit of the --check-
update- only-changed option, but you shouldn´t use this option if the mysqld server is using the table and you are
state running it with external locking disabled.

1274/3812
-T, --read- Don't mark table as checked. This is useful if you use myisamchk to check a table that is in use by some
only 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 tables by using REPAIR TABLE.
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-
Max length of data file (when recreating data file when it's full).
length=#
Try to recover every possible row from the data file. Normally this will also find a lot of garbage
-e, --extend-check
rows; Don't use this option if you are not totally desperate.
Overwrite old temporary files. Add another --force to avoid 'myisam_sort_buffer_size is too small'
-f, --force 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.
Specify which keys to update. The value is a bit mask of which keys to use. Each binary bit
-k val, --keys-
corresponds to a table index, with the first index being bit 0. 0 disables all index updates, useful
used=#
for faster inserts. Deactivated indexes can be reactivated by using myisamchk -r.
--create-missing- Create missing keys. This assumes that the data file is correct and that the number of rows
keys stored in the index file is correct. Enables --quick
--max-record-
Skip rows larger than this if myisamchk can't allocate memory to hold them.
length=#
Can fix almost anything except unique keys that aren't unique (a rare occurrence). Usually this is
-r, --recover
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-
Uses the same technique as '-r' and '-n', but creates all the keys in parallel, in different threads.
recover
Uses old recovery method; Slower than '-r' but uses less disk space and can handle a couple of
-o, --safe-recover cases where '-r' reports that it can't fix the data file. Increase key_buffer_size for better
performance.
--character-sets-
Directory where the character sets are installed.
dir=directory_name
--set-
Change the collation (and by implication, the character set) used by the index.
collation=name
Faster repair by not modifying the data file. One can give a second '-q' to force myisamchk to
-q, --quick 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
Analyze distribution of keys. Will make some joins faster as the join optimizer can better choose
-a, --analyze 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.
-- Specifies how index statistics collection code should treat NULLs. Possible values of name are
stats_method=name "nulls_unequal" (default), "nulls_equal" (emulate MySQL 4.0 behavior), and "nulls_ignored".
Print some descriptive information about the table. Specifying the --verbose option once or
-d, --description
twice produces additional information.
-A [value], --set-
Force auto_increment to start at this or higher value. If no value is given, then sets the next
auto-
auto_increment value to the highest used value for the auto key + 1.
increment[=value]

1275/3812
Sort the index tree blocks in high-low order. This optimizes seeks and makes table scans that
-S, --sort-index
use indexes faster.
Sort records according to the given index (as specified by the index number). This makes your
-R index_num, -- data much more localized and may speed up range-based SELECTs and ORDER BYs using
sort-records=# this index. It may be VERY slow to do a sort the first time! To see the index numbers, SHOW
INDEX displays table indexes in the same order that myisamchk sees them. The first index is 1.
-b offset, --block-
Find the record to which a block at the given offset belongs.
search=offset

For more, see Memory and Disk Use With myisamchk.

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

1.3.8.2 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 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 file.
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.
1276/3812
key_buffer_size (which particularly helps with the --extend-check and --safe-recover options.
read_buffer_size
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
...

1.3.8.3 myisamchk Table Information


Contents
1. -dvv output
2. -eiv output
3. Examples

myisamchk 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
Storage format. One of packed (dynamic), fixed or compressed.
format
Chararacter
Default character set for the table.
set
File-version Always 1.
Creation time Time the data file was created
Recover time Most recent time the file was reconstructed.
Table status. One or more of analyzed, changed, crashed, open, optimized keys and sorted index
Status
pages.
Auto
increment Index number of the table's auto-increment column. Not shown if no auto-increment column exists.
key
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
Number of deleted blocks that are still reserving space. Use OPTIMIZE TABLE to defragment.
blocks
For dynamic tables, the number of data blocks. If the table is optimized, this will match the number of
Datafile parts
data records.
Deleted data Number of bytes of unreclaimed deleted data, Use OPTIMIZE TABLE to reclaim the space.
Datafile
Size in bytes of the data file pointer. The size of the data file pointer, in bytes.
pointer

1277/3812
Keyfile
Size in bytes of the index file pointer.
pointer
Max datafile
Maximum length, in bytes, that the data file could become.
length
Max keyfile
Maximum length, in bytes, that the index file could become.
length
Recordlength Space, in bytes, that each row takes.
table
Description of all indexes in the table, followed by all columns
description
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.
Length of the index or index part. The length of a multiple-column index is the sum of the component
Len 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.
Record of the number of rows per value for the index or index part. Used by the optimizer to calculate
Rec/key
query plans. Can be updated with myisamchk-a. If not present, defaults to 30.
Root Root index block address.
Blocksize Index block size, in bytes.
Column number, starting with one. The first line will contain the position and number of bytes used to
Field
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.
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 to defragment.
Key Index number, starting with one.
Keyblocks
Percentage of the keyblocks that are used. Percentages will be higher for optimized tables.
used

1278/3812
Packed Percentage space saved from packing key values with a common suffix.
Max levels Depth of the b-tree index 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
Percentage of the data file used.
used
Empty space Percentage of the data file unused.
Average number of blocks per record. Values higher than one indicate fragmentation. Use OPTIMIZE
Blocks/Record
TABLE 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

1279/3812
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

1280/3812
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

1.3.8.4 myisamlog
myisamlog processes and returns the contents of a MyISAM log file.
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
Specify record position file and record position.
record_pos

-u Displays update operations.


Verbose mode. Print more output about what the program does. This option can be given
-v
multiple times (-vv, -vvv) to produce more and more output.
-w write_file Specify the write file.

1281/3812
-V Display version information.

1.3.8.5 myisampack
Contents
1. Options
2. Uncompressing
3. Examples
4. See Also

myisampack is a tool for compressing MyISAM 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 (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 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 file.

Option Description
-b , --backup Make a backup of the table as table_name.OLD .
--character-sets-
Directory where character sets are.
dir=name

-# , --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.
Write info about progress and packing result. Use multiple -v flags for more
-v , --verbose
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 option.

Examples

1282/3812
> 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
myisamchk

1.3.8.6 myisam_ftdump
myisam_ftdump is a utility for displaying information about MyISAM FULLTEXT 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 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.

1283/3812
1.3.9 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 .
Visit https://www.dbdeployer.com for details on how to install and use it.

1.3.10 EXPLAIN Analyzer


The EXPLAIN Analyzer is an online tool for analyzing and optionally sharing the output of both EXPLAIN and EXPLAIN
EXTENDED .

Using the Analyzer


Using the analyzer is very simple.
1. In the mysql 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 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 page for details.
The following clients have support for the EXPLAIN Analyzer built in:

HeidiSQL
HeidiSQL has a button when viewing a query that sends the query to the explain analyzer.

1.3.11 EXPLAIN Analyzer API


The online EXPLAIN Analyzer 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

1284/3812
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

1.3.12 innochecksum
Contents
1. Usage
2. Description
3. Options
4. Examples

innochecksum is a tool for printing checksums for InnoDB files.

Usage
innochecksum [options] file_name

Description
It reads an InnoDB 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 .
MariaDB 10.1.4 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 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 mysqldump 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- Maximum checksum mismatch allowed before innochecksum terminates. MariaDB 10.2.2 ,
mismatches=# Defaults to 0, which terminates on the first mismatch. MariaDB 10.1.26
-c, --count Print a count of the number of pages in the file.
Debug mode; prints checksums for each page, implies --verbose . Replaced
-d, --debug
by --log in MariaDB 10.1.26
-e num, --end-
End at this page number (0-based).
page=#
-?, --help Displays help and exits.
-I, --info Synonym for --help.
Examine leaf index pages. Until MariaDB 10.2.4 , the short code was -l , but
-f, --leaf MariaDB 10.1.4
this was changed to avoid confusion with the --log option.
MariaDB 10.2.2 ,
-l fn, --log=fn Log output to the specified filename fn .
MariaDB 10.1.26

1285/3812
-m num, --
Leaf page count if merge given number of consecutive pages. MariaDB 10.1.4
merge=#
Ignore the checksum verification. Until MariaDB 10.6, must be used with the -- MariaDB 10.2.2 ,
-n, --no-check
write option. MariaDB 10.1.26
-p num, --
Check only this page number (0-based).
page=#
-D, --page-
MariaDB 10.2.2 ,
type- Dump the page type info for each page in a tablespace.
MariaDB 10.1.26
dump=name
-S, --page- MariaDB 10.2.2 ,
Display a count of each page type in a tablespace
type-summary MariaDB 10.1.26
-i, --per-page-
Print out per-page detail information.
details
-u, --skip-
Skip corrupt pages. MariaDB 10.0.16
corrupt
-s num, --
Start at this page number (0-based).
start-page=#
Added MariaDB
Specify the strict checksum algorithm. One of: crc32, innodb, none. If not 10.2.2 , MariaDB
-C, --strict-
specified, validates against innodb, crc32 and none. See also 10.1.26
check=name
innodb_checksum_algorithm. Removed MariaDB
10.6.0
-v, --verbose Verbose mode; print a progress indicator every five seconds.
-V, --version Displays version information and exits.
Added MariaDB
Rewrite the checksum algorithm. One of crc32, innodb, none. An exclusive lock 10.2.2 , MariaDB
-w, --
is obtained during use. Use in conjunction with the -no-check option to rewrite 10.1.26
write=name
an invalid checksum. Removed MariaDB
10.6.0

Examples
Rewriting a crc32 checksum to replace an invalid checksum:

innochecksum --no-check --write crc32 tablename.ibd

A count of each page type:

1286/3812
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

1.3.13 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 utility to make the function name substitutions.

1.3.14 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
1287/3812
Option Description
-c , --config- Deprecated, please use --defaults-file instead. Name of config file to read; if no extension is
file=name given, default extension (e.g., .ini or .cnf) will be added.
In debug versions, write a debugging log. A typical debug_options string is d:t:o,file_name .
-# , --debug[=#]
The default is d:t:o,/tmp/my_print_defaults.trace .
-c, --defaults- Like --config-file, except: if first option, then read this file only, do not read global or per-user
file=name config files; should be the first option. Removed in MariaDB 10.8.0.
-e , --defaults- Read this file after the global config file and before the config file in the users home directory;
extra-file=name should be the first option. Removed in MariaDB 10.8.0.
-g , --defaults-
In addition to the given groups, read also groups with this suffix. Removed in MariaDB 10.8.0.
group-suffix=name

-e , --extra-
Deprecated. Synonym for --defaults-extra-file.
file=name

--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

mysqlcheck reads from the [mysqlcheck] and [client] sections, so the following would display the mysqlcheck options.

my_print_defaults mysqlcheck client

1.3.15 mysqladmin
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-admin is a symlink to mysqladmin .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-admin is the name of the script, with mysqladmin a symlink .

Contents
1. Using mysqladmin
1. Options
2. Option Files
1. Option Groups
2. mysqladmin Variables
3. The shutdown Command and the --wait-
for-all-slaves Option
4. Examples
1. Other Ways To Stop mysqld (Unix)
5. See Also

mysqladmin 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)

1288/3812
Using mysqladmin
The command to use mysqladmin and the general syntax is:

mysqladmin [options] command [command-arg] [command [command-arg]] ...

Options
mysqladmin supports the following options:

Option Description Added


--character-sets-
Directory where the character set files are located.
dir=name

Compress all information sent between the client and the server if both support
-C , --compress
compression.
Maximum time in seconds before connection timeout. The default value is 43200
--connect_timeout=val
(12 hours).
-c val , --count=val Number of iterations to make. This works with -i ( --sleep ) only.
--
Write a debugging log. A typical debug_options string is d:t:o,file_name . The
debug[=debug_options] ,
default is d:t:o,/tmp/mysqladmin.trace .
-# [debug_options]

--debug-check Check memory and open file usage at exit.


Print debugging information and memory and CPU usage statistics when the
--debug-info
program exits.
--default-auth=plugin Default authentication client-side plugin to use.
--default-character-
Set the default character set.
set=name

Don't ask for confirmation on drop database; with multiple commands, continue
-f , --force
even if an error occurs.
-? , --help Display this help and exit.
-h name , --host=name Hostname to connect to.
MariaDB
Suppress the SQL command(s) from being written to the binary log by enabling 10.2.5
sql_log_bin=0 for the session, or, from MariaDB 10.2.7 and MariaDB 10.1.24 ,
-l , --local
, for flush commands only, using FLUSH LOCAL rather than SET MariaDB
sql_log_bin=0 , so the privilege requirement is RELOAD rather than SUPER. 10.1.22

-b , --no-beep Turn off beep on error.


-p[password] , -- Password to use when connecting to server. If password is not given it's asked
password[=password] 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 number to use for connection, or 0 for default to, in order of preference,
port=portnum my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default (3306).
--protocol=name The protocol to use for connection (tcp, socket, pipe, memory).
Show difference between current and previous values when used with -i .
-r , --relative
Currently only works with extended-status.
-O value , --set- Change the value of a variable. Please note that this option is deprecated; you
variable=vaue can set variables directly with --variable-name=value .
-- Maximum number of seconds to wait for server shutdown. The default value is
shutdown_timeout=val 3600 (1 hour).
-s , --silent Silently exit if one can't connect to server.
Execute commands repeatedly, sleeping for delay seconds in between. The --
-i delay , --
count option determines the number of iterations. If --count is not given,
sleep=delay
mysqladmin executes commands indefinitely until interrupted.

1289/3812
-S name , -- For connections to localhost, the Unix socket file to use, or, on Windows, the
socket=name name of the named pipe to use.
Enables TLS. TLS is also enabled even without setting this option when certain
other TLS options are set. Starting with MariaDB 10.2, the --ssl option will not
--ssl
enable verifying the server certificate by default. In order to verify the server
certificate, the user must specify the --ssl-verify-server-cert option.
Defines a path to a PEM file that should contain one or more X509 certificates
for trusted Certificate Authorities (CAs) to use for TLS. This option requires that
--ssl-ca=name you use the absolute path, not a relative path. See Secure Connections
Overview: Certificate Authorities (CAs) for more information. This option implies
the --ssl 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) to use
for TLS. 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 command. See Secure Connections Overview: Certificate
--ssl-capath=name 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 for more information about which libraries are used
on which platforms. This option implies the --ssl option.

Defines a path to the X509 certificate file to use for TLS. This option requires
--ssl-cert=name that you use the absolute path, not a relative path. This option implies the --
ssl option.

List of permitted ciphers or cipher suites to use for TLS. This option implies the
--ssl-cipher=name
--ssl option.

Defines a path to a PEM file that should contain one or more revoked X509
certificates to use for TLS. This option requires that you use the absolute path,
not a relative path. See Secure Connections Overview: Certificate Revocation
--ssl-crl=name 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 for more information about which libraries are used on which platforms.
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. 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 command. See
--ssl-crlpath=name Secure Connections Overview: 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 for more
information about which libraries are used on which platforms.

Defines a path to a private key file to use for TLS. This option requires that you
--ssl-key=name
use the absolute path, not a relative path. This option implies the --ssl option.
--ssl-verify-server-
Enables server certificate verification. This option is disabled by default.
cert

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 MariaDB
--tls-version=name
protocol versions will not be permitted. See Secure Connections Overview: TLS 10.4.6
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.
If the connection cannot be established, wait and retry instead of aborting. If a
-w[count] , --
count value is given, it indicates the number of times to retry. The default is one
wait[=count]
time.
Wait for the last binlog event to be sent to all connected replicas before shutting MariaDB
--wait-for-all-slaves
down. This option is off by default. 10.4.4

1290/3812
Option Files
In addition to reading options from the command-line, mysqladmin can also read options from option files. If an
unknown option is provided to mysqladmin 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 and later, mysqladmin is linked with MariaDB Connector/C . 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 for more information.

Option Groups
mysqladmin reads options from the following option groups from option files:

Group Description
[mysqladmin] Options read by mysqladmin , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysqladmin . Available starting with MariaDB 10.4.6.
admin]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and MySQL
[client]
clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

mysqladmin 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)

1291/3812
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

mysqladmin Commands
mysqladmin [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 Added


create
Create a new database.
databasename

debug Instruct server to write debug information to log.


drop
Delete a database and all its tables.
databasename

extended-
Return all status variables and their values.
status

flush-all-
Flush all statistics tables
statistics

flush-all-
Flush status and statistics.
status

MariaDB
10.1.25
flush-
Flush binary log. ,
binary-log
MariaDB
10.2.5
flush-
client- Flush client statistics.
statistics

MariaDB
10.1.25
flush-
Flush engine log. ,
engine-log
MariaDB
10.2.5
MariaDB
10.1.25
flush-error-
Flush error log. ,
log
MariaDB
10.2.5
MariaDB
10.1.25
flush-
Flush general query log. ,
general-log
MariaDB
10.2.5
flush-hosts Flush all cached hosts.
flush-index-
statistics Flush index statistics.

flush-logs Flush all logs.


1292/3812
flush-
Reload grant tables (same as reload).
privileges

MariaDB
10.1.25
flush-relay-
Flush relay log. ,
log
MariaDB
10.2.5
flush-slow-
Flush slow query log.
log

MariaDB
flush-ssl Flush SSL certificates.
10.6.0
flush-
Clear status variables.
status

flush-table-
Clear table statistics.
statistics

flush-
Flush all tables.
tables

flush-
Flush the thread cache.
threads

MariaDB
10.1.25
flush-user-
Flush user resources. ,
resources
MariaDB
10.2.5
flush-user-
Flush user statistics.
statistics

kill
Kill mysql threads.
id,id,...

Change old password to new-password. The new password can be passed on the
commandline as the next argument (for example, mysqladmin password "new_password" ,
or can be omitted (as long as no other command follows), in which case the user will be
password
prompted for a password. If the password contains special characters, it needs to be
new-password
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 option, changing the password in this way will have no effect.
old-password
Change old password to new-password using the old pre-MySQL 4.1 format.
new-password

Check if mysqld is alive. Return status is 0 if the server is running (even in the case of an
ping
error such as access denied), 1 if it is not.
Show list of active threads in server, equivalent to SHOW PROCESSLIST. With --
processlist
verbose , equivalent to SHOW FULL PROCESSLIST.

reload Reload grant tables.


refresh Flush all tables and close and open log files.
Take server down by executing the SHUTDOWN command on the server. If connected to
a local server using a Unix socket file, mysqladmin waits until the server's process ID file
shutdown
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-
Start all replicas.
slaves

start-slave Start replication on a replica server.


stop-all-
Stop all replicas.
slaves

stop-slave Stop replication on a replica server.


variables Prints variables available.
version Returns version as well as status info from the server.

1293/3812
The shutdown Command and the --wait-for-all-slaves
Option
MariaDB starting with 10.4.4
The --wait-for-all-slaves option was first added in MariaDB 10.4.4.

When a master server is shutdown and it goes through the normal shutdown process, the master kills client threads in
random order. By default, the master 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 master during a normal shutdown that won't be replicated. This is true even if semi-synchronous
replication is being used.
In MariaDB 10.4 and later, this problem can be solved by shutting down the server with the mysqladmin utility and by
providing the --wait-for-all-slaves option to the utility and by executing the shutdown command with the utility. For
example:

mysqladmin --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 has been sent to all connected
replicas.
See Replication Threads: Binary Log Dump Threads and the Shutdown Process for more information.

Examples
Quick check of what the server is doing:

shell> mysqladmin 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> mysqladmin 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> mysqladmin --relative --sleep=1 extended-status | grep -v " 0 "

Check the variables for a running server:

shell> mysqladmin variables | grep datadir


| datadir | /my/data/ |

Using a shortened prefix for the version command:

shell> mysqladmin ver


mysqladmin Ver 9.1 Distrib 10.1.6-MariaDB, for debian-linux-gnu on x86_64
Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Server version 10.1.6-MariaDB-1~trusty-log


Protocol version 10
Connection Localhost via UNIX socket
UNIX socket /var/run/mysqld/mysqld.sock
Uptime: 1 hour 33 min 33 sec

Threads: 1 Questions: 281 Slow queries: 0 Opens: 64 Flush tables: 1 Open tables: 76 Queries per second
avg: 0.050

Other Ways To Stop mysqld (Unix)


If you get the error:

mysqladmin: shutdown failed; error: 'Access denied; you need (at least one of) the SHUTDOWN
privilege(s) for this operation'

1294/3812
It means that you didn't use mysqladmin 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 mysqladmin shutdown .


On windows you should use:

NET STOP MySQL

You can use the SHUTDOWN command from any client.

See Also
SHUTDOWN command
mytop , 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

1.3.16 mysqlaccess
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-access is a symlink to mysqlaccess .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-access is the name of the tool, with mysqlaccess a symlink .

Contents
1. Usage
2. Options
3. Note

mysqlaccess 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 mysqlaccess checks
access using only the user, db, and host tables. It does not check table, column, or routine privileges specified in the
tables_priv, columns_priv, or procs_priv tables.

Usage
mysqlaccess [host [user [db]]] OPTIONS

If your MariaDB distribution is installed in some non-standard location, you must change the location where
mysqlaccess expects to find the mysql client. Edit the mysqlaccess script at approximately line 18. Search for a line that
looks like this: <<code> $MYSQL = ´/usr/local/bin/mysql´; # path to mysql executable <</code>> Change the path to
reflect the location where mysql actually is stored on your system. If you do not do this, a Broken pipe error will occur
when you run mysqlaccess.

Options
Option Description
-? , --help Displayhelp and exit.
-v , --version Display version.
-u username , --
Username for logging in to the db.
user=username

-p[password] , --
Password to use for user. If ommitted, mysqlaccess prompts for one.
password[=password]

-h hostname , --
Name or IP of the host.
host=hostname

1295/3812
-d dbname , --db=dbname Name of the database.

-U username , --
Connect as superuser.
superuser=username

-P password , --
Password for superuser.
spassword=password

-H server , --
Remote server to connect to.
rhost=server

Connect to a very old MySQL servers (before version 3.21) that does not know how to
--old_server
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 `mysqlaccess'.
--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.
Copy grant-rules from temporary tables to grant-tables (the grant tables must be flushed
--commit
after, for example with mysqladmin reload ).
--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 '*')

1.3.17 mysqlbinlog
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-binlog is a symlink to mysqlbinlog .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-binlog is the name of the tool, with mysqlbinlog a symlink .

mysqlbinlog is a utility included with MariaDB for processing binary log and relay log 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 mysqlbinlog utility is
used to view these events in plain text.
Using mysqlbinlog
Viewing the binary log with mysqlbinlog.

mysqlbinlog Options
Options supported by mysqlbinlog.

Annotate_rows_log_event
1 Annotate_rows events accompany row events and describe the query which caused the row event.

mariadb-binlog
Symlink or new name for mysqlbinlog.

There are 3 related questions .

1296/3812
1.3.17.1 Using mysqlbinlog
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-binlog is a symlink to mysqlbinlog .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-binlog is the name of the tool, with mysqlbinlog a symlink .

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 mysqlbinlog utility is
used to view these events in plain text.
Run mysqlbinlog from a command-line like this:

shell> mysqlbinlog [options] log_file ...

See mysqlbinlog Options for details on the available options.


As an example, here is how you could display the contents of a binary log file named "mariadb-bin.000152":

shell> mysqlbinlog 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 mysqlbinlog can be used as input to the mysql client to redo the statements contained in a binary log.
This is useful for recovering after a server crash. Here is an example:

shell> mysqlbinlog 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> mysqlbinlog -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> mysql -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 mysql 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 mysqlbinlog command line:

shell> mysqlbinlog mariadb-bin.000001 mariadb-bin.000002 | mysql -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> mysqlbinlog mariadb-bin.000001 > /tmp/mariadb-bin.sql


shell> mysqlbinlog 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 Options

1.3.17.2 mysqlbinlog Options


1297/3812
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-binlog is a symlink to mysqlbinlog .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-binlog is the name of the tool, with mysqlbinlog a symlink .

Contents
1. Options
2. Option Files
1. Option Groups
3. See Also

mysqlbinlog is a utility included with MariaDB for processing binary log and relay log files.

Options
The following options are supported by mysqlbinlog. They can be specified on the command line or in option files:
Option default value Description Introduced
-? , --help Display a help statement.
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 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
--base64-output=name experience with large binary log files, as the raw data will be omitted.
(>= MariaDB 10.6.1, auto Unlike never, mysqlbinlog will not exit with an error if a row event is
MariaDB 10.5.11) found. auto (synonymous with unspec) outputs base64 encoded
entries for row-based 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.
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; decode-rows
decodes row events into commented SQL statements if the --verbose
option is also given; Unlike never, mysqlbinlog does not exit with an
--base64- error if a row event is found auto or unspec , the default, prints
output[=name] (<= base64 only when necessary (i.e., for row-based events and format
(No default Value)
MariaDB 10.6.0, description events), and is the only safe behavior if you intend to use
MariaDB 10.5.10) the output of mysqlbinlog 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- The maximum size in bytes of a row-based binary log event. Should be
4294967040 (4GB)
max-size=val a multiple of 256. Minimum 256, maximum 18446744073709547520.
--character-sets-
(No default value) Directory where the character sets are.
dir=name

Output entries from the binary log (local log only) that occur while name
has been selected as the default database by USE. Only one database
can be specified. The effects depend on whether the statement-based
or row-based logging format is in use. For statement-based logging, the
-d , --database=name (No default value)
server will only log statements where the default database is name. The
default database is set with the USE 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] , -- In a debug build, write a debugging log. A typical debug options string is
d:t:o,/tmp/mysqlbinlog.trace
debug[=options] 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- Read the file name, which can be the full path, or the path relative to
file=name the current directory, after the global files are read.

1298/3812
Only read default options from the given file
--defaults-file=name name
, which can be the full path, or the path relative to the current directory.
Also read groups with a suffix of str. For example, since mysqlbinlog
--defaults-group- normally reads the [client] and [mysqlbinlog] groups, --defaults-
suffix=str group-suffix=x would cause it to also read the groups [mysqlbinlog_x]
and [client_x].
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
-D , --disable-log-
FALSE avoid an endless loop. You would also like to use it when restoring after
bin
a crash to avoid duplication of the statements you already have. NOTE:
you will need a SUPER privilege to use this option.
A list of positive integers, separated by commas, that form a whitelist of
domain ids. Any log event with a GTID that originates from a domain id
MariaDB
--do-domain-ids=name (No default value) specified in this list is displayed. Cannot be used with --ignore-
10.9.0
domain-ids . When used with --ignore-server-ids or --do-server-
ids , the result is the intersection between the two datasets

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
MariaDB
--do-server-ids=name (No default value) is displayed. Cannot be used with --ignore-server-ids . When used
10.9.0
with --ignore-domain-ids or do-domain-ids , the result is the
intersection between the two datasets. Alias for --server-id .
MariaDB
-B , --flashback FALSE Support flashback mode.
10.2.4
Force if binlog was not closed properly. Defaults to ON; use --skip-
-F , --force-if-open TRUE
force-if-open to disable.

If mysqlbinlog reads a binary log event that it does not recognize, it


-f , --force-read FALSE prints a warning, ignores the event, and continues. Without this option,
mysqlbinlog stops if it reads such an event.
Process binlog according to gtid-strict-mode specification. The start,
stop positions are verified to satisfy start < stop comparison condition.
MariaDB
--gtid-strict-mode TRUE Sequence numbers of any gtid domain must comprise monotically
10.8.0
growing sequence, Defaults to on; use --skip-gtid-strict-mode to
disable.
-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.
A list of positive integers, separated by commas, that form a blacklist of
domain ids. Any log event with a GTID that originates from a domain id
--ignore-domain- MariaDB
(No default value) specified in this list is hidden. Cannot be used with --do-domain-ids .
ids=name 10.9.0
When used with --ignore-server-ids or --do-server-ids , the result
is the intersection between the two datasets.
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
--ignore-server- MariaDB
(No default value) is hidden. Cannot be used with --do-server-ids . When used with --
ids=name 10.9.0
ignore-domain-ids or --do-domain-ids , the result is the intersection
between the two datasets.
-l path , --local- Prepare local temporary files for LOAD DATA INFILE in the specified
(No default value)
load=path directory. The temporary files are not automatically removed.
--no-defaults Don't read default options from any option file
-o value , --
0 Skip the first value entries in the log.
offset=value

--open_files_limit=# 64 Reserve file descriptors for usage by mysqlbinlog.


Password to connect to the remote server. The password can be
-p[passwd] , -- omitted allow it be entered from the prompt, or an option file can be
(No default value)
password[=passwd] used to avoid the security risk of passing a password on the
commandline.
--plugin-
Directory for client-side plugins.
dir=dir_name ,

Port number to use for connection or 0 for default to, in order of


-P num , --port=num 0 preference, my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default
(3306).
--position=# 4 Removed in MariaDB 5.5. Use --start-position instead.
--print-defaults Print the program argument list from all option files and exit.
Print row counts for each row events. (Defaults to on; use --skip-
--print-row-count TRUE MariaDB 10.3
print-row-count to disable.)

--print-row-event- Print row event positions. Defaults to on; use --skip-print-row-event-


TRUE MariaDB 10.3
positions positions to disable.)

MariaDB
print-table-metadata Print metadata stored in Table_map_log_event.
10.5.0
--protocol=name (No default value) The protocol of the connection (tcp,socket,pipe,memory).
Requires -R. Output raw binlog data instead of SQL statements. Output MariaDB
--raw
files named after server logs. 10.2.0

1299/3812
Read binary logs from a remote MariaDB server rather than reading a
local log file. Any connection parameter options are ignored unless this
-R , --read-from- option is given as well. These options are --host , --password , --
FALSE
remote-server 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-
(No default value) Direct output to a given file. With --raw this is a prefix for the file names.
file=name

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 ".
--rewrite-db=name (No default value)
Row-based events are rewritten correctly to use the new database
name.

Filtering (e.g. with --database=name ) happens after 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" ).

Extract only binlog entries created by the server having the given id.
--server-id=idnum 0
From MariaDB 10.9.0, alias for --do-server-ids.
--set- Add ' SET NAMES character_set ' to the output to specify the character
(No default value)
charset=character_set set to be used for processing log files.
Shared-memory name to use for Windows connections using shared
--shared-memory-base-
MYSQL memory to a local server (started with the --shared-memory option).
name=name
Case-sensitive.
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
-s , --short-form FALSE
want to suppress base64-output, consider using --base64-
output=never instead.

Skip all Annotate_rows events in the mysqlbinlog output (by default,


--skip-annotate-row-
mysqlbinlog prints Annotate_rows events, if the binary log does contain
events
them).
For connections to localhost, the Unix socket file to use, or, on
-S , --socket=name (No default value)
Windows, the name of the named pipe to use.
Enables TLS. TLS is also enabled even without setting this option when
certain other TLS options are set. Starting with MariaDB 10.2, the --
--ssl FALSE ssl option will not enable verifying the server certificate by default. In
order to verify the server certificate, the user must specify the --ssl-
verify-server-cert option.

Defines a path to a PEM file that should contain one or more X509
certificates for trusted Certificate Authorities (CAs) to use for TLS. This
--ssl-ca=name option requires that you use the absolute path, not a relative path. See
Secure Connections Overview: Certificate Authorities (CAs) for more
information. This option implies the --ssl 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) to use for TLS. 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 command. See
--ssl-capath=name Secure Connections Overview: 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 for more information about which libraries are used on
which platforms. This option implies the --ssl option.
Defines a path to the X509 certificate file to use for TLS. This option
--ssl-cert=name requires that you use the absolute path, not a relative path. This option
implies the --ssl option.
List of permitted ciphers or cipher suites to use for TLS. This option
--ssl-cipher=name
implies the --ssl option.
Defines a path to a PEM file that should contain one or more revoked
X509 certificates to use for TLS. This option requires that you use the
absolute path, not a relative path. See Secure Connections Overview:
Certificate Revocation Lists (CRLs) for more information. This option is
--ssl-crl=name
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 for more
information about which libraries are used on which platforms.

1300/3812
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. 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 command. See Secure Connections Overview: Certificate
--ssl-crlpath=name
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 for more information
about which libraries are used on which platforms.
Defines a path to a private key file to use for TLS. This option requires
--ssl-key=name that you use the absolute path, not a relative path. This option implies
the --ssl option.
--ssl-verify-server-
FALSE Enables server certificate verification. This option is disabled by default.
cert

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
--start- time zone, in any format accepted by the MariaDB server for DATETIME
(No default value)
datetime=datetime and TIMESTAMP 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.
Start reading the binlog at this position. Type can either be a positive
integer or, from MariaDB 10.8.0, a GTID 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
-j pos , --start-
4 comma separated list, where each must have a unique domain id. The
position=pos
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 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
--stop-datetime=name (No default value)
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.
Wait for more data from the server instead of stopping at the end of the MariaDB
--stop-never
last log. Implies --to-last-log . 10.2.0
--stop-never-slave- The slave server_id used for --read-from-remote-server --stop- MariaDB
server-id never . 10.2.0
Stop reading the binlog at this position. Type can either be a positive
integer or, from MariaDB 10.8, a GTID list. When using a positive
integer, the value only applies to the last binlog passed on the
--stop-position=pos 18446744073709551615 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.
MariaDB
-T , --table List entries for just this table (local log only).
10.2.4
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 MariaDB
--tls-version=name TLSv1.1,TLSv1.2,TLSv1.3
other TLS protocol versions will not be permitted. See Secure 10.4.6
Connections Overview: TLS Protocol Versions for more information.
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
-t , --to-last-log FALSE
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.
Reconstruct SQL statements out of row events. -v -v adds comments on
-v , --verbose
column data types
-V , --version Print version and exit.
--verify-binlog-
Verify binlog event checksums when reading a binlog file.
checksum

Option Files
In addition to reading options from the command-line, mysqlbinlog can also read options from option files. If an
unknown option is provided to mysqlbinlog 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.


1301/3812
--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 and later, mysqlbinlog is linked with MariaDB Connector/C . 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 for more information.

Option Groups
mysqlbinlog reads options from the following option groups from option files:

Group Description
[mysqlbinlog] Options read by mysqlbinlog , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysqlbinlog . Available starting with MariaDB 10.4.6.
binlog]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and
[client]
MySQL clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

In MariaDB 10.2 and later, mysqlbinlog is linked with MariaDB Connector/C . 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 for more information.

See Also
Using mysqlbinlog

1.3.17.3 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 has begun the process of renaming. The documentation process is ongoing. See MDEV-
18777 to follow progress on this effort.

Contents
1. Annotate_rows Example
2. Options Related to
Annotate_rows_log_event
1. Master Option: --binlog-annotate-row-
events
2. Slave Option: --replicate-annotate-
row-events
3. mysqlbinlog Option: --skip-annotate-
row-events
3. Example of mysqlbinlog Output
4. See Also

Annotate_rows events accompany row events and describe the query which caused the row event.

Until MariaDB 10.2.4 , 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 to MySQL/MariaDB 5.1). You can enable this with --
binlog-annotate-row-events .

In the binary log, 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;
1302/3812
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
|
+-------------------+------+---------------+-----------+-------------+---------------------------------
------------------------------------------------+

1303/3812
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 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 for a detailed description of the variable.

mysqlbinlog Option: -- skip-annotate-row-events


This option tells mysqlbinlog to skip all Annotate_row events in its output (by default, mysqlbinlog prints Annotate_row
events, if the binary log contains them).

Example of mysqlbinlog Output


...> mysqlbinlog.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/*!*/; 1304/3812
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
1305/3812
#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
1306/3812
### 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 mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

See Also
mysqlbinlog Options
Replication and Binary Log Server System Variables
Full List of MariaDB Options, System and Status Variables
mysqld Options
What is MariaDB 5.3

1.3.17.4 mariadb-binlog
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-binlog is a symlink to mysqlbinlog .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-binlog is the name of the tool, with mysqlbinlog a symlink .

See mysqlbinlog for details.

1.3.18 mysqlcheck
1.3.19 mysql_convert_table_format
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-convert-table-format is a symlink to mysql_convert_table_format .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-convert-table-format is the name of the tool, with mysql_convert_table_format a
symlink .

Usage
mysql_convert_table_format [options] db_name

Contents
1. Usage
2. Description
3. Options

Description
mysql_convert_table_format converts the tables in a database to use a particular storage engine (MyISAM by default).
mysql_convert_table_format is written in Perl and requires that the DBI and DBD::mysql Perl modules be installed
Invoke mysql_convert_table_format like this:

shell> mysql_convert_table_format [options]db_name

1307/3812
The db_name argument indicates the database containing the tables to be converted.

Options
mysql_convert_table_format supports the options described in the following list:

Option Description
--help Display a help message and exit.
--force Continue even if errors occur.
--host=host_name Connect to the MariaDB server on the given host.
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
password=password
command-line is generally considered insecure.
--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.
Specify the storage engine that the tables should be converted to use. The default is MyISAM if
--type=engine_name
this option is not given.
--user=user_name The MariaDB user name to use when connecting to the server.
--verbose Verbose mode. Print more information about what the program does.
--version Display version information and exit.

1.3.20 mysqldumpslow
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-dumpslow is a symlink to mysqldumpslow .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-dumpslow is the name of the tool, with mysqldumpslow a symlink .

Contents
1. Usage
2. Options

mysqldumpslow is a tool to examine the slow query log.

It parses the slow query log files, printing a summary result. Normally, mysqldumpslow 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
mysqldumpslow [ 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


1308/3812
-n NUM Abstract numbers with at least NUM digits within names
-r Reverse the sort order (largest last instead of first)
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
-s ORDER
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.

1.3.21 mysql_embedded
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-embedded is a symlink to mysql_embedded .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-embedded is the name of the tool, with mysql_embedded a symlink.

mysql_embedded is a mysql client statically linked to libmysqld, the embedded server. Upon execution, an embedded
MariaDB server is instantiated and you can execute statements just as you would using the normal mysql client, using
the same options.

Do not run mysql_embedded while MariaDB is running, as effectively it starts a new instance of the server.

Examples
sudo mysql_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 mysql_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

1309/3812
1.3.22 mysql_find_rows
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-find-rows is a symlink to mysql_find_rows .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-find-rows is the name of the binary, with mysql_find_rows a symlink .

Contents
1. Usage
2. Options
3. Examples

mysql_find_rows reads files containing SQL statements and extracts statements that match a given regular expression
or that contain USE db_name or SET 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
mysql_find_rows [options] [file_name ...]

Each file_name argument should be the name of file containing SQL statements. If no file names are given,
mysql_find_rows reads the standard input.

Options
mysql_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 statements in the output.
--start_row=N Start output from this row (first row is 1).

Examples
mysql_find_rows --regexp=problem_table --rows=20 < update.log
mysql_find_rows --regexp=problem_table update-log.1 update-log.2

1.3.23 mysql_fix_extensions
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-fix-extensions is a symlink to mysql_fix_extensions .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_fix_extensions is the symlink, and mariadb-fix-extensions the binary name.

mysql_fix_extensions converts the extensions for MyISAM (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 mysql_fix_extensions as follows, where data_dir is the path name to the MariaDB data directory.

1310/3812
mysql_fix_extensions data_dir

1.3.24 mysql_install_db
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-install-db is a symlink to mysql_install_db .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_install_db is the symlink, and mariadb-install-db the binary name.

This page is for the mysql_install_db script for Linux/Unix only


For the Windows specific tool of similar name and purpose see mysql_install_db.exe.
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.

Contents
1. Using mysql_install_db
1. Options
2. Option Files
1. Option Groups
2. Installing System Tables
1. Installing System Tables From a
Source Tree
2. Installing System Tables From a
Binary Tarball
3. User Accounts Created by Default
4. Troubleshooting Issues
1. Checking the Error Log
2. Testing With mysqld
5. Using a Server Compiled With --disable-
grant-options
6. The test and test_% Databases
1. Not Creating the test Database and
Anonymous User
7. See Also

mysql_install_db initializes the MariaDB data directory and creates the system tables in the mysql database, if they
do not exist. MariaDB uses these tables to manage privileges, roles, and plugins. It also uses them to provide the data
for the help command in the mysql client.
mysql_install_db works by starting MariaDB Server's mysqld process in --bootstrap mode and sending commands
to create the system tables and their content.

Using mysql_install_db
To invoke mysql_install_db , use the following syntax:

$ mysql_install_db [options]

Because the MariaDB server, mysqld , needs to access the data directory when it runs later, you should either run
mysql_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 mysql_install_db does not use the correct locations for the installation directory or data
directory. For example:

$ scripts/mysql_install_db --user=mysql \
--basedir=/opt/mysql/mysql \
--datadir=/opt/mysql/mysql/data

Options
1311/3812
mysql_install_db supports the following options:

Option Description
If set to normal , it creates a root@localhost account that authenticates with the
--auth-root- mysql_native_password authentication plugin and that has no initial password set, which can be
authentication- insecure. If set to socket , it creates a root@localhost account that authenticates with the
method={normal unix_socket authentication plugin. Set to socket by default from MariaDB 10.4 (see
| socket} Authentication from MariaDB 10.4), or normal by default in earlier versions. Available since
MariaDB 10.1.
--auth-root- Used with --auth-root-authentication-method=socket . It specifies the name of the second
socket- account to create with SUPER privileges in addition to root , as well as of the system account
user=USER allowed to access it. Defaults to the value of --user .
--
The path to the MariaDB installation directory.
basedir=path

-- If using --srcdir with out-of-directory builds, you will need to set this to the location of the build
builddir=path directory where built files reside.
--cross-
For internal use. Used when building the MariaDB system tables on a different host than the target.
bootstrap

--
datadir=path , The path to the MariaDB data directory.
--ldata=path

--defaults-
extra- Read this file after the global files are read. Must be given as the first option.
file=name

--defaults-
Only read default options from the given file name Must be given as the first option.
file=name

--defaults-
In addition to the given groups, read also groups with this suffix. From MariaDB 10.1.31 ,
group-
MariaDB 10.2.13 and MariaDB 10.3.5.
suffix=name

Causes mysql_install_db to run even if DNS does not work. In that case, grant table entries that
--force
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-
Print the program argument list and exit. Must be given as the first option.
defaults

--rpm For internal use. This option is used by RPM files during the MariaDB installation process.
--skip-auth-
Do not create the anonymous user.
anonymous-user

--skip-name- Uses IP addresses rather than host names when creating grant table entries. This option can be
resolve useful if your DNS does not work.
--skip-test-
Don't install the test database.
db

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
--srcdir=path
want to create the system tables. The directory under which mysql_install_db looks for support
files such as the error message file and the file for populating the help tables.

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
user=user_name
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, mysql_install_db can also read options from option files. If an
unknown option is provided to mysql_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:

1312/3812
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
mysql_install_db reads options from the following option groups from option files:

Group Description
[mysql_install_db] Options read by mysqld_safe , which includes both MariaDB Server and MySQL Server.

mysql_install_db also reads options from the following server option groups from option files:

Group Description
[mysqld] Options read by mysqld , which includes both MariaDB Server and MySQL Server.
[server] Options read by MariaDB Server.
[mysqld- Options read by a specific version of mysqld , which includes both MariaDB Server and MySQL Server.
X.Y] For example, [mysqld-5.5] .
[mariadb] Options read by MariaDB Server.
[mariadb-
Options read by a specific version of MariaDB Server.
X.Y]

[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] 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, and if you want to use mysql_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/mysql_install_db --srcdir=. --datadir=path-to-temporary-data-dir

Installing System Tables From a Binary Tarball


If you install a binary tarball 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. For example:

./scripts/mysql_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. For
example:

./scripts/mysql_install_db --defaults-file=~/.my.cnf

User Accounts Created by Default


MariaDB starting with 10.4
In MariaDB 10.4 and later, mysql_install_db sets --auth-root-authentication-method=socket by default. When
1313/3812
this is set, the default root@localhost user account is created with the ability to use two authentication plugins:
First, it is configured to try to use the unix_socket authentication plugin. This allows the the root@localhost
user to login without a password via the local Unix socket file defined by the 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, then it is configured to try to use the
mysql_native_password 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 mysql_install_db sets --auth-root-authentication-method=socket by default, the following additional user


accounts are not created by default:
[email protected]
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 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 mysql
...
MariaDB> SET PASSWORD = PASSWORD('XH4VmT3_jt');

You may notice in the above example that the mysql command-line client is executed via sudo . This allows the
root@localhost user account to successfully authenticate via the unix_socket authentication plugin.

MariaDB until 10.3


In MariaDB 10.3 and before, mysql_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
[email protected]
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 statement or by running mysql_secure_installation .
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 mysql_install_db sets --auth-root-authentication-method=normal by default, the --auth-root-socket-


1314/3812
user option is ignored by default.

Troubleshooting Issues
Checking the Error Log
If mysql_install_db fails, you should examine the error log 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 option will tell it to ignore the system tables. Enabling the general query log 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 mysql client to connect to the mysql database and look at the system tables. 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:

mysql_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 . mysql_install_db will use that server.

The test and test_% Databases


When calling the mysql_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 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:

1315/3812
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
+--------------------+
| 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 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 table. Looking at the
mysql.db table, it already contains 2 rows created when the mysql_install_db script was invoked.
1316/3812
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
mysql_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 mysql_install_db with the --skip-test-db option, no test database will be created, which we can see as
follows:

1317/3812
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
Installing system tables (mysql_install_db)
The Windows version of mysql_install_db : mysql_install_db.exe

1.3.25 mysql_plugin
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-plugin is a symlink to mysql_plugin .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_plugin is the symlink, and mariadb-plugin the binary name.

Contents
1. Usage
2. Options
3. See Also

mysql_plugin is a tool for enabling or disabling plugins.


It is a commandline alternative to the INSTALL PLUGIN and UNINSTALL PLUGIN statements, and the --plugin-load
option to mysqld.
mysql_plugin must be run while the server is offline, and works by adding or removing rows from the mysql.plugin
table.
mysql_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 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 mysql_plugin can be the only viable action though.

Usage
mysql_plugin [options] <plugin> ENABLE|DISABLE

mysql_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:

mysql_plugin crazyplugins ENABLE

1318/3812
Here, mysql_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-
Path to my_print_defaults executable. Example: /source/temp11/extra
defaults=name

-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.
Read plugin information from configuration file specified instead of from <plugin-
-i , --plugin-ini=name
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
Plugin Overview
INFORMATION_SCHEMA.PLUGINS Table
INSTALL PLUGIN
INSTALL SONAME
UNINSTALL PLUGIN
UNINSTALL SONAME

1.3.26 mysqlreport
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-report is a symlink to mysqlreport .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysqlreport is the symlink, and mariadb-report the binary name.

Contents
1. Usage
2. mysqlreport options
3. Examples

mysqlreport 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, mysqlreport 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 at the mysqlreport web page at
http://hackmysql.com/mysqlreport .
1319/3812
The benefit of mysqlreport 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 mysqlreport, 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 at http://hackmysql.com/mysqlreportguide .

Usage
mysqlreport [options]

mysqlreport 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 .)
Print top N number of non-DMS Com_ status values in descending order (after DMS in Questions report).
--com N If N is not given, default is 3. Such non-DMS Com_ values include Com_change_db, Com_show_tables,
Com_rollback, etc.
Print Data Manipulation Statements (DMS) report (under DMS in Questions report). DMS are those from
--dms the Data Manipulation section. Currently, mysqlreport considers only SELECT, INSERT, REPLACE,
UPDATE, and DELETE. Each DMS is listed in descending order by count.
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
--dtq
COM_QUIT and Questions at http://hack‐mysql.com/com_quit ), and Unknown. --dtq lists the number
of queries in each of these areas in descending order.
After printing the report to screen, email the report to ADDRESS. This option requires sendmail in
--email /usr/sbin/, therefore it does not work on Windows. /usr/sbin/sendmail can be a sym link to qmail, for
ADDRESS example, or any MTA that emulates sendmail's -t command line option and operation. The FROM: field is
"mysqlreport", SUBJECT: is "MySQL status report".
--flush- Execute a FLUSH STATUS after generating the reports. If you do not have permissions in MariaDB to do
status this an error from DBD::mysql::st will be printed after the reports.
--help Output help information and exit.
--host
Host address.
ADDRESS

Instead of getting SHOW STATUS values from MariaDB, read values from FILE. FILE is often a copy of
the output of SHOW STATUS including formatting characters (+, -). mysqlreport 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. mysqlreport also needs
the following MariaDB server variables: version, table_cache, max_connections, key_buffer_size,
--infile query_cache_size. These values can be specified in INFILE in the format "name = value" where name is
FILE 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- Makes mysqlreport not read /.my.cnf which it does by default otherwise. --user and --password always
mycnf override values from /.my.cnf.
After printing the report to screen, print the report to FILE too. Internally, mysqlreport always writes the
--
report to a temp file first: /tmp/mysqlreport.PID on *nix, c:sqlreport.PID on Windows (PID is the
outfile
script's process ID). Then it prints the temp file to screen. Then if --outfile is specified, the temp file is
FILE
copied to OUTFILE. After --email (above), the temp file is deleted.
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 mysqlreport to prompt for a
password
password.

1320/3812
--port
Port number.
PORT

--
Print Query Cache report.
qcache

Print report for Select_ and Sort_ status values (after Questions report). See MySQL Select and Sort
--sas
Status Variables at http://hackmysql.com/selectandsort .
--socket For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to
SOCKET use.
Print Threads, Aborted, and Bytes status reports (after Created temp report). As of mysqlreport v2.3 the
--tab
Threads report reports on all Threads_ status values.
--user
Username.
USERNAME

Examples

1.3.27 mysql_secure_installation
Note that many of the reasons for the existence of this script no longer apply. In particular, from MariaDB 10.4, Unix
socket authentication is applied by default, and there is usually no need to create a root password. See
Authentication from MariaDB 10.4.

MariaDB starting with 10.4.6


From MariaDB 10.4.6, mariadb-secure-installation is a symlink to mysql_secure_installation .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_secure_installation is the symlink, and mariadb-secure-installation the binary
name.

Contents
1. Description
1. Options
2. Option Files
1. Option Groups
3. Use With Galera Cluster

Description
mysql_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.
mysql_secure_installation can be invoked without arguments:

shell> mysql_secure_installation

The script will prompt you to determine which actions to perform.

1321/3812
Example:
localhost:# mysql_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
mysql_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.

1322/3812
Other unrecognized options will be passed on to the server.

Option Files
In addition to reading options from the command-line, mysql_secure_installation can also read options from option
files. If an unknown option is provided to mysql_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
mysql_secure_installation reads options from the following option groups from option files:

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

Use With Galera Cluster


This script is not 100% safe for use with Galera Cluster as it directly manipulates the mysql.user/mysql.global_priv
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 .

1.3.28 mysql_setpermission
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-setpermission is a symlink to mysql_setpermission .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_setpermission is the symlink, and mariadb-setpermission the binary name.

Syntax
mysql_setpermission [options]

Description
mysql_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. mysql_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.
1323/3812
mysql_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.
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
password=password 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.

1.3.29 mysqlshow
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-show is a symlink to mysqlshow .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysqlshow is the symlink, and mariadb-show the binary name.

Contents
1. Using mysqlshow
1. Options
2. Option Files
1. Option Groups
2. Examples

Shows the structure of a MariaDB database (databases, tables, columns and indexes). You can also use SHOW
DATABASES, SHOW TABLES, SHOW COLUMNS, SHOW INDEX and SHOW TABLE STATUS, as well as the
Information Schema tables (TABLES, COLUMNS, STATISTICS), to get similar functionality.

Using mysqlshow
mysqlshow [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, mysqlshow 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
mysqlshow supports the following options:

Option Description

1324/3812
-c name , --
character-sets- Directory for character set files.
dir=name

-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 tables).
-# [name] , --
Output debug log. Typical is d:t:o,filename , the default is d:t:o .
debug[=name]

--debug-check Check memory and open file usage at exit.


--debug-info Print some debug info at exit.
--default-
Default authentication client-side plugin to use.
auth=name

--default-
Set the default character set.
character-set=name

--defaults-extra-
Read the file name after the global files are read. Must be given as the first option.
file=name

--defaults-
Only read default options from the given file name. Must be given as the first option.
file=name

--defaults-group-
In addition to the given groups, also read groups with this suffix.
suffix=suffix

-? , --help Display help and exit.


-h name , --
Connect to the MariaDB server on the given host.
host=name

-k , --keys Show indexes for table.


--no-defaults Don't read default options from any option file. Must be given as the first option.
Password to use when connecting to server. If password is not given, it's solicited on the
-p[password] , --
command line. Specifying a password on the command line should be considered insecure.
password[=password]
You can use an option file to avoid giving the password on the command line.
On Windows, connect to the server via a named pipe. This option applies only if the server
-W , --pipe
supports named-pipe connections.
--plugin-dir=name Directory for client-side plugins.
Port number to use for connection or 0 for default to, in order of preference, my.cnf,
-P num , --port=num
$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).
On Windows, the shared-memory name to use, for connections made using shared memory
--shared-memory- to a local server. The default value is MYSQL . The shared-memory name is case sensitive.
base-name=name The server must be started with the --shared-memory option to enable shared-memory
connections.
-t , --show-table-
Show table type column, as in SHOW FULL TABLES. The type is BASE TABLE or VIEW.
type

-S name , -- For connections to localhost, the Unix socket file to use, or, on Windows, the name of the
socket=name named pipe to use.
Enables TLS. TLS is also enabled even without setting this option when certain other TLS
options are set. Starting with MariaDB 10.2, the --ssl option will not enable verifying the
--ssl
server certificate by default. In order to verify the server certificate, the user must specify the
--ssl-verify-server-cert option.

Defines a path to a PEM file that should contain one or more X509 certificates for trusted
Certificate Authorities (CAs) to use for TLS. This option requires that you use the absolute
--ssl-ca=name
path, not a relative path. See Secure Connections Overview: Certificate Authorities (CAs) for
more information. This option implies the --ssl option.

1325/3812
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. 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 command. See Secure
--ssl-capath=name Connections Overview: 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 for more information about which libraries are used on which platforms. This option
implies the --ssl option.
Defines a path to the X509 certificate file to use for TLS. This option requires that you use the
--ssl-cert=name
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. This option implies the --ssl option.
Defines a path to a private key file to use for TLS. This option requires that you use the
--ssl-key=name
absolute path, not a relative path. This option implies the --ssl option.
Defines a path to a PEM file that should contain one or more revoked X509 certificates to use
for TLS. This option requires that you use the absolute path, not a relative path. See Secure
Connections Overview: Certificate Revocation Lists (CRLs) for more information. This option
--ssl-crl=name 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 for more information about which libraries are used on which platforms.
This option implies the --ssl option.
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. 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 command. See Secure Connections Overview: Certificate Revocation
--ssl-crlpath=name
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 for more information about
which libraries are used on which platforms. This option implies the --ssl option.
--ssl-verify-
Enables (or disables) server certificate verification. This option is disabled by default.
server-cert

Shows a lot of extra information about each table. See the


-i , --status
INFORMATION_SCHEMA.TABLES table for more details on the returned information.
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
--tls-version=name
permitted. See Secure Connections Overview: TLS Protocol Versions for more information.
This option was added in MariaDB 10.4.6.
-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, mysqlshow can also read options from option files. If an unknown
option is provided to mysqlshow 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 and later, mysqlshow is linked with MariaDB Connector/C . 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 for more information.

Option Groups
1326/3812
mysqlshow reads options from the following option groups from option files:

Group Description
[mysqlshow] Options read by mysqlshow , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysqlshow . Available starting with MariaDB 10.4.6.
show]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and MySQL
[client]
clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

Examples
Getting a list of databases:

bin/mysqlshow
+--------------------+
| Databases |
+--------------------+
| information_schema |
| test |
+--------------------+

Getting a list of tables in the test database:

bin/mysqlshow test
Database: test
+---------+
| Tables |
+---------+
| author |
| book |
| city |
| country |
+---------+

Getting a list of columns in the test . book table:

bin/mysqlshow 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 | |
+-----------+-----------------------+-------------------+------+-----+---------+----------------+------
--------------------------+---------+

1.3.30 mysqlslap
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-slap is a symlink to mysqlslap .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysqlslap is the symlink, and mariadb-slap the binary name.

1327/3812
Contents
1. Using mysqlslap
1. Options
2. Option Files
1. Option Groups
2. Examples

mysqlslap 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 mysqlslap
The command to use mysqlslap and the general syntax is:

mysqlslap [options]

Options
mysqlslap supports the following options:

Option Description
-a , --auto- Generate SQL statements automatically when they are not supplied in files or via command
generate-sql options.
--auto-generate-
sql-add- Add an AUTO_INCREMENT column to auto-generated tables.
autoincrement

--auto-generate-
sql-execute- Specify how many queries to generate automatically.
number=num

--auto-generate-
Add GUID based primary keys to auto-generated tables.
sql-guid-primary

Specify the test load type. The allowable values are read (scan tables), write (insert into
--auto-generate-
tables), key (read primary keys), update (update primary keys), or mixed (half inserts, half
sql-load-type=name
scanning selects). The default is mixed.
--auto-generate-
sql-secondary- Number of secondary indexes to add to auto-generated tables. By default, none are added.
indexes=num

--auto-generate- Number of unique queries to generate for automatic tests. For example, if you run a key test
sql-unique-query- that performs 1000 selects, you can use this option with a value of 1000 to run 1000 unique
number=num queries, or with a value of 50 to perform 50 different selects. The default is 10.
--auto-generate-
sql-unique-write- Number of unique queries to generate for auto-generate-sql-write-number .
number=num

--auto-generate-
sql-write- Number of row inserts to perform for each thread. The default is 100.
number=num

--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 , --
Number of clients to simulate for query to run.
concurrency=name

--create=name File or string containing the statement to use for creating the table.
--create-
Schema to run tests in.
schema=name

1328/3812
--csv[=name] Generate comma-delimited output to named file or to standard output if no file is named.
-# , -- For debug builds, write a debugging log. A typical debug_options string is d:t:o,file_name .
debug[=options] The default is d:t:o,/tmp/mysqlslap.trace .
--debug-check Check memory and open file usage at exit.
-T, --debug-info Print some debug info at exit.
--default-
Default authentication client-side plugin to use.
auth=name

--defaults-extra-
Read this file after the global files are read. Must be given as the first option.
file=name

--defaults-
Only read default options from the given file name Must be given as the first option.
file=name

-F name , --
Delimiter to use in SQL statements supplied in file or command line.
delimiter=name

Detach (close and reopen) connections after the specified number of requests. The default is
--detach=num
0 (connections are not detached).
Comma separated list of storage engines to use for creating the table. The test is run for each
-e name , --
engine. You can also specify an option for an engine after a #:#, for example
engine=name
memory:max_row=2300 .

-? , --help Display help and exit.


-h name , --
Connect to the MariaDB server on the given host.
host=name

--init- SQL Command to execute when connecting to the MariaDB server. Will automatically be re-
command=name executed when reconnecting. Added in MariaDB 5.5.34 .
-i num , --
Number of times to run the tests.
iterations=num

--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-
Number of VARCHAR columns to create in table if specifying --auto-generate-sql .
char-cols=name

-y name , --number-
Number of INT columns to create in table if specifying --auto-generate-sql .
int-cols=name

Limit each client to approximately this number of queries. Query counting takes into account
the statement delimiter. For example, if you invoke as follows, mysqlslap --delimiter=";" -
--number-of-
-number-of-queries=10 --query="use test;insert into t values(null)" , the #;#
queries=num
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.
Password to use when connecting to server. If password is not given it's asked from the
-p[password] , --
command line. Specifying a password on the command line should be considered insecure.
password[=password]
You can use an option file to avoid giving the password on the command line.
On Windows, connect to the server via a named pipe. This option applies only if the server
-W , --pipe
supports named-pipe connections.
--plugin-dir=name Directory for client-side plugins.
-P num , --port=num Port number to use for connection.
Query to run or file containing query to execute after tests have completed. This execution is
--post-query=name
not counted for timing purposes.
system() string to execute after tests have completed. This execution is not counted for timing
--post-system=name
purposes.
Query to run or file containing query to execute before running tests. This execution is not
--pre-query=name
counted for timing purposes.
system() string to execute before running tests. This execution is not counted for timing
--pre-system=name
purposes.
--print-defaults Print the program argument list and exit. Must be given as the first option.

1329/3812
--protocol=name The protocol to use for connection (tcp, socket, pipe, memory).
-q name , --
Query to run or file containing query to run.
query=name

--shared-memory- Shared-memory name to use for Windows connections using shared memory to a local server
base-name (started with the --shared-memory option). Case-sensitive.
-s , --silent Run program in silent mode - no output.
For connections to localhost, the Unix socket file to use, or, on Windows, the name of the
-S , --socket=name
named pipe to use.
Enables TLS. TLS is also enabled even without setting this option when certain other TLS
options are set. Starting with MariaDB 10.2, the --ssl option will not enable verifying the
--ssl
server certificate by default. In order to verify the server certificate, the user must specify the
--ssl-verify-server-cert option.

Defines a path to a PEM file that should contain one or more X509 certificates for trusted
Certificate Authorities (CAs) to use for TLS. This option requires that you use the absolute
--ssl-ca=name
path, not a relative path. See Secure Connections Overview: Certificate Authorities (CAs) for
more information. This option implies the --ssl 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) to use for TLS. 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 command. See Secure
--ssl-capath=name Connections Overview: 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 for more information about which libraries are used on which platforms. This option
implies the --ssl option.
Defines a path to the X509 certificate file to use for TLS. This option requires that you use the
--ssl-cert=name
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. This option implies the --ssl option.
Defines a path to a PEM file that should contain one or more revoked X509 certificates to use
for TLS. This option requires that you use the absolute path, not a relative path. See Secure
Connections Overview: Certificate Revocation Lists (CRLs) for more information. This option
--ssl-crl=name
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 for more information about which libraries are used on which platforms.
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. 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 command. See Secure Connections Overview: Certificate Revocation
--ssl-crlpath=name
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 for more information about
which libraries are used on which platforms.
Defines a path to a private key file to use for TLS. This option requires that you use the
--ssl-key=name
absolute path, not a relative path. This option implies the --ssl option.

--ssl-verify-
Enables server certificate verification. This option is disabled by default.
server-cert

-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, mysqlslap can also read options from option files. If an unknown
option is provided to mysqlslap 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.

1330/3812
--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 and later, mysqlslap is linked with MariaDB Connector/C . 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 for more information.

Option Groups
mysqlslap reads options from the following option groups from option files:

Group Description
[mysqlslap] Options read by mysqlslap , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysqlslap . Available starting with MariaDB 10.4.6.
slap]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and MySQL
[client]
clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

Examples
Create a table with data, and then query it with 40 simultaneous connections 100 times each.

mysqlslap
--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.

mysqlslap
--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

1.3.31 mysql-stress-test
Contents
1. Syntax
2. Options

mysql-stress-test.pl is a Perl script that performs stress-testing of the MariaDB server. It requires a version of Perl that
1331/3812
has been built with threads support.

Syntax
mysql-stress-test.pl [options]

Options
Option Description
--help Display a help message and exit.
--abort-on- Causes the program to abort if an error with severity less than or equal to N was encountered.
error=N Set to 1 to abort on any error.
--check-tests- Periodically check the file that lists the tests to be run. If it has been modified, reread the file.
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-
Log error details in the global error log file.
details

--loop-count=N In sequential test mode, the number of loops to execute before exiting.
--mysqltest=path The path name to the mysqltest program.
--server-
The database to use for the tests. The default is test.
database=db_name

--server- he host name of the local host to use for making a TCP/IP connection to the local server. By
host=host_name default, the connection is made to localhost using a Unix socket file.
--server-logs- This option is required. path is the directory where all client session logs will be stored. Usually
dir=path this is the shared directory that is associated with the server used for testing.
--server-
The password to use when connecting to the server.
password=password

--server-
The TCP/IP port number to use for connecting to the server. The default is 3306.
port=port_num

--server- For connections to localhost, the Unix socket file to use, or, on Windows, the name of the
socket=file_name named pipe to use. The default is /tmp/mysql.sock .
--server-
The MariaDB user name to use when connecting to the server. The default is root.
user=user_name

--sleep-time=N The delay in seconds between test executions.


--stress- This option is required and specified the path is the working directory for the test run. It is used
basedir=path as the temporary location for result tracking during testing.
--stress- The directory of data files to be used during testing. The default location is the data directory
datadir=path under the location given by the --stress-suite-basedir option.
file_name is the location of the file that contains the list of tests to be run once to initialize the
--stress-init-
database for the testing. If missing, the default file is stress_init.txt in the test suite
file[=path]
directory.
This option indicates the test order in stress-test mode. The mode value is either random to
--stress-
select tests in random order or seq to run tests in each thread in the order specified in the test
mode=mode
list file. The default mode is random .
This option is required and specifies the directory that has the t and r subdirectories containing
--stress-suite- the test case and result files. This directory is also the default location of the stress-test.txt
basedir=path file that contains the list of tests. (A different location can be specified with the --stress-tests-
file option.)

Use this option to run the stress tests. file_name is the location of the file that contains the list of
--stress-tests-
tests. If omitted, the default file is stress-test.txt in the stress suite directory. (See --
file[=file_name]
stress-suite-basedir .)

-- Run the named test suite. The default name is main (the regular test suite located in the
suite=suite_name mysql-test directory).

--test-count=N The number of tests to execute before exiting.

1332/3812
--test-
The duration of stress testing in seconds.
duration=N

--threads=N The number of threads. The default is 1.


--verbose Verbose mode. Print more information about what the program does

1.3.32 mysql-test
MariaDB uses mysql-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.
mysql-test Overview
1 Overview of mysql-test.

mysql-test Auxiliary Files


Besides test and result files, many other files that affect the testing process in mysql-test

mysql-test-run.pl Options
Run test cases.

Pausing mysql-test-run.pl
Working while your computer is busy running mysql-test-run.pl.

mysqltest and mysqltest-embedded


Runs a test case against a MariaDB server, optionally comparing the output with a result file.

New Features for mysqltest in MariaDB


MariaDB added a number of new options and commands to mysqltest.

Debugging MariaDB With a Debugger


If MariaDB is compiled for debugging, you can both use it in a debugger, an...

The Debug Sync Facility


DEBUG_SYNC synchronization points in server code

Code Coverage with dgcov


The dgcov tool helps you check the coverage for new code.

Installing MinIO for Usage With mysql-test-run


Easiest way to access to Amazon S3 compatible storage.

1.3.32.1 mysql-test Overview


Contents
1. The Basics
2. Overlays
3. Combinations
4. Sample Output
5. Plugin Support
6. mtr communication procedure

The Basics
At its core, mysql-test is very simple. The client program mysqltest 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 mysql-test-run.pl driver script, or mtr for short (for
convenience, mtr is created as a symbolic link to mysql-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 mysql-test/suite directory, and in the mysql-test subdirectories of plugins and
storage engine directories. For example, the following are all valid suite paths:

1333/3812
mysql-test/suite/rpl

mysql-test/suite/handler

storage/example/mysql-test/demo

plugin/auth_pam/mysql-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 mysql-test directory.
Test files have a .test extension and can be placed directly in the suite directory (for example, mysql-
test/suite/handler/interface.test ) or in the t subdirectory (e.g. mysql-test/suite/rpl/t/rpl_alter.test or
mysql-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, mysql-test/suite/handler/init.inc or mysql-
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 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/mysql-
test/rpl could be a myisam overlay of the rpl suite in mysql-test/suite/rpl . And plugin/daemon_example/mysql-
test/demo could be a daemon_example overlay of the demo suite in storage/example/mysql-test/demo . As a special
exception, an overlay of the main suite, should be called main , as in storage/pbxt/mysql-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

1334/3812
[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 mysqld , 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

1335/3812
--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.

1.3.32.2 mysql-test Auxiliary Files


Contents
1. disabled.def file
2. suite.opt file
3. other *.opt files
4. my.cnf file
5. other *.cnf files
6. combinations file
7. other *.combinations files
8. suite.pm file
9. *.sh files
10. *.require files
11. *.rdiff files
12. valgrind.supp file

The mysql-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):

1336/3812
# 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 mysqld 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.
1337/3812
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, 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.

1338/3812
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:

a number. Processes are started in the order of increasing SORT values (and stopped in the reverse order).
SORT
mysqld has number 300.

a function to start a process. It takes two arguments, My::Config::Group and My::Test . If START is
START
undefined a process will not be started.
a function to wait for the process to be started. It takes My::Config::Group as an argument. Internally mtr
WAIT
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 mysqltest . 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 mysql-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.

1339/3812
*.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 .

1340/3812
valgrind.supp file
This file defines valgrind suppressions, and it is used when mtr is started with a --valgrind option.

1.3.32.3 mysql-test-run.pl Options


Contents
1. Syntax
1. Examples
2. Options
1. Options to Control What
Engine/Variation to Run
2. Options to Control Directories to Use
3. Options to Control What Test Suites
or Cases to Run
4. Options That Specify Ports
5. Options For Test Case Authoring
6. Options That Pass On Options
7. Options to Run Test On Running
Server
8. Options For Debugging the Product
9. Misc Debugging Related Options
10. Misc Options

Syntax
./mysql-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.
If mysql-test-run.pl is started with the --ssl option, it sets up a secure connection for all test
--ssl cases. In this case, if mysqld does not support TLS, mysql-test-run.pl exits with an error
message: Couldn´t find support for SSL .
--skip-ssl Dont start server with support for TLS connections.
Visual Studio configuration used to create executables (default: MTR_VS_CONFIG
--vs-config
environment variable).
How many parallel tests should be run. Default is 1 , use --parallel=auto for auto-setting
--parallel=num
of num.

1341/3812
--defaults-file=
Use fixed config template for all tests.
<config template>

--
defaults_extra_file= Extra config template to add to all generated configs.
<config template>

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.
mysql-test-run.pl executes multiple test runs, using the options for each instance of --
--combination=
combination in successive runs. If --combination is given only once, it has no effect. For
<opt>
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
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
tmpdir=DIR
been set explicitly. This may be referred to in tests.
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
vardir=DIR this directory, whether it has the default value or has been set explicitly. This may be referred to in
tests.
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
--mem
locations to search, so it takes precedence over any built-in locations. Once you have run tests with --
mem within a mysql-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-
Path to the directory where client binaries are located.
bindir=PATH

--client-
Path to the directory where client libraries are located.
libdir=PATH

Options to Control What Test Suites or Cases to Run


Option Description
Normally, mysql-test-run.pl exits if a test case fails. --force causes execution to
--force
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.
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
--do-test=PREFIX or tests in the main test suite that begin with testa, and --do-test=main.*testa matches
REGEX 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 Skip test cases with names prefixed with PREFIX or which fulfil the REGEX. See -do-
REGEX test for examples.

Sorts the list of names of the test cases to be run, and then starts with the test prefixed
--start-from=PREFIX
with PREFIX, where the prefix may be suite.testname or just testname.

1342/3812
Comma separated list of suite names to run. The default, as of MariaDB 10.4.5, is:
"main-, archive-, binlog-, binlog_encryption-, csv-, compat/oracle-, encryption-, federated-
-- , funcs_1-, funcs_2-, gcol-, handler-, heap-, innodb-, innodb_fts-, innodb_gis-,
suite[s]=NAME1,..,NAMEN 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.
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
--big-test 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
Run a limited number of tests (no slow tests). Used for running staging trees with
--staging-run
valgrind.
Ignore any disabled.def file, and also run tests marked as disabled. Success or failure of
--enable-disabled
those tests will be reported the same way as other tests.
Don't run the tests but print details about all the selected tests, in the order they would be
--print-testcases
run.
Skip the tests listed in FILE. Each line in the file is an entry and should be formatted as:
--skip-test-list=FILE
<TESTNAME> : <COMMENT>

Options That Specify Ports


Option Description
--[mtr- Base for port numbers. Ports from this number to number+9 are reserved. Should be divisible by 10; if
]port- not it will be rounded down. May be set with environment variable MTR_PORT_BASE. If this value is
base=num set and is not "auto", it overrides build-thread.
--[mtr- Specify unique number to calculate port number(s) from. Can be set in environment variable
]build- MTR_BUILD_THREAD. Set MTR_BUILD_THREAD="auto" to automatically acquire a build thread id
thread=num that is unique to current host. The more logical --port-base is supported as an alternative.

Options For Test Case Authoring


Option Description
--record
(Re)generate the result file for TESTNAME.
TESTNAME

Check testcases for side-effects. This is done by checking system state before and after each test case;
--check-
if there is any difference, a warning to that effect will be written, but the test case will not be marked as
testcases
failed because of it. This check is enabled by default. Use --nocheck-testcases to disable.
mark-
Log line number and elapsed time to <testname>.progress
progress

Options That Pass On Options


Option Description
--mysqld=ARGS Specify additional arguments to "mysqld"
-- Specify additional arguments to "mysqltest". Use additional --mysqld-env options to set more than
mysqltest=ARGS one variable.

Options to Run Test On Running Server


Option Description
Use an already running server. The option/value pair is what is needed by the mysql client to connect
to the server. Each --extern option can only take one option/value pair as an argument, so you
extern need to repeat --extern for each pair needed. Example: ./mysql-test-run.pl --extern
option=value 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.

1343/3812
Options For Debugging the Product
In mysql-test-run.pl there is a concept of a "debugger". A "debugger" is a tool that mysql-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
ddd GUI frontend for gdb
dbx https://en.wikipedia.org/wiki/Dbx_(debugger)
devenv Visual Studio debugger
windbg https://en.wikipedia.org/wiki/WinDbg
lldb Debugger from LLVM project
valgrind Detects memory management problems and more
strace syscall tracer
"record and replay" — record the program execution and then replay it forward, backward, or in any other
rr
direction

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- Start mysqltest process under a debugger
XXX

--
Before running tests mysql-test-run executes mariadbd to bootstrap, prepare the datadir. This options
boot-
causes this bootstrapping mariadbd process to be run under a debugger.
XXX

--
Don't start anything, instead print the command that the user needs to run to start mariadbd under a
manual-
debugger. Then wait.
XXX

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-
Same as --debug , but sets the 'd' debug flags to "query,info,error,enter,exit"
common

--debug-
Use debug version of server, but without turning on tracing.
server

--max- Limit the number of core files saved (to avoid filling up disks for heavily crashing server). Defaults to 5,
save-core set to 0 for no limit. Set its default with MTR_MAX_SAVE_CORE.
--max-
Limit the number of datadir saved (to avoid filling up disks for heavily crashing server). Defaults to 20,
save-
set to 0 for no limit. Set its default with MTR_MAX_SAVE_DATDIR.
datadir

--max- Limit the number of test failurs before aborting the current test run. Defaults to 10, set to 0 for no limit.
test-fail Set its default with MTR_MAX_TEST_FAIL.

Misc Options
1344/3812
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-
Write when and why servers are restarted between test cases.
restart

Only initialize and start the servers, using the startup settings for the first specified test case
--start Example: ./mysql-test-run.pl --start alias & start-dirty Only start the servers (without
initialization) for the first specified test case
--start-and-
Same as --start , but mysql-test-run terminates and leaves just the server running.
exit

This is similar to --start , but will skip the database initialization phase and assume that
--start-dirty
database files are already available. Usually this means you must have run another test first.
In combination with start* and no test name, drops arguments to mysqld except those specified
--user-args
with --mysqld (if any).
If --start or --start-dirty option is used, wait for all servers to exit before finishing the
--wait-all
process. Otherwise, it will terminate if one (of several) servers is restarted.
Do not perform controlled shutdown when servers need to be restarted or at the end of the test
--fast
run. This is equivalent to using --shutdown-timeout=0 .
--force-
Always restart servers between tests.
restart

--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.
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
--retry=N
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- When using the --retry option to retry failed tests, stop when N failures have occured (default 2).
failure=N Setting it to 0 or 1 effectively turns off retries.
Reorder tests to get fewer server restarts. This is the default behavior. There is no guarantee that
--reorder
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-
Max test suite run time in minutes (default 360).
timeout=MINUTES

--shutdown-
Max number of seconds to wait for server shutdown before killing servers (default 10).
timeout=SECONDS

Scan the log files for warnings and report any suspicious ones; if any are found, the test will be
--warnings
marked as failed. Use --nowarnings to turn off.
--stop- If this file is detected, mysqltest will not start new tests until the file is removed (also
file=file MTR_STOP_FILE environment variable).
--stop-keep- Works with --stop-file , print messages every sec seconds when mysqltest is waiting to remove
alive=sec the file (for buildbot) (also MTR_STOP_KEEP_ALIVE environment variable).
--
Passed to mysqltest; will be used as fixed sleep time.
sleep=SECONDS

--debug-sync-
Set default timeout for WAIT_FOR debug sync actions. Disable facility with NUM=0.
timeout=NUM

Collect coverage information after the test. The result is a dgcov file per source and header file
--gcov and a last_changes.dgcov file in the vardir with the coverage for the uncommitted changes if any
(or the last commit).

1345/3812
--gprof Collect profiling information using the gprof profiling tool.
Specify a file that contains a list of test cases that should be displayed with the [ exp-fail ] code
--experimental=
rather than [ fail ] if they fail. For an example of a file that might be specified via this option, see
<file>
mysql-test/collections/default.experimental .
--report- First run a "test" that reports MariaDB features, displaying the output of SHOW ENGINES and
features SHOW VARIABLES. 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- Maximum number of simultaneous server connections that may be used per test. Default is 128.
connections=N Minimum is 8, maximum is 5120. Corresponds to the same option for mysqltest.
--default- Set default storage engine to MyISAM for non-innodb tests. This is needed after switching default
myisam storage engine to InnoDB.
--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. Options are separated by comma.
xml-report= Output jUnit xml file of the results. From MariaDB 10.1.45 , MariaDB 10.2.32 , MariaDB
<file> 10.3.23, MariaDB 10.4.13, MariaDB 10.5.3
tail-lines=N Number of lines of the result to include in a failure report. From MariaDB 10.3.4.

1.3.32.4 Pausing mysql-test-run.pl


Contents
1. Keep Alive
2. The mysql-test-run Stop File
3. Examples
4. Fixes

Sometimes you need to work when your computer is busy running mysql-test-run.pl. The mysql-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 mysql-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 mysql-test-run.pl
at the interval you set to prevent timeouts.
If you are calling mysql-test-run.pl directly, you do not need to specify a timeout.

The mysql-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 mysql-test-run.
When enabled via the command-line or environment variable options, mysql-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:

mysql-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
mysql-test-run.pl

Fixes
1346/3812
The following mysql-test-run bugs have been fixed in MariaDB 5.1:
Windows: mysql-test-run --log-error fixed to not add --console.
mysql-test-run sometimes terminated mysqld early, causing loss of memory leak error reports from Valgrind and
GCov test coverage output

1.3.32.5 mysqltest and mysqltest-embedded


Contents
1. Options
2. See Also

The mysqltest 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 mysqltest> via mysql-
test-run.pl rather than invoking it directly.

mysqltest_embedded is similar but is built with support for the libmysqld embedded server.

Features of mysqltest:
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 mysqld servers and switch between connections
Can connect to an embedded server (libmysqld), if MariaDB or MySQL is compiled with support for libmysqld. (In
this case, the executable is named mysqltest_embedded rather than mysqltest.)
By default, mysqltest reads the test case on the standard input. To run mysqltest this way, you normally invoke it like
this:

shell> mysqltest **[options] [db_name]** < //test_file//

You can also name the test case file with a --test-file=file_name option.
The exit value from mysqltest 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
mysqltest supports the following options:

Option Description
--help , -? Display a help message and exit.
--basedir=dir , -b
The base directory for tests.
dir

--character-sets-
The directory where character sets are installed.
dir=path

Compress all information sent between the client and the server if both support
--compress , -C
compression.
This can be used to set the MYSQL_OPT_CONNECT_TIMEOUT parameter of
--connect-timeout=N mysql_options to change the number of seconds before an unsuccessful connection
attempt times out.
Continue test even if we got an error. This is mostly useful when testing a storage engine
--continue-on-error 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 , -
The default database to use.
D db_name

-- Write a debugging log if MariaDB is built with debugging support. The default
debug[=debug_options] , debug_options value is d:t:S:i:O,/tmp/mysqltest.trace on Unix and
-#[debug_options] d:t:i:O,\mysqld.trace on Windows.

--debug-check Print some debugging information when the program exits.


Print debugging information and memory and CPU usage statistics when the program
--debug-info
exits.

1347/3812
--host=host_name , -h
Connect to the server on the given host.
host_name

--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-
The maximum number of connection attempts when connecting to server.
retries=num

The maximum number of simultaneous server connections per client (that is, per test). If
--max-connections=num
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.
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
password[=password] ,
value following the --password or -p option on the command line, you are prompted for
-p[password]
one.
plugin-dir Directory for client-side plugins.
--port=port_num , -P The TCP/IP port number to use for the connection, or 0 for default to, in order of
port_num preference, my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default (3306).
Include the contents of the given file before processing the contents of the test file. The
--prologue=name included file should have the same format as other mysqltest 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 the output that results from running the test file into the file named by the --
--record , -r result-file option, if that option is given. It is an error to use this option without also
using --result-file .
This option specifies the file for test case expected results. --result-file , together with
--record , determines how mysqltest treats the test actual and expected results for a test
case:

If the test produces no results, mysqltest exits with an error message to that effect, unless
--result-file is given and the named file is an empty file.

--result- Otherwise, if --result-file is not given, mysqltest sends test results to the standard
file=file_name , -R output.
file_name
With --result-file but not --record , mysqltest reads the expected results from the
given file and compares them with the actual results. If the results do not match, mysqltest
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 , mysqltest updates the given file by writing the
actual test results to it.

--result-format-
Version of the result file format to use.
version=#

--server-arg=value , - Pass the argument as an argument to the embedded server. For example, --server-arg=-
A value -tmpdir=/tmp or --server-arg=--core . Up to 64 arguments can be given.

--server-
Read arguments for the embedded server from the given file. The file should contain one
file=file_name , -F
argument per line.
file_name

--shared-memory-base- Shared-memory name to use for Windows connections using shared memory to a local
name server (started with the --shared-memory option). Case-sensitive.
--silent , -s Suppress all normal output.
Cause all sleep commands in the test case file to sleep num seconds. This option does not
--sleep=num , -T num affect real_sleep commands. An option value of 0 can be used, which effectively disables
sleep commands in the test case.
1348/3812
--socket=path , -S
The socket file to use when connecting to localhost (which is the default host).
path

Execute DML statements within a stored procedure. For every DML statement, mysqltest
--sp-protocol creates and invokes a stored procedure that executes the statement rather than executing
the statement directly.
Enable TLS for secure connection (automatically enabled with other flags). Disable with -
--ssl
-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- Verify server's "Common Name" in its cert against hostname used when connecting. This
cert option is disabled by default.
--suite-dir=name Suite directory.
Specify how many lines of the result to include in the output if the test fails because an
--tail-lines=nn
SQL statement fails. The default is 0, meaning no lines of result printed.
--test-
file=file_name , -x Read test input from this file. The default is to read from the standard input.
file_name

--timer-
If given, the number of microseconds spent running the test will be written to this file. This
file=file_name , -m
is used by mysql-test-run.pl for its reporting.
file_name

--tmpdir=dir_name , -t
The temporary directory where socket files are created.
dir_name

--user=user_name , -u
The user name to use when connecting to the server.
user_name

--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-
Wait longer for timeouts. Useful when running under valgrind.
timeouts

See Also
New Features for mysqltest in MariaDB

1.3.32.6 New Features for mysqltest in


MariaDB
Note that not all MariaDB-enhancements are listed on this page. See mysqltest and mysqltest-embedded 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.

1349/3812
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).

MariaDB 10.0.13
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

1.3.32.7 Debugging MariaDB With a Debugger


Contents
1. Checking That MariaDB is Compiled For
Debugging
2. Building MariaDB for Debugging Starting
from 5.5
3. Building MariaDB 5.3 and Older
4. Debugging MariaDB From the Source
Directory
1. Creating the MariaDB Database
Directory
2. Running MariaDB in a Debugger
5. Debugging MariaDB Server with mysql-
test-run
1. Sample .my.cnf file to Make
Debugging Easier
6. See Also

If you have MariaDB compiled for debugging 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 !

1350/3812
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 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 , 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 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/mysql_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 so as not to have to repeat them on the run line.
If you run mysqld with --debug , you will get a trace file 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 mysql-test-run


If you get a crash while running mysql-test-run you can debug this in a debugger by using one of the following
options:
1351/3812
mysql-test-run --gdb failing-test-name

or if you prefer the ddd debugger:

mysql-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 or --language
even if one switches between debugging different MariaDB versions.

See Also
Creating a trace file
Configuring MariaDB with my.cnf
Running mariadbd from the build director

1.3.32.8 The Debug Sync Facility


Contents
1. Formal Syntax
2. Activation/Deactivation
3. Implementation
4. A typical synchronization pattern
5. Co-work with the DBUG facility
6. Synchronizing DEBUG_SYNC Actions

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

1352/3812
Nomenclature Description
A value of a global variable that persists until overwritten by a new signal. The global variable can
signal also be seen as a "signal post" or "flag mast". Then the signal is what is attached to the "signal post"
or "flag mast".
Assign the value (the signal) to the global variable ("set a flag") and broadcast a global condition to
emit a signal
wake those waiting for a signal.
wait for a
Loop over waiting for the global condition until the global value matches the wait-for signal.
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:

1353/3812
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, 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:

mysql-test-run.pl ... --debug-sync-timeout=0 ...

Likewise the default wait timeout can be set:

mysql-test-run.pl ... --debug-sync-timeout=10 ...

The command line option influences the readable value of the 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 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


1354/3812
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
1355/3812
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

1.3.32.9 Code Coverage with dgcov


Contents
1. Overview
2. Usage
3. Options and Variables
4. How to Prepare the Code for dgcov
5. Output
6. Examples
7. Caveats
8. References

The dgcov tool helps you check the coverage for new code

MariaDB starting with 10.2.4


dgcov.pl script is part of the mysql-test framework (and any packages that include mysql-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 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

1356/3812
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

mysql-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 mysql-test framework you need to have gcc version 4.8 or newer.

References
dgcov was created by Kristian Nielsen and was first announced here .
dgcov was re-implemented to aggregate the data and to work for git and cmake by Sergei Golubchik.

1.3.32.10 Installing MinIO for Usage With


mysql-test-run
When testing the S3 storage engine with the s3 test suite, mysql-test-run needs access to Amazon S3 compatible
storage.
The easiest way to achieve this is to install MinIO , an open source S3 compatible storage.
Here is a shell script that you can use to install MinIO with the right credentials for mysql-test-run. This should work on
most Linux systems as the binaries are statically linked. You can alternatively download MinIO binaries directly from
here .

1357/3812
# 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 mysql-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"/mysql-test
./mysql-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:

mysql-test/suite/s3/my.cnf
mysql-test/suite/s3/slave.cnf

1.3.33 mysql_tzinfo_to_sql
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-tzinfo-to-sql is a symlink to mysql_tzinfo_to_sql .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_tzinfo_to_sql is the symlink, and mariadb-tzinfo-to-sql the binary name.

mysql_tzinfo_to_sql is a utility used to load time zones on systems that have a zoneinfo database to load the time
zone tables (time_zone, time_zone_leap_second, time_zone_name, time_zone_transition and
time_zone_transition_type) 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
mysql_tzinfo_to_sql can be called in several ways. The output is usually passed straight to the mysql client for direct
loading in the mysql database.

shell> mysql_tzinfo_to_sql timezone_dir


shell> mysql_tzinfo_to_sql timezone_file timezone_name
shell> mysql_tzinfo_to_sql --leap timezone_file

Examples
Most commonly, the whole directory is passed:

shell>mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

Load a single time zone file, timezone_file , corresponding to the time zone called timezone_name .
1358/3812
shell> mysql_tzinfo_to_sql timezone_file timezone_name | mysql -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> mysql_tzinfo_to_sql --leap timezone_file | mysql -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.

1.3.34 mysql_upgrade
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-upgrade is a symlink to mysql_upgrade .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_upgrade is the symlink, and mariadb-upgrade the binary name.

MariaDB starting with 10.2.42


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 , MariaDB 10.3.33, MariaDB 10.4.23, MariaDB 10.5.14, MariaDB 10.6.6, MariaDB
10.7.2 and newer.

Contents
1. Using mariadb-upgrade/mysql_upgrade
1. Options
2. mariadb-upgrade/mysql_upgrade 2.0
1. Option Files
1. Option Groups
3. Differences Between mysql_upgrade in
MariaDB and MySQL
4. Speeding Up mariadb-
upgrade/mysql_upgrade
5. Symptoms of Not Having Run mariadb-
upgrade/mysql_upgrade When It Was
Needed
6. Other Uses
7. See Also

mariadb-upgrade/mysql_upgrade is a tool that checks and updates your tables to the latest version.
You should run mariadb-upgrade/mysql_upgrade after upgrading from one major MySQL/MariaDB release to another,
such as from MySQL 5.0 to MariaDB 10.4 or MariaDB 10.4 to MariaDB 10.5. You also have to use mysql_upgrade
after a direct "horizontal" migration, for example from MySQL 5.5.40 to MariaDB 5.5.40 . It's also safe to run mariadb-
upgrade/mysql_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/mysql_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 of all the databases before running mariadb-upgrade/mysql_upgrade .
In most cases, mariadb-upgrade/mysql_upgrade should just take a few seconds. The main work of mariadb-
upgrade/mysql_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). For tables that are not
up to date, runs ALTER TABLE table_name FORCE 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 change (rare)
A format change in the storage engine requires an update (very rare)

Using mariadb-upgrade/mysql_upgrade
1359/3812
mysql_upgrade [--force] [--user=# --password
--host=hostname --port=# --socket=#
--protocol=tcp|socket|pipe|memory
--verbose] OTHER_OPTIONS]

mariadb-upgrade/mysql_upgrade is mainly a framework to call mysqlcheck. mysql_upgrade works by doing the


following operations:

# Find out path to datadir


echo "show show variables like 'datadir'" | mysql
mysqlcheck --no-defaults --check-upgrade --auto-repair --databases mysql
mysql_fix_privilege_tables
mysqlcheck --no-defaults --all-databases --fix-db-names --fix-table-names
mysqlcheck --no-defaults --check-upgrade --all-databases --auto-repair

The connect options given to mariadb-upgrade/mysql_upgrade are passed along to mysqlcheck and mysql.
The mysql_fix_privilege_tables script is not actually called; it's included as part of mysql_upgrade
If you have a problem with mariadb-upgrade/mysql_upgrade try run it in very verbose mode:

mysql_upgrade --verbose --verbose other-options

mariadb-upgrade/mysql_upgrade also saves the MariaDB version number in a file named mysql_upgrade_info in the
data directory. 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, mysql_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/mysql_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-
Old option accepted for backward compatibility but ignored.
sets-dir=path

check-if-
upgrade-is- Do a quick check if upgrade is needed. Returns 0 if yes, 1 if no. 2.0
needed

--
Old option accepted for backward compatibility but ignored.
compress=name

--datadir=name Old option accepted for backward compatibility but ignored.


-# [name] , --
For debug builds, output debug log.
debug[=name]

--debug-check Check memory and open file usage at exit.


-T , --debug-
Print some debug info at exit.
info

--default-
character- Old option accepted for backward compatibility but ignored.
set=name

Force execution of mysqlcheck even if mysql_upgrade has already been executed for
-f , --force
the current version of MariaDB. Ignores mysql_upgrade_info .
-h , --
Connect to MariaDB on the given host.
host=name

-p , -- Password to use when connecting to server. If password is not given, it's solicited on
password[=name] 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 number to use for connection or 0 for default to, in order of preference, my.cnf, the
port=name MYSQL_TCP_PORT environment variable, /etc/services, built-in default (3306).
--
The protocol to use for connection (tcp, socket, pipe, memory).
protocol=name

1360/3812
--silent Print less information.
-S , -- For connections to localhost, the Unix socket file to use, or, on Windows, the name of
socket=name the named pipe to use.
Enables TLS. TLS is also enabled even without setting this option when certain other
TLS options are set. Starting with MariaDB 10.2, the --ssl option will not enable
--ssl
verifying the server certificate by default. In order to verify the server certificate, the user
must specify the --ssl-verify-server-cert option.
Defines a path to a PEM file that should contain one or more X509 certificates for
trusted Certificate Authorities (CAs) to use for TLS. This option requires that you use
--ssl-ca=name
the absolute path, not a relative path. See Secure Connections Overview: Certificate
Authorities (CAs) for more information. This option implies the --ssl 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) to use for TLS. 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 command. See
--ssl-
Secure Connections Overview: Certificate Authorities (CAs) for more information. This
capath=name
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 for more information about which libraries are
used on which platforms. This option implies the --ssl option.
--ssl- Defines a path to the X509 certificate file to use for TLS. This option requires that you
cert=name use the absolute path, not a relative path. This option implies the --ssl option.
--ssl- List of permitted ciphers or cipher suites to use for TLS. This option implies the --ssl
cipher=name option.
Defines a path to a PEM file that should contain one or more revoked X509 certificates
to use for TLS. This option requires that you use the absolute path, not a relative path.
See Secure Connections Overview: Certificate Revocation Lists (CRLs) for more
--ssl-crl=name 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 for more information
about which libraries are used on which platforms.
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. This option requires that you use
the absolute path, not a relative path. The directory specified by this option needs to be
--ssl- run through the openssl rehash command. See Secure Connections Overview:
crlpath=name 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 for more information about which libraries are used on which platforms.
Defines a path to a private key file to use for TLS. This option requires that you use the
--ssl-key=name
absolute path, not a relative path. This option implies the --ssl option.
--ssl-verify-
Enables server certificate verification. This option is disabled by default.
server-cert

-t , --
Directory for temporary files.
tmpdir=name

-s , --upgrade- Only upgrade the system tables in the mysql database. Tables in other databases are
system-tables not checked or touched.
-u , --
User for login if not current user.
user=name

Display more output about the process, using it twice will print connection arguments;
using it 3 times will print out all CHECK, RENAME and ALTER TABLE commands used
-v , --verbose during the check phase; using it 4 times will also write out all mysqlcheck commands
used.

-V , --version Output version information and exit.


Run this program only if its 'server version' matches the version of the server to which
-k , --version- it's connecting check. Note: the 'server version' of the program is the version of the
check MariaDB server with which it was built/distributed. (Defaults to on; use --skip-
version-check to disable.)

1361/3812
All commands including those run by mysqlcheck are written to the binary log. Disabled
by default. Before MariaDB 10.0.6 and MariaDB 5.5.34 , this was enabled by
--write-binlog
default, and --skip-write-binlog should be used when commands should not be sent
to replication slaves.

mariadb-upgrade/mysql_upgrade 2.0
mariadb-upgrate/mysql_upgrade 2.0 was introduced in MariaDB 10.2.42 , MariaDB 10.3.33, MariaDB 10.4.23,
MariaDB 10.5.14, MariaDB 10.6.6, MariaDB 10.7.2.
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 ( mysql_upgrade did not have rights to create the file), mariadb-
upgrade/mysql_upgrade 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 mysql_upgrade run would have to do a full upgrade check, which can
take a while if there are a lot of tables.
mariadb-upgrade/mysql_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/mysql_upgrade processes cannot be run in parallel, which can cause deadlocks
(MDEV-27068 ). One side-effect of this is that mariadb-upgrade/mysql_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/mysql_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/mysql_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/mysql_upgrade will return
0 if there has been a major version change and one should run mariadb-upgrade/mysql_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/mysql_upgrade .

Option Files
In addition to reading options from the command-line, mariadb-upgrade/mysql_upgrade can also read options from
option files. If an unknown option is provided to mariadb-upgrade/mysql_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 and later, mariadb-upgrade/mysql_upgrade is linked with MariaDB Connector/C . 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 for more information.

Option Groups
mariadb-upgrade/mysql_upgrade reads options from the following option groups from option files:

Group Description
[mysql_upgrade] Options read by mysql_upgrade , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysql_upgrade . Available starting with MariaDB 10.4.6.
upgrade]

Options read by all MariaDB and MySQL client programs, which includes both MariaDB and
[client]
MySQL clients. For example, mysqldump .
Options read by all MariaDB client programs and the MariaDB Server. This is useful for options
[client-server] like socket and port, which is common between the server and the clients.

1362/3812
[client-
Options read by all MariaDB client programs.
mariadb]

Differences Between mysql_upgrade in MariaDB and


MySQL
This is as of MariaDB 5.1.50 :
MariaDB will convert long table names properly.
MariaDB will convert InnoDB tables (no need to do a dump/restore or ALTER TABLE ).
MariaDB will convert old archive tables to the new 5.1 format.
"mysql_upgrade --verbose" will run "mysqlcheck --verbose" so that you get more information of what is
happening. Running with 3 times --verbose will in MariaDB 10.0 print out all CHECK, RENAME and ALTER
TABLE commands executed.
The mysql.event table is upgraded live; no need to restart the server to use events if the event table has changed
(MariaDB 10.0.22 and MariaDB 10.1.9 ).
More descriptive output.

Speeding Up mariadb-upgrade/mysql_upgrade
- If you are sure that all your tables are up to date with the current version, then you can run mysql_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/mysql_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.
If some of the tables are using an index for which we have changed sort order.
This has not happened since MariaDB 5.5.
If you are 100% sure this applies to you, you can just run mariadb-upgrade/mysql_upgrade with the ---upgrade-
system-tables option.

Symptoms of Not Having Run mariadb-


upgrade/mysql_upgrade When It Was Needed
Errors in the error log 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 may report the wrong checksum for MyISAM or Aria tables.
To fix issues like this, run mariadb-upgrade/mysql_upgrade , mysqlcheck, CHECK TABLE and if needed REPAIR
TABLE on the wrong table.

Other Uses
mariadb-upgrade/mysql_upgrade will re-create any missing tables in the mysql database. It will not touch any
data in existing tables.

See Also
mysqlcheck
CHECK TABLE
REPAIR TABLE

1.3.35 mysql_waitpid
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-waitpid is a symlink to mysql_waitpid .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_waitpid is the symlink, and mariadb-waitpid the binary name.

1363/3812
Contents
1. Usage
2. Description
3. Options

mysql_pid is a utility for terminating processes. It runs on Unix-like systems, making use of the kill() system call.

Usage
mysql_waitpid [options] pid time

Description
mysql_pid 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

1.3.36 perror
Contents
1. Usage
2. Options
3. Examples

perror is a utility that displays descriptions for system or storage engine error codes.
See MariaDB Error Codes for a full list of MariaDB error codes, and Operating System Error Codes 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:
1364/3812
shell> perror 96
OS error code 96: Protocol family not supported

MariaDB/MySQL error code:

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

1.3.37 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.
Match space-character, start of line or end of line. For an end \b the next replace starts looking at the
\b
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.

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.

1.3.38 resolveip

1365/3812
Contents
1. Usage
2. Options
3. Examples

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

1.3.39 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.

1.3.40 xtstat
Contents
1. Using xtstat
1. Command line options
1. Size indicators
2. Statistics
2. More Information

1366/3812
xtstat can be used to monitor all internal activity of PBXT .

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 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.
Password to use when connecting to server. If password is not given it's asked
-p, --password[=value]
from the tty.
Database to be used ( pbxt or information_schema required), default is
-d, --database=value
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
Columns to display: use short names separated by | (the pipe character), partial
--display=value
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)
1367/3812
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.

Display name Name Description


time-curr Current Time The current time in seconds
time-msec Time Since Last Call 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
Number of transactions still to be cleaned up. This also includes all the
currently running transactions. Cleanup means that the Sweeper thread
xact-dirty Dirty Xact Count 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
Bytes written to the record/row files. This data is transfered from the
rec-out Record Bytes Written
transaction logs to the handle data (xtd) and the row index files (xtr).
2 values separated by a '/': the number of flushes to data handle (.xtd) and
rec-syncs/ms Record File Flushes row index (.xtr) files and the time taken in milliseconds to perform the flush
operations.
Hits when accessing the record cache. The record cache caches the data
rec-hits Record Cache Hits
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
Percentage of record cache in use. This value is displayed by xtstat as a
rec-%use Record Cache Usage 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
Bytes written to the index files. This data is transfered from the index log
ind-out Index Bytes Written
files (ilog) to the index files (xti), during a consistent flush of the index.
2 values separated by a '/': the number of flushes to index files and the time
ind-syncs/ms Index File Flushes
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
Percentage of index cache used. This value is displayed by xtstat as a
ind-%use Index Cache Usage 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
Bytes written to the index log files. This data is transfered from the index
ilog-out Index Log Bytes Out cache in main memory to the index log files (ilog) during a consistent flush
of the index.
ilog- 2 values separated by a '/': the number of flushes to index log files and the
Index Log File Syncs
syncs/ms time taken for the flush operations in milliseconds
xlog-in Xact Log Bytes In Bytes read from the transaction log files

1368/3812
Bytes written to the transaction log files. This is data transfered from the
transaction log buffer (pbxt_transaction_buffer_size) to the transaction log
xlog-out Xact Log Bytes Out
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
Xact Log Cache
xlog-miss Misses when accessing the transaction log cache
Misses
Percentage of transaction log cache used. This value is displayed by xtstat
xlog-%use Xact Log Cache Usage 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
Bytes written to the data log files. This data is transfered from the data log
data-out Data Log Bytes Out 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 Sweeper Wait on Xact 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 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

1.3.41 mariadb-access
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-access is a symlink to mysqlaccess , the tool for checking access privileges.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-access is the name of the tool, with mysqlaccess a symlink .

See mysqlaccess for details.

1.3.42 mariadb-admin
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-admin is a symlink to mysqladmin , the administration program for the mysqld
daemon.

MariaDB starting with 10.5.2


1369/3812
From MariaDB 10.5.2, mariadb-admin is the name of the administration program for the mysqld daemon, with
mysqladmin a symlink .

See mysqladmin for details.

1.3.43 mariadb-check
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-check is a symlink to mysqlcheck , the tool for checking, repairing, analyzing and
optimizing tables.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-check is the name of the tool, with mysqlcheck a symlink .

See mysqlcheck for details.

1.3.44 mariadb-conv
MariaDB starting with 10.5.1
mariadb-conv is a character set conversion utility for MariaDB and was added in MariaDB 10.5.1.

Contents
1. Usage
2. Options
3. Examples

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.
1370/3812
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
@[email protected]
@[email protected]
@g0@[email protected]
@g0@[email protected]
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

1.3.45 mariadb-convert-table-format
MariaDB starting with 10.4.6
From MariaDB 10.4.6, 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


From MariaDB 10.5.2, mariadb-convert-table-format is the name of the tool, with mysql_convert_table_format a
symlink .

See mysql_convert_table_format for details.

1.3.46 mariadb-dumpslow
1371/3812
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-dumpslow is a symlink to mysqldumpslow , the tool for examining the slow query log.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-dumpslow is the name of the tool, with mysqldumpslow a symlink .

See mysqldumpslow for details.

1.3.47 mariadb-embedded
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-embedded is a symlink to mysql_embedded , the embedded server.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-embedded is the name of the tool, with mysql_embedded a symlink.

See mysql_embedded for details.

1.3.48 mariadb-find-rows
MariaDB starting with 10.4.6
From MariaDB 10.4.6, 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 or
SET statements.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-find-rows is the name of the tool, with mysql_find_rows a symlink .

See mysql_find_rows for details.

1.3.49 mariadb-fix-extensions
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-fix-extensions is a symlink to mysql_fix_extensions , the tool for converting the
extensions for MyISAM (or ISAM) table files to their canonical forms.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_fix_extensions is the symlink, and mariadb-fix-extensions the binary name.

See mysql_fix_extensions for details.

1.3.50 mariadb-install-db
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-install-db is a symlink to mysql_install_db . the tool for initializing the MariaDB
data directory and creating the system tables

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_install_db is the symlink, and mariadb-install-db the binary name.

See mysql_install_db for details.

1372/3812
1.3.51 mariadb-plugin
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-plugin is a symlink to mysql_plugin , the tool for enabling or disabling plugins.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_plugin is the symlink, and mariadb-plugin the binary name.

See mysql_plugin for details.

1.3.52 mariadb-report
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-report is a symlink to mysqlreport , the binary for showing the value of important
status variables.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadb-report is the name of the binary, with mysqlreport a symlink .

See mysqlreport for details.

1.3.53 mariadb-secure-installation
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-secure-installation is a symlink to mysql_secure_installation , the script for
enabling you to improve the security of your MariaDB installation.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_secure_installation is the symlink, and mariadb-secure-installation the binary
name.

See mysql_secure_installation for details.

1.3.54 mariadb-setpermission
MariaDB starting with 10.4.6
From MariaDB 10.4.6, 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


From MariaDB 10.5.2, mysql_setpermission is the symlink, and mariadb-setpermission the binary name.

See mysql_setpermission for details.

1.3.55 mariadb-show
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-show is a symlink to mysqlshow , the script showing the structure of a MariaDB
database.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysqlshow is the symlink, and mariadb-show the binary name.

1373/3812
See mysqlshow for details.

1.3.56 mariadb-slap
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-slap is a symlink to mysqlslap , the tool for load-testing MariaDB.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysqlslap is the symlink, and mariadb-slap the binary name.

See mysqlslap for details.

1.3.57 mariadb-tzinfo-to-sql
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-tzinfo-to-sql is a symlink to mysql_tzinfo_to_sql , the tool for loading time zones
on systems that have a zoneinfo database.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_tzinfo_to_sql is the symlink, and mariadb-tzinfo-to-sql the binary name.

See mysql_tzinfo_to_sql for details.

1.3.58 mariadb-upgrade
MariaDB starting with 10.4.6
From MariaDB 10.4.6, 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


From MariaDB 10.5.2, mysql_upgrade is the symlink, and mariadb-upgrade the binary name.

See mysql_upgrade for details.

1.3.59 mariadb-waitpid
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadb-waitpid is a symlink to mysql_waitpid , the utility for terminating processes.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mysql_waitpid is the symlink, and mariadb-waitpid the binary name.From MariaDB 10.5.2,
mysql_waitpid is the symlink, and mariadb-waitpid the binary name.

See mysql_waitpid for details.

2 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.
Getting, Installing, and Upgrading MariaDB
Getting, installing, and upgrading MariaDB Server and related software.

User & Server Security


Creating users, granting privileges, and encryption.
1374/3812
Backing Up and Restoring Databases
Tools and methods for backing up and restoring databases.

Server Monitoring & Logs


Monitoring MariaDB Server and enabling and using logs.

Partitioning Tables
Splitting huge tables into multiple table files.

MariaDB Audit Plugin


Logging user activity with the MariaDB Audit Plugin.

Variables and Modes


Server variables and SQL modes.

Copying Tables Between Different MariaDB Databases and MariaDB Servers


1 Copy table files.

2.1 Getting, Installing, and Upgrading MariaDB


Where to Download MariaDB
4 Downloading tarballs, binaries, packages, and the source code for MariaDB.

MariaDB Binary Packages


Instructions on installing MariaDB binaries and packages.

Upgrading MariaDB
Upgrading from an earlier version, or from MySQL

Downgrading between Major Versions of MariaDB


Downgrading MariaDB is not supported.

Compiling MariaDB From Source


Articles on compiling MariaDB from source

Starting and Stopping MariaDB


Articles related to starting and stopping MariaDB Server.

MariaDB Performance & Advanced Configurations


Articles of how to setup your MariaDB optimally on different systems

Troubleshooting Installation Issues


Articles relating to installation issues users might run into

Installing System Tables (mysql_install_db)


Using mysql_install_db to create the system tables in the 'mysql' database directory.

mysql_install_db.exe
4 Windows equivalent of mysql_install_db for creating the system tables etc.

Configuring MariaDB with Option Files


12 Configuring MariaDB with my.cnf and other option files.

MariaDB Environment Variables


List of environment variables used by MariaDB.

Puppet and MariaDB


Puppet modules that allow you to use MariaDB.

MariaDB on Amazon RDS


Getting started with MariaDB on Amazon RDS

Obsolete Installation Information


Installation-related items that are obsolete

Migrating to MariaDB
Migrating to MariaDB from another DBMS.
1375/3812
Installing MariaDB on IBM Cloud
Get MariaDB on IBM Cloud You should have an IBM Cloud account, otherwise ...

mysqld Configuration Files and Groups


1 Which configuration files and groups mysqld reads.

There are 59 related questions .

2.1.1 Where to Download MariaDB


Contents
1. The Latest Packages
2. Distributions Which Include MariaDB
3. Pre-Release Binaries
4. Getting the Source

The Latest Packages


Tarballs, binaries (Linux, Solaris, and Windows), and packages for some Linux distributions are available at
mariadb.com/downloads/ or mariadb.org/download/ (which also contains a PDF version of the MariaDB Server
documentation).
We hope that interested community package maintainers will step forward, as others already have, to build packages
for their distributions. We ask for strict adherence to your packaging system's best practices and invite you to create a
bug report if our project impedes this in any way.
Instructions how to install the packages can be found here.

Distributions Which Include MariaDB


Most distributions already include MariaDB. See Distributions Which Include MariaDB.

Pre-Release Binaries
Binaries from our Buildbot system (see also the Buildbot page), are available at http://hasky.askmonty.org/archive
. They are not suitable for use in production systems but may be of use for debugging.
Once at the above URL you will need to click on the MariaDB tree you are interested in, and then the build. The build
number corresponds to the tarbuildnum variable in Buildbot.
For example, if you were interested in the bsd9-64 build of the MariaDB 5.5 tree, revision 3497, the tarbuildnum is
listed in the "Build Properties" table of the Buildbot build report . In this case, the value is "2434".

Getting the Source


You can find all the source code at https://github.com/MariaDB/server
To retrieve the code, the Git source control software offers the path of least resistance. If you are unfamiliar with git,
please refer to the git documentation for an understanding of version control with git.
For instructions on creating a local branch of MariaDB, see the Getting the MariaDB Source Code page.
See the Generic Build Instructions page for general instructions on compiling MariaDB from the source. The source
page has links to platform and distribution-specific information, including information on how we build the release
packages.

2.1.2 MariaDB Binary Packages


This section contains information on and installation instructions for MariaDB binaries and packages .
Installing MariaDB RPM Files
Information and instructions on using the RPM packages and the related repositories.

Installing MariaDB .deb Files


12 Installing MariaDB .deb Files.

Installing MariaDB MSI Packages on Windows


3 MSI packages are available for both x86 (32 bit) and x64 (64 bit) processor architectures
1376/3812
Installing MariaDB Server PKG packages on macOS
2 MariaDB Server does not currently provide a .pkg installer for macOS

Installing MariaDB Binary Tarballs


4 Installing MariaDB binary tarballs, systemd, and glibc-2.14.

Installing MariaDB Server on macOS Using Homebrew


3 Installing MariaDB on macOS via the Homebrew package manager, the "missing ...

Installing MariaDB Windows ZIP Packages


3 Getting started with ZIP packages on Windows.

Compiling MariaDB From Source


Articles on compiling MariaDB from source

Distributions Which Include MariaDB


Distributions including MariaDB.

Running Multiple MariaDB Server Processes


1 Running multiple MariaDB Server processes on the same server.

Installing MariaDB Alongside MySQL


5 MariaDB was designed as a drop in place replacement for MySQL, but you can ...

GPG
The MariaDB project signs their MariaDB packages for Debian, Ubuntu, Fedora, CentOS, and Red Hat

MariaDB Deprecation Policy


1 Information on MariaDB's Software Deprecation Policy and Schedule.

Automated MariaDB Deployment and Administration


Tools for automating deployment and management of MariaDB servers.

MariaDB Package Repository Setup and Usage


3 Executing and using a convenient shell script to set up the MariaDB Package Repository.

There are 6 related questions .

2.1.2.1 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.
About the MariaDB RPM Files
2 Describes the contents of the RPM packages that come with each MariaDB release.

Installing MariaDB with yum/dnf


23 Installing MariaDB with yum or dnf on RHEL, CentOS, Fedora, and similar distros.

Installing MariaDB with zypper


How to install MariaDB with zypper on SLES, OpenSUSE, and other similar Linux distributions.

Installing MariaDB With the rpm Tool


Downloading and installing RPM files using the rpm command

Checking MariaDB RPM Package Signatures


Steps to check MariaDB RPM package signatures

Troubleshooting MariaDB Installs on Red Hat/CentOS


Issues people have encountered when installing MariaDB on Red Hat / CentOS

MariaDB for DirectAdmin Using RPMs


Using DirectAdmin when installing MariaDB with YUM

1377/3812
MariaDB Installation (Version 10.1.21) via RPMs on CentOS 7
Detailed steps for installing MariaDB (version 10.1.21) via RPMs on CentOS 7

Why Source RPMs (SRPMs) Aren't Packaged For Some Platforms


Explanation for why source RPM (SRPMs) aren't packaged for some platforms

Building MariaDB from a Source RPM


How to build MariaDB from a source RPM (SRPM).

There are 4 related questions .

2.1.2.1.1 About the MariaDB RPM Files


Contents
1. Available RPM Packages
1. Available RPM Packages in MariaDB
10.4
2. Available RPM Packages in MariaDB
10.2 and MariaDB 10.3
3. Available RPM Packages in MariaDB
10.1
2. Installing RPM Packages
3. Actions Performed by RPM Packages
1. Users and Groups Created
4. See Also

Available RPM Packages


The available RPM packages depend on the specific MariaDB release series.

Available RPM Packages in MariaDB 10.4


MariaDB starting with 10.4
In MariaDB 10.4, the following RPMs are available:
Package Name Description
galera-4 The WSREP provider for Galera 4.
MariaDB-backup Mariabackup
MariaDB-backup-debuginfo Debuginfo for Mariabackup
MariaDB-client Client tools like mysql CLI, mysqldump , and others.
MariaDB-client-debuginfo Debuginfo for client tools like mysql CLI, mysqldump , 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 storage engine.
MariaDB-connect-engine-
Debuginfo for the CONNECT storage engine.
debuginfo

MariaDB-cracklib-password-
The cracklib_password_check password validation plugin.
check

MariaDB-cracklib-password-
Debuginfo for the cracklib_password_check password validation plugin.
check

MariaDB-devel Development headers and static libraries.


MariaDB-devel-debuginfo Debuginfo for development headers and static libraries.
MariaDB-gssapi-server The gssapi authentication plugin.
MariaDB-gssapi-server-
Debuginfo for the gssapi authentication plugin.
debuginfo

1378/3812
MariaDB-rocksdb-engine The MyRocks storage engine.
MariaDB-rocksdb-engine-
Debuginfo for the MyRocks storage engine.
debuginfo

MariaDB-server The server and server tools, like myisamchk and mysqlhotcopy are here.
Debuginfo for the server and server tools, like myisamchk and mysqlhotcopy are
MariaDB-server-debuginfo
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.

Debuginfo for mysql-client-test executable, and mysql-test framework with


MariaDB-test-debuginfo
the tests.
MariaDB-tokudb-engine The TokuDB storage engine.
MariaDB-tokudb-engine-
Debuginfo for the TokuDB storage engine.
debuginfo

Available RPM Packages in MariaDB 10.2 and MariaDB 10.3


MariaDB starting with 10.2
In MariaDB 10.2 and MariaDB 10.3, the following RPMs are available:
Package Name Description
galera The WSREP provider for Galera 3.
MariaDB-backup Mariabackup
MariaDB-backup-debuginfo Debuginfo for Mariabackup
MariaDB-client Client tools like mysql CLI, mysqldump , and others.
MariaDB-client-debuginfo Debuginfo for client tools like mysql CLI, mysqldump , 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 storage engine.
MariaDB-connect-engine-
Debuginfo for the CONNECT storage engine.
debuginfo

MariaDB-cracklib-password-
The cracklib_password_check password validation plugin.
check

MariaDB-cracklib-password-
Debuginfo for the cracklib_password_check password validation plugin.
check

MariaDB-devel Development headers and static libraries.


MariaDB-devel-debuginfo Debuginfo for development headers and static libraries.
MariaDB-gssapi-server The gssapi authentication plugin.
MariaDB-gssapi-server-
Debuginfo for the gssapi authentication plugin.
debuginfo

MariaDB-rocksdb-engine The MyRocks storage engine.

MariaDB-rocksdb-engine-
Debuginfo for the MyRocks storage engine.
debuginfo

MariaDB-server The server and server tools, like myisamchk and mysqlhotcopy are here.
Debuginfo for the server and server tools, like myisamchk and mysqlhotcopy are
MariaDB-server-debuginfo
here.
MariaDB-shared Dynamic client libraries.
MariaDB-shared-debuginfo Debuginfo for dynamic client libraries.

1379/3812
MariaDB-test mysql-client-test executable, and mysql-test framework with the tests.

Debuginfo for mysql-client-test executable, and mysql-test framework with


MariaDB-test-debuginfo
the tests.
MariaDB-tokudb-engine The TokuDB storage engine.
MariaDB-tokudb-engine-
Debuginfo for the TokuDB storage engine.
debuginfo

Available RPM Packages in MariaDB 10.1


MariaDB starting with 10.1
In MariaDB 10.1, the following RPMs are available:
Package Name Description
galera The WSREP provider for Galera 3.
MariaDB-backup Mariabackup
MariaDB-backup-debuginfo Debuginfo for Mariabackup
MariaDB-client Client tools like mysql CLI, mysqldump , and others.
MariaDB-client-debuginfo Debuginfo for client tools like mysql CLI, mysqldump , 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 storage engine.
MariaDB-connect-engine-
Debuginfo for the CONNECT storage engine.
debuginfo

MariaDB-cracklib-password-
The cracklib_password_check password validation plugin.
check

MariaDB-cracklib-password-
Debuginfo for the cracklib_password_check password validation plugin.
check

MariaDB-devel Development headers and static libraries.


MariaDB-devel-debuginfo Debuginfo for development headers and static libraries.
MariaDB-gssapi-server The gssapi authentication plugin.
MariaDB-gssapi-server-
Debuginfo for the gssapi authentication plugin.
debuginfo

MariaDB-server The server and server tools, like myisamchk and mysqlhotcopy are here.
Debuginfo for the server and server tools, like myisamchk and mysqlhotcopy are
MariaDB-server-debuginfo
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.

Debuginfo for mysql-client-test executable, and mysql-test framework with


MariaDB-test-debuginfo
the tests.
MariaDB-tokudb-engine The TokuDB storage engine.
MariaDB-tokudb-engine-
Debuginfo for the TokuDB storage engine.
debuginfo

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.

1380/3812
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

2.1.2.1.2 Installing MariaDB with yum/dnf


On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant RPM
packages from MariaDB's repository using yum or dnf . 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 .
This page walks you through the simple installation steps using yum .

Contents
1. Adding the MariaDB YUM repository
1. Using the MariaDB Package
Repository Setup Script
2. Using the MariaDB Repository
Configuration Tool
3. Pinning the MariaDB Repository to a
Specific Minor Release
2. Updating the MariaDB YUM repository to
a New Major Release
1. Updating the Major Release with the
MariaDB Package Repository Setup
Script
2. Updating the Major Release with the
MariaDB Repository Configuration
Tool
3. Importing the MariaDB GPG Public Key
4. Installing MariaDB Packages with YUM
1. Installing the Most Common Packages
with YUM
2. Installing MariaDB Server with YUM
3. Installing MariaDB Galera Cluster with
YUM
4. Installing MariaDB Clients and Client
Libraries with YUM
5. Installing Mariabackup with YUM
6. Installing Plugins with YUM
7. Installing Debug Info Packages with
YUM
1. Installing Debug Info for the Most
Common Packages with YUM
2. Installing Debug Info for MariaDB
Server with YUM
3. Installing Debug Info for MariaDB
Clients and Client Libraries with
YUM
4. Installing Debug Info for
Mariabackup with YUM
5. Installing Debug Info for Plugins
with YUM
8. Installing Older Versions from the
Repository
5. After Installation

Adding the MariaDB YUM repository


We currently have YUM repositories for the following Linux distributions:
Red Hat Enterprise Linux (RHEL) 6
1381/3812
Red Hat Enterprise Linux (RHEL) 7
CentOS 6
CentOS 7
Fedora 27
Fedora 28
Fedora 29

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 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, client libraries , plugins, and Mariabackup. 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 and a repository for MariaDB Tools, which
currently only contains Percona XtraBackup and its dependencies.
See MariaDB Package Repository Setup and Usage 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 .
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, client libraries , plugins, and Mariabackup. 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.3 on CentOS 7, then you could use the following
yum repository configuration in /etc/yum.repos.d/MariaDB.repo :

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.3/centos7-amd64
gpgkey=https://yum.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 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 on CentOS 7, then you could use the following
yum repository configuration in /etc/yum.repos.d/MariaDB.repo :

[mariadb]
name = MariaDB-10.3.14
baseurl=http://yum.mariadb.org/10.3.14/centos7-amd64
# alternative: baseurl=http://archive.mariadb.org/mariadb-10.3.14/yum/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

1382/3812
Note that if you change an existing repository configuration, then you 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, 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 , 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.2 to MariaDB 10.3, 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.2/10.3/' /etc/yum.repos.d/MariaDB.repo

After that, the repository should refer to MariaDB 10.3.

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.

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 0xcbcb082a1bb943db . The short form of the id is 0x1BB943DB . The full key fingerprint
is:

1993 69E5 404B D5FC 7D2F E43B CBCB 082A 1BB9 43DB

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 utility can be used to manually import this key instead. 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 YUM


After the yum repository is configured, you can install MariaDB by executing the yum 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 YUM


MariaDB starting with 10.4
In MariaDB 10.4 and later, to Install the most common packages, execute the following command:

1383/3812
sudo yum install MariaDB-server galera-4 MariaDB-client MariaDB-shared MariaDB-backup MariaDB-common

MariaDB until 10.3


In MariaDB 10.3 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 with YUM


To Install MariaDB Server, execute the following command:

sudo yum 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.1 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 and later, you also need to install the galera-4 package to obtain the Galera 4 wsrep provider library.
In MariaDB 10.3 and before, you also need to install the galera package to obtain the Galera 3 wsrep provider library.

MariaDB starting with 10.4


In MariaDB 10.4 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


In MariaDB 10.3 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 for more information on MariaDB Galera Cluster.

Installing MariaDB Clients and Client Libraries with YUM


In MariaDB 10.2 and later, MariaDB Connector/C 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 yum install MariaDB-client MariaDB-shared

Installing Mariabackup with YUM


To install Mariabackup, execute the following command:

sudo yum install MariaDB-backup

Installing Plugins with YUM


Some plugins may also need to be installed.
For example, to install the cracklib_password_check password validation plugin, execute the following command:

sudo yum install MariaDB-cracklib-password-check

1384/3812
Installing Debug Info Packages with YUM
MariaDB starting with 5.5.64
The MariaDB yum repository first added debuginfo packages in MariaDB 5.5.64 , MariaDB 10.1.39 , MariaDB
10.2.23 , MariaDB 10.3.14, and MariaDB 10.4.4.

The MariaDB yum repository also contains debuginfo packages. These package may be needed when debugging a
problem .

Installing Debug Info for the Most Common Packages with YUM
To install debuginfo 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

Installing Debug Info for MariaDB Server with YUM


To install debuginfo for MariaDB Server, execute the following command:

sudo yum install MariaDB-server-debuginfo

Installing Debug Info for MariaDB Clients and Client Libraries with YUM
In MariaDB 10.2 and later, MariaDB Connector/C has been included as the client library. However, the package name
for the client library has not been changed.
To install debuginfo for the clients and client libraries, execute the following command:

sudo yum install MariaDB-client-debuginfo MariaDB-shared-debuginfo

Installing Debug Info for Mariabackup with YUM


To install debuginfo for Mariabackup, execute the following command:

sudo yum install MariaDB-backup-debuginfo

Installing Debug Info for Plugins with YUM


For some plugins, debuginfo may also need to be installed.
For example, to install debuginfo for the cracklib_password_check password validation plugin, execute the following
command:

sudo yum install MariaDB-cracklib-password-check-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, MariaDB 10.3.11, and MariaDB 10.3.12. The
CentOS base yum repository also contains MariaDB 5.5.60 .
1385/3812
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 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.
If you are using MariaDB Galera Cluster, then keep in mind that the first node will have to be bootstrapped.

2.1.2.1.3 Installing MariaDB with zypper


On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant RPM
packages from MariaDB's repository using zypper .
This page walks you through the simple installation steps using zypper .

1386/3812
Contents
1. Adding the MariaDB ZYpp repository
1. Using the MariaDB Package
Repository Setup Script
2. Using the MariaDB Repository
Configuration Tool
3. Pinning the MariaDB Repository to a
Specific Minor Release
2. Updating the MariaDB ZYpp repository to
a New Major Release
1. Updating the Major Release with the
MariaDB Package Repository Setup
Script
2. Updating the Major Release with the
MariaDB Repository Configuration
Tool
3. Importing the MariaDB GPG Public Key
4. Installing MariaDB Packages with ZYpp
1. Installing the Most Common Packages
with ZYpp
2. Installing MariaDB Server with ZYpp
3. Installing MariaDB Galera Cluster with
ZYpp
4. Installing MariaDB Clients and Client
Libraries with ZYpp
5. Installing Mariabackup with ZYpp
6. Installing Plugins with ZYpp
7. Installing Debug Info Packages with
ZYpp
1. Installing Debug Info for the Most
Common Packages with ZYpp
2. Installing Debug Info for MariaDB
Server with ZYpp
3. Installing Debug Info for MariaDB
Clients and Client Libraries with
ZYpp
4. Installing Debug Info for
Mariabackup with ZYpp
5. Installing Debug Info for Plugins
with ZYpp
8. Installing Older Versions from the
Repository
5. After Installation

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 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, client libraries , plugins, and Mariabackup. 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 and a repository for MariaDB Tools, which
currently only contains Percona XtraBackup and its dependencies.
See MariaDB Package Repository Setup and Usage for more information.

1387/3812
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 .
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, client libraries , plugins, and Mariabackup. 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 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 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, 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 , 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 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.

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
1388/3812
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 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 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
In MariaDB 10.4 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


In MariaDB 10.3 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 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 and later, you also need to install the galera-4 package to obtain the Galera 4 wsrep provider library.
In MariaDB 10.3 and before, you also need to install the galera package to obtain the Galera 3 wsrep provider library.

MariaDB starting with 10.4


In MariaDB 10.4 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


In MariaDB 10.3 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.

1389/3812
See MariaDB Galera Cluster for more information on MariaDB Galera Cluster.

Installing MariaDB Clients and Client Libraries with ZYpp


In MariaDB 10.2 and later, MariaDB Connector/C 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, execute the following command:

sudo zypper install MariaDB-backup

Installing Plugins with ZYpp


Some plugins may also need to be installed.
For example, to install the cracklib_password_check 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
The MariaDB zypper repository first added debuginfo packages in MariaDB 5.5.64 , MariaDB 10.1.39 ,
MariaDB 10.2.23 , MariaDB 10.3.14, and MariaDB 10.4.4.

The MariaDB zypper repository also contains debuginfo packages. These package may be needed when
debugging a problem .

Installing Debug Info for the Most Common Packages with ZYpp
To install 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 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 and later, MariaDB Connector/C has been included as the client library. However, the package name
for the client library has not been changed.
To install 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 for Mariabackup, execute the following command:

sudo zypper install MariaDB-backup-debuginfo

Installing Debug Info for Plugins with ZYpp


For some plugins, debuginfo may also need to be installed.
For example, to install debuginfo for the cracklib_password_check password validation plugin, execute the
following command:
1390/3812
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 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 .
If you are using MariaDB Galera Cluster, then keep in mind that the first node will have to be bootstrapped.

2.1.2.1.4 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 where possible.
Navigate to http://downloads.mariadb.org 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 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 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:


1391/3812
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/mysqladmin -u root password 'new-password'


/usr/bin/mysqladmin -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 [email protected].
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
mysqladmin 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 MySQL client program. Issuing the command mysql should give you the MariaDB cursor.

See Also
Installing MariaDB with yum
Troubleshooting MariaDB Installs on RedHat/CentOS
Checking MariaDB RPM Package Signatures

2.1.2.1.5 Checking MariaDB RPM Package


Signatures
MariaDB RPM packages since MariaDB 5.1.55 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
1392/3812
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
Troubleshooting MariaDB Installs on RedHat/CentOS

2.1.2.1.6 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 where possible.
In Red Hat / CentOS it is also possible to install a RPM or a tar ball. 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)
Installing MariaDB RPM Files
Checking MariaDB RPM Package Signatures

2.1.2.1.7 MariaDB for DirectAdmin Using RPMs


If you are using DirectAdmin and you encounter any issues with Installing MariaDB with YUM, 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:
1393/3812
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. 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.

2.1.2.1.8 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:

1394/3812
# 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 to secure the
production server by dis allowing remote login for root, creating root password and removing the test database.
5) mysql_secure_installation

2.1.2.1.9 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 for a lot of things. In this specific case,
MariaDB's build process relies on CMake CPack Package Generators to build RPMs. The specific package generator
that it uses to build RPMs is called CPackRPM .
Support for source RPMs in CPackRPM became usable with MariaDB's build system starting from around cmake
3.10 . This means that we do not produce source RPMs on platforms where the installed cmake version is older
than that.
See also Building MariaDB from a Source RPM.

2.1.2.1.10 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).
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:

1395/3812
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

2.1.2.2 Installing MariaDB .deb Files

1396/3812
Contents
1. Installing MariaDB with APT
1. Adding the MariaDB APT repository
1. Using the MariaDB Package
Repository Setup Script
2. Using the MariaDB Repository
Configuration Tool
1. Executing add-apt-repository
2. Creating a Source List File
3. Using Ubuntu Software Center
4. Using Synaptic Package
Manager
3. Pinning the MariaDB Repository to
a Specific Minor Release
2. Updating the MariaDB APT repository
to a New Major Release
1. Updating the Major Release with
the MariaDB Package Repository
Setup Script
2. Updating the Major Release with
the MariaDB Repository
Configuration Tool
1. Updating a Repository with add-
apt-repository
2. Updating a Source List File
3. Importing the MariaDB GPG Public
Key
4. Installing MariaDB Packages with APT
1. Installing the Most Common
Packages with APT
2. Installing MariaDB Server with APT
3. Installing MariaDB Galera Cluster
with APT
4. Installing MariaDB Clients and
Client Libraries with APT
5. Installing Mariabackup with APT
6. Installing Plugins with APT
7. Installing Older Versions from the
Repository
2. Installing MariaDB with dpkg
3. After Installation
4. Installation Issues
1. Upgrading mariadb-server and
mariadb-client packages
5. Available DEB Packages
1. Available DEB Packages in MariaDB
10.4
2. Available DEB Packages in MariaDB
10.2 and MariaDB 10.3
3. Available DEB Packages in MariaDB
10.1
6. Actions Performed by DEB Packages
1. Users and Groups Created
7. See Also

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 , aptitude , Ubuntu Software Center , Synaptic Package
Manager , 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 9 (Jessie)
Debian 10 (Buster)
Debian 11 (Bullseye)
Debian Unstable (Sid)
1397/3812
Ubuntu 18.04 LTS (Bionic)
Ubuntu 20.04 LTS (Focal)
Ubuntu 20.10 (Groovy)
Ubuntu 21.04 (Hirsute)
Ubuntu 21.10 (Impish)

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 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, client libraries , plugins, and Mariabackup. 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 and a repository for MariaDB Tools, which
currently only contains Percona XtraBackup and its dependencies.
See MariaDB Package Repository Setup and Usage 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 .
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, client libraries , plugins, and Mariabackup. 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 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 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 file in /etc/apt/sources.list.d/ .
For example, if you wanted to use the repository to install MariaDB 10.3 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 .


1398/3812
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 .
See here for more information.

Using Synaptic Package Manager


Another way to add an apt repository is by using Synaptic Package Manager .
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 .
See here 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 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 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.


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, 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 , 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 command, then you can update the major
release that the repository uses by using the the add-apt-repository 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 command and
providing the --remove option. For example, if you wanted to remove a MariaDB 10.2 repository, then you could do so
1399/3812
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 command. For example, if
you wanted to use the repository to install MariaDB 10.3 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.

Updating a Source List File


If you added the apt repository by creating a source list 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 to MariaDB 10.3, 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.

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 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 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 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:

1400/3812
$ 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 <[email protected]>" 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 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


In MariaDB 10.4 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 - 10.3


In MariaDB 10.2 and MariaDB 10.3, to Install the most common packages, execute the following command:
sudo apt-get install mariadb-server galera mariadb-client libmariadb3 mariadb-backup mariadb-common

MariaDB until 10.1


In MariaDB 10.1 and before, to Install the most common packages, execute the following command:
sudo apt-get install mariadb-server galera mariadb-client libmysqlclient18 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 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 and later, you also need to install the galera-4 package to obtain the Galera 4 wsrep provider library.
In MariaDB 10.3 and before, you also need to install the galera-3 package to obtain the Galera 3 wsrep provider
library.
To install MariaDB Galera Cluster, first you would have to update the package cache by executing the following
command:
1401/3812
sudo apt update

MariaDB starting with 10.4


In MariaDB 10.4 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


In MariaDB 10.3 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 and
later, the package is called galera-arbitrator-4 In MariaDB 10.3 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


In MariaDB 10.4 and later, to install the arbitrator package, you could execute the following command:
sudo apt-get install galera-arbitrator-4

MariaDB until 10.3


In MariaDB 10.3 and before, to install the arbitrator package, you could execute the following command:
sudo apt-get install galera-arbitrator-3

See MariaDB Galera Cluster for more information on MariaDB Galera Cluster.

Installing MariaDB Clients and Client Libraries with APT


In MariaDB 10.2 and later, MariaDB Connector/C 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 and later, execute the following command:

sudo apt-get install mariadb-client libmariadb3

Or in MariaDB 10.1 and before, execute the following command:

sudo apt-get install mariadb-client libmysqlclient18

Installing Mariabackup with APT


To install Mariabackup, 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 may also need to be installed.

1402/3812
For example, to install the cracklib_password_check 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 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 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 .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 .
If you are using MariaDB Galera Cluster, then keep in mind that the first node will have to be bootstrapped.

Installation Issues
MariaDB starting with 5.5

Upgrading mariadb-server and mariadb-client packages


As noted in MDEV-4266 , the mariadb-server and mariadb-client packages have a minor upgrade issue if you
use ' apt-get install mariadb-server ' or ' apt-get install mariadb-client ' to upgrade them instead of the more
1403/3812
common ' apt-get upgrade '. This is because those two packages depend on mariadb-server-5.5 and mariadb-
client-5.5 with no specific version of those packages. For example, if you have the mariadb-server package
installed, version 5.5.29 and you install version 5.5.30 of that package it will not automatically upgrade the mariadb-
server-5.5 package to version 5.5.30 like you would expect because the 5.5.29 version of that package satisfies the
dependency.
The mariadb-server and mariadb-client packages are virtual packages, they only exist to require the installation
of the mariadb-server-5.5 and mariadb-client-5.5 packages, respectively. MariaDB will function normally with a,
for example, version 5.5.30 version of the mariadb-server package and a version 5.5.29 version of the mariadb-
server-5.5 package. No data is at risk. However, expected behavior is for ' apt-get install mariadb-server ' to
upgrade everything to the latest version (if a new version is available), so this is definitely a bug.
A fix is planned for this bug in a future version of MariaDB. In the mean time, when upgrading MariaDB, use ' apt-get
upgrade ' or ' apt-get install mariadb-server-5.5 '.

Available DEB Packages


The available DEB packages depend on the specific MariaDB release series.

Available DEB Packages in MariaDB 10.4


MariaDB starting with 10.4
In MariaDB 10.4, the following DEBs are available:
Package Name Description
galera-4 The WSREP provider for Galera 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
mariadb-client Client tools like mysql CLI, mysqldump , and others.
mariadb-client-core Core client tools
mariadb-common Character set files and /etc/my.cnf
mariadb-plugin-connect The CONNECT storage engine.
mariadb-plugin-cracklib-password-
The cracklib_password_check password validation plugin.
check

mariadb-plugin-gssapi-client The client-side component of the gssapi authentication plugin.


mariadb-plugin-gssapi-server The server-side component of the gssapi authentication plugin.
mariadb-plugin-rocksdb The MyRocks storage engine.
mariadb-plugin-spider The SPIDER storage engine.
mariadb-plugin-tokudb The TokuDB storage engine.
The server and server tools, like myisamchk and mysqlhotcopy are
mariadb-server
here.
mariadb-server-core The core server.
mysql-client-test executable, and mysql-test framework with the
mariadb-test
tests.
mariadb-test-data MariaDB database regression test suite - data files

Available DEB Packages in MariaDB 10.2 and MariaDB 10.3


MariaDB starting with 10.2
In MariaDB 10.2 and MariaDB 10.3, the following DEBs are available:
Package Name Description

1404/3812
galera The WSREP provider for Galera 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
mariadb-client Client tools like mysql CLI, mysqldump , and others.
mariadb-client-core Core client tools
mariadb-common Character set files and /etc/my.cnf
mariadb-plugin-connect The CONNECT storage engine.
mariadb-plugin-cracklib-password-
The cracklib_password_check password validation plugin.
check

mariadb-plugin-gssapi-client The client-side component of the gssapi authentication plugin.


mariadb-plugin-gssapi-server The server-side component of the gssapi authentication plugin.
mariadb-plugin-rocksdb The MyRocks storage engine.
mariadb-plugin-spider The SPIDER storage engine.
mariadb-plugin-tokudb The TokuDB storage engine.
The server and server tools, like myisamchk and mysqlhotcopy are
mariadb-server
here.
mariadb-server-core The core server.
mysql-client-test executable, and mysql-test framework with the
mariadb-test
tests.
mariadb-test-data MariaDB database regression test suite - data files

Available DEB Packages in MariaDB 10.1


MariaDB starting with 10.1
In MariaDB 10.1, the following DEBs are available:
Package Name Description
galera The WSREP provider for Galera 3.
libmysqlclient18 Dynamic client libraries.
mariadb-backup Mariabackup
mariadb-client Client tools like mysql CLI, mysqldump , and others.
mariadb-client-core Core client tools
mariadb-common Character set files and /etc/my.cnf
mariadb-plugin-connect The CONNECT storage engine.
mariadb-plugin-cracklib-password-
The cracklib_password_check password validation plugin.
check

mariadb-plugin-gssapi-client The client-side component of the gssapi authentication plugin.


mariadb-plugin-gssapi-server The server-side component of the gssapi authentication plugin.
mariadb-plugin-spider The SPIDER storage engine.
mariadb-plugin-tokudb The TokuDB storage engine.
The server and server tools, like myisamchk and mysqlhotcopy are
mariadb-server
here.
mariadb-server-core The core server.
mysql-client-test executable, and mysql-test framework with the
mariadb-test
tests.

1405/3812
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
Installing MariaDB .deb Files with Ansible

2.1.2.3 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).

Contents
1. Installation UI
1. Welcome
2. License Agreement
3. Custom Setup
4. Database Authentication/Security
Related Properties
5. Other Database Properties
6. Ready to Install
7. End
2. New Entries in Start Menu
3. Uninstall UI
4. Silent Installation
1. Properties
2. Features
3. Silent Installation Examples
4. Silent Uninstall
5. Installation Logs
6. Running 32 and 64 Bit Distributions on
the Same Machine

Installation UI
This is the typical mode of installation. To start the installer, just click on the mariadb-<major>.<minor>.<patch>.msi

Welcome

1406/3812
License Agreement

Click on "I accept the terms"

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
1407/3812
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 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

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

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 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 and --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 parameter post-installation to bind to only local addresses. If the "Enable
networking" checkbox is deselected, the database will use named pipes for communication.
1408/3812
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

At this point, all installation settings are collected. Click on the "Install" button.

End

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:

1409/3812
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.

1410/3812
If you installed a database instance, you will need to decide if you want to remove or keep the data in the database
directory.

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

1411/3812
%ProgramFiles%\MariaDB
INSTALLDIR Installation root
<version>\

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
Name of the Windows service. A service is not
SERVICENAME
created if this value is empty.
SKIPNETWORKING Skip networking
Corresponds to "optimize for transactions" in the GUI,
STDCONFIG 1
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
1412/3812
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.

2.1.2.4 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.

2.1.2.5 Installing MariaDB Binary Tarballs


Contents
1. Ensure You Use the Correct my.cnf Files
2. Installing MariaDB as root in
/usr/local/mysql
3. Installing MariaDB as Not root in Any
Directory
4. Auto Start of mysqld
5. Post Installation

MariaDB Binary tarballs are named following the pattern: mariadb-VERSION-OS.tar.gz. Be sure to download the
correct version for your machine.

Note: Some 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 , unpack the distribution into the directory of your choice and run the mysql_install_db 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.

NOTE: For MariaDB 5.1.32 only the line " ./scripts/mysql_install_db --user=mysql " should be changed to " ./bin/mysql_install_db --
user=mysql "

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 in your home directory and telling mysql_install_db , mysqld_safe and
possibly mysql (the command-line client utility) to only use this one with the option ' --defaults-file=~/.my.cnf '. Note
that this has to be first option for the above commands!

1413/3812
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/mysql_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 mysql_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, mysqldump, 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/mysql_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:

1414/3812
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 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 to start MariaDB automatically 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 can be consulted.
For details on the exact steps used to build the binaries, see the compiling MariaDB section of the KB.

2.1.2.6 Installing MariaDB Server on macOS


Using Homebrew
Contents
1. Upgrading MariaDB
2. Building MariaDB Server from source
3. Other resources

MariaDB Server is available for installation on macOS (formerly Mac OS X) via the Homebrew 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:

brew services start mariadb

After MariaDB Server is started, you can log in as your user:

mysql

Or log in as root:
1415/3812
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
Terin Stock (terinjokes) who is the packager for Homebrew
MariaDB Server on macOS: Does it even make sense to try? (video)

2.1.2.7 Installing MariaDB Windows ZIP


Packages
Users need to run mysql_install_db.exe, 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

2.1.2.8 Compiling MariaDB From Source


Get, Build and Test Latest MariaDB the Lazy Way
Instructions for people who don't have time to read the whole manual.

MariaDB Source Code


17 How to get the source code for MariaDB from GitHub.

Build Environment Setup for Linux


7 Requirements and build environment setup for Linux.
1416/3812
Generic Build Instructions
7 Instructions to help compile MariaDB from source.

Compiling MariaDB with Extra Modules/Options


Articles on compiling MariaDB with extra modules and options

Creating the MariaDB Source Tarball


How to create a source tar.gz file

Creating the MariaDB Binary Tarball


How to generate binary tar.gz files

Build Environment Setup for Mac


1 Setting up the build environment for Mac

Building MariaDB from a Source RPM


How to build MariaDB from a source RPM (SRPM).

Building MariaDB on CentOS


11 CentOS build requirements and steps.

Building MariaDB on Fedora


Guide to building MariaDB from source code on Fedora Linux.

Building MariaDB on Debian


Steps to compiling MariaDB on Debian Linux.

Building MariaDB on FreeBSD


How to build MariaDB on FreeBSD.

Building MariaDB on Gentoo


Steps to build MariaDB on Gentoo

Building MariaDB on Solaris and OpenSolaris


Links and notes for building MariaDB on Solaris and OpenSolaris

Building MariaDB on Ubuntu


Requirements and steps for building MariaDB on Ubuntu.

Building MariaDB on Windows


Instructions for building MariaDB on Windows.

Installing MariaDB Server on macOS Using Homebrew


3 Installing MariaDB on macOS via the Homebrew package manager, the "missing ...

Compiling with the InnoDB Plugin from Oracle


Compiling MariaDB with the InnoDB plugin from Oracle.

Creating a Debian Repository


Instructions for creating your own Debian repository

Building MariaDB From Source Using musl-based GNU/Linux


Instructions on compiling MariaDB on musl-based operating systems (Alpine)

Compiling MariaDB for Debugging


1 Passing -DCMAKE_BUILD_TYPE=Debug to cmake to compile with debug information.

Cross-compiling MariaDB
To cross-compile with cmake you will need a toolchain file

MariaDB Source Configuration Options


Options for configuring a MariaDB source distribution.

Building RPM Packages From Source


Building MariaDB RPM packages with CMake and CPackRPM.

Compile and Using MariaDB with Sanitizers (ASAN, UBSAN, TSAN, MSAN)
How to compile and use MariaDB with AddressSanitizer (ASAN).

1417/3812
There are 15 related questions .

2.1.2.8.1 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


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
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
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)


cd mysql-test
mtr --parallel=8 --force

Install the Default Databases


./scripts/mariadb-install-db --srcdir=.

(Older MariaDB version use mysql_install_db)

Install the Server (If needed)


You can also run and test mariadb directly from the build directory, in which case you can skip the rest of the steps
below.

make install

Start the Server


Start the server in it's own terminal window for testing. Note that the directory depends on your system!

/usr/sbin/mysqld

1418/3812
2.1.2.8.2 MariaDB Source Code
Checking out the Source with Git
The MariaDB source is hosted on GitHub: https://github.com/MariaDB/server
If you want a source tarball for a specific released MariaDB version, you can find it at http://downloads.mariadb.org .
At any given time, developers will be working on their own branches locally or on GitHub, with the main MariaDB
branches receiving pushes less often.
The main MariaDB branches are:
10.9
10.8
10.7
10.6
10.5
10.4
10.3
10.2
Source repositories for the MariaDB Connectors are:
MariaDB Connector/C
MariaDB Connector/J
MariaDB Connector/Node.js
MariaDB Connector/ODBC
MariaDB Connector/Python
See the Using git page for instructions on how to use git to check out the source code and switch between the various
branches.

2.1.2.8.3 Build Environment Setup for Linux


Contents
1. Required Tools
2. See Also

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 CentOS, and Building MariaDB on Gentoo pages for specific requirements for those platforms.
git
gunzip
GNU tar
gcc/g++ 4.8.5 or later, recommend above 9 or clang/clang++
GNU make 3.75 or later or Ninja
bison (3.0)
libncurses
zlib-dev
libevent-dev
cmake above 2.8.7 though preferably above 3.3
gnutls or openssl
jemalloc (optional)
valgrind (only needed if running mysql-test-run --valgrind)
libcurl (only needed if you want to use the S3 storage engine)
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.

1419/3812
# dnf builddep mariadb-server

CentOS has a separate utility yum-builddep , which is part of the yum-utils package. This works like the DNF
builddep command.

# yum install yum-utils


# yum-builddep mariadb-server

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 and then
using the Generic Build Instructions to build MariadB (or following the steps for your Linux distribution or Creating a
MariaDB Binary Tarball).

See Also
Installing Galera from source

2.1.2.8.4 Generic Build Instructions


Contents
1. Using cmake
2. Using BUILD Scripts
3. Starting MariaDB for the First Time
4. Testing MariaDB
5. Increasing Version Number or Tagging a
Version
6. Non-ascii Symbols
7. Post-install Tasks

The instructions on this page will help you compile MariaDB from source. Links to more complete instructions for
specific platforms can be found on the source page.
1420/3812
First, get a copy of the MariaDB source.
Next, prepare your system to be able to compile the source.
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 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

1421/3812
compile-
Compile an optimized binary optimized for 64 bit pentium (works also for amd64)
pentium64
compile-
pentium- Compile a debug binary optimized for 64 bit pentium
debug
compile- Compile a debug binary that can be used with valgrind to find wrong memory accesses and
pentium- memory leaks. Should be used if one want's to run the mysql-test-run test suite with the --
valgrind-max 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 .
The binary is compiled with all symbols (gcc -g) and the DBUG log system is
-debug
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 mysql_install_db 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/mysql_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:

1422/3812
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 .

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 (mysql_install_db)
Starting and Stopping MariaDB Automatically

2.1.2.8.5 Compiling MariaDB with Extra


Modules/Options
Compiling MariaDB with TCMalloc
TCMalloc is a malloc replacement library optimized for multi-threaded usage.

Compiling MariaDB with Vanilla XtraDB


Sometimes, one needs to have MariaDB compiled with Vanilla XtraDB. This pag...

Specifying Which Plugins to Build


Specifying which plugins to build.

2.1.2.8.5.1 Compiling MariaDB with TCMalloc


TCMalloc 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 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

2.1.2.8.5.2 Specifying Which Plugins to Build


1423/3812
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.
the plugin will be compiled dynamically, if supported. Otherwise it will be not compiled. This is the default
DYNAMIC
behavior.
AUTO the plugin will be compiled statically, if supported. Otherwise it will be compiled dynamically.
same as AUTO, but if plugin prerequisites (for example, specific libraries) are missing, it will not be
YES
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.

2.1.2.8.6 Creating the MariaDB Source Tarball


How to create a source tar.gz file.
First Setup your build environment.
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.

2.1.2.8.7 Creating the MariaDB Binary Tarball


How to generate binary tar.gz files.
Setup your build environment.
Build binaries with your preferred options/plugins.

MariaDB until 5.3


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

MariaDB starting with 5.5

1424/3812
If the binaries are already built, you can generate a binary tarball with
make package

2.1.2.8.8 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 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
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 page.
When building with Mac, you'll need -DOPENSSL_ROOT_DIR=/usr/local/openssl passed as a cmake argument to build
against openssl correctly.

2.1.2.8.9 Building MariaDB From a Source


RPM
2.1.2.8.10 Building MariaDB on CentOS
Contents
1. Installing Build Dependencies
2. Building MariaDB
3. Creating MariaDB-compat package
4. Additional Dependencies
5. More about CMake and CPackRPM

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


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-builddep mariadb-server

Running this command installs many of the build dependencies, but it doesn't install all of them. Not all the required
packages are noted and it's run against the official CentOS package of MariaDB, not necessarily the version that you
want to install. Use YUM to install the remaining packages.

1425/3812
# yum install git \
gcc \
gcc-c++ \
bison \
libxml2-devel \
libevent-devel \
rpm-build

In addition to these, you also need to install gnutls or openssl , depending on the TLS implementation you want to
use.
For more information on dependencies, see Linux Build Environment.

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

With the source repository cloned onto your system, you can start building MariaDB. Run CMake to read MariaDB for
the build,

$ cmake -DRPM=centos7 server/

Once CMake readies the relevant Makefile for your system, use Make to build MariaDB.

$ make package

This generates an RPM file, which you can then install on your system or copy over to install on other CentOS hosts.

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

2.1.2.8.11 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.

1426/3812
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

2.1.2.8.12 Building MariaDB on Debian


Contents
1. Installing Build Dependencies
2. Building MariaDB
1. After Building

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.
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 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

1427/3812
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 page for
instructions.

2.1.2.8.13 Building MariaDB on FreeBSD


Contents
1. Using Ports
1. Building MariaDB from Ports
2. Using Poudriere
1. Building MariaDB
2. Using Poudriere Repositories

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.

1428/3812
# 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 . 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

1429/3812
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 httpspkg.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

2.1.2.8.14 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

2.1.2.8.15 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 x86

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.

2.1.2.8.16 Building MariaDB on Ubuntu

1430/3812
Contents
1. Installing Build Dependencies
2. Building MariaDB
1. Further Dependencies
2. After Building

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 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

After Building
After building the packages, it is a good idea to put them in a repository. See the Creating a Debian Repository page for
instructions.

2.1.2.8.17 Building MariaDB on Windows

1431/3812
Contents
1. Build Requirements
2. Building Windows Binaries
3. Build Variations
1. Debug Builds
2. 32bit and 64 bit Builds
1. Build 64 bit binary
2. Build 32 bit binary
3. IDE Builds
4. Building the ZIP Package
5. Building the MSI Package
6. Including HeidiSQL in the MSI Installer
7. Code Signing Support for MariaDB
Release Processing
8. Building Packages for MariaDB Releases
9. Running Tests
1. Running a Test Under Debugger

Build Requirements
To build MariaDB you need the following:
Visual C++ : 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++".
CMake : 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 : 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 : 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 . Instead, install into C:\GnuWin32 .
Add C:\GnuWin32\bin to your system PATH after installation.
Strawberry perl : Used to run the test suite. ActiveState Perl 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 . If you build MSI with 10.4, also
modify your Visual Studio installation, add "Redistributable MSMs" (see MDEV-22555 )
Gnu Diff , needed if you run mysql-test-run.pl tests.
Verify that bison.exe, bzr.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 or higher.
Branch the MariaDB bzr 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
1432/3812
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 , it is possible to build an installer which includes 3rd party products, as described in
MWL#200 . Currently only HeidiSQL 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 Support for MariaDB Release Processing


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:

1433/3812
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

2.1.2.8.19 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


1434/3812
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.

2.1.2.8.20 Building MariaDB From Source


Using musl-based GNU/Linux
Instructions on compiling MariaDB on musl-based
operating systems (Alpine)
Contents
1. Instructions on compiling MariaDB on
musl-based operating systems (Alpine)
2. Using cmake

The instructions on this page will help you compile MariaDB from source. Links to more complete instructions for
specific platforms can be found on the source page.
First, get a copy of the MariaDB source.
Next, prepare your system to be able to compile the source.

Using cmake
MariaDB 10.1 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.

2.1.2.8.21 Compiling MariaDB for Debugging

1435/3812
Contents
1. Compiling MariaDB for Debugging Using
the CMAKE_BUILD_TYPE Option
2. Compiling MariaDB for Debugging Using
Build Scripts
1. Example of Compiling MariaDB for
Debugging Using Build Scripts
3. Building Optimized Build With Debug
Symbols
4. Doing a Debug Build on Debian/Ubuntu
1. Temporarily Installing your Debug
Build
2. Reinstalling your Release Build
5. Different Compilation Options
1. Changing DBUG_ASSERT to Print to
Error Log
6. See Also

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 memory checking tool with the MariaDB test system:

./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.

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 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:

1436/3812
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 .
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 .


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 .
Then, execute the following command to delete the symbolic link:

1437/3812
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 .


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.

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
Debugging MariaDB with a debugger
Creating a trace file
Using ASAN with MariaDB

2.1.2.8.22 Cross-compiling MariaDB


Buildroot
Buildroot 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 . 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 ..

1438/3812
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

2.1.2.8.23 MariaDB Source Configuration


Options
Contents
1. See Also

All CMake configuration options for MariaDB can be displayed with:

cmake . -LH

See Also
Get the Code, Build it, Test it (mariadb.org)
Generic Build Instructions

2.1.2.8.24 Building RPM Packages From


Source
To generate RPM packages from the build, supply the -DRPM=yes flag to CMake.
The value yes (or whatever) will build generic RPM packages. It is also possible to use one of these special values
that will slightly modify what kind of layout the resulting RPM packages will have:
fedora
centos7/rhel7
centos8/rhel8
sles
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

See Also
About the MariaDB RPM Files
Building MariaDB on CentOS
Installing MariaDB RPM Files
MariaDB RPM Packages

2.1.2.8.25 Compile and Using MariaDB with


Sanitizers (ASAN, UBSAN, TSAN, MSAN)
Contents
1. What are Sanitizers?
2. How to Compile MariaDB with Sanitizers
3. Running an ASAN Build
1. Using Valgrind
4. See Also

1439/3812
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) is a memory error detector for C/C++. It finds a lot of the same things as valgrind, 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)
ThreadSanitizer (aka TSAN)
MemorySanitizer (aka MSAN)

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 and up.


You can use one of the two following build commands:

cmake . -DWITH_ASAN=ON

or from MariaDB 10.2 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 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 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:

1440/3812
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 can use Valgrind 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 to run the test under Valgrind.

See Also
Compiling MariaDB for debugging

2.1.2.9 Distributions Which Include MariaDB


Contents
1. Linux Distributions
2. BSD Distributions
3. macOS

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
Alpine Linux — Defaults to MariaDB. MariaDB 10.6 has been available 3.12.11
4mLinux — Defaults to MariaDB. MariaDB 10.7 has been available since 39.0
ALT Linux — MariaDB 5.5 included in 7.0.0, MariaDB is default from 8.1, which includes MariaDB 10.1, 9.1 includes MariaDB 10.4
Arch Linux — Features MariaDB 10.8, and replaced MySQL as a default
Asianux — MariaDB 5.5 replaced MySQL in 7.
Austrumi — Defaulted to MariaDB 5.3 in 2.4.8, 3.5.8 includes MariaDB 10.1
BlackArch — Defaulted to MariaDB 5.5 in 2014.07.01, 2020.12.01 includes MariaDB 10.5
BlueOnyx — 5209 defaults to MariaDB 5.5, 5210R to MariaDB 10.3
BlueStar — 4.8.4 defaults to MariaDB 10.1, 5.4.2 to MariaDB 10.5
CentOS — MariaDB 5.5 replaced MySQL in CentOS 7
The Chakra Project — MariaDB replaced MySQL as default in 2013.05. 2016.02 includes MariaDB 10.1
Debian — Debian 8 "Jessie" includes MariaDB 10.0, Debian 9 "Stretch" MariaDB 10.1, Debian 10 "Buster" MariaDB 10.3, Debian 11
"Bullseye" MariaDB 10.5 as default.
Elastix —Defaulted to MariaDB 5.5 in 4.0.76
Exherbo —Includes MariaDB 10.4
Fedora — MariaDB 5.5 became the default relational database in Fedora 19. Fedora 30 includes MariaDB 10.3 , Fedora 34 includes
MariaDB 10.5 .
Funtoo —Includes MariaDB 5.5
Gentoo Linux
Guix —11.2.0 includes MariaDB 10.1
Hanthana — 19.1 defaulted to MariaDB 5.5, 21 includes MariaDB 10.0, 28.1.2 includes MariaDB 10.2, 30 includes MariaDB 10.3
KaOS —Defaulted to MariaDB 5.5 in 2014.12, 2019.04 includes MariaDB 10.3
Kali Linux —2017.3 Included MariaDB 10.1, 2021.1 includes MariaDB 10.5
GNU/Linux KDu — MariaDB 5.5 replaced MySQL as a default in 2.0 Final.
Korora —Defaulted to MariaDB in 19.1, 26 includes MariaDB 10.1
Linux from Scratch —10.1-BLFS defaults to MariaDB 10.5
Lunar —1.7.0 includes MariaDB 5.5, Moonbase includes MariaDB 10.5
Mageia — MariaDB 5.5 replaced MySQL as default in version 3, MariaDB 10.3 from version 7.1, MariaDB 10.5 from 8.
Manjaro Linux — Defaulted to MariaDB 5.5 in 0.8.11, 16.10.3 includes MariaDB 10.1.
1441/3812
NixOS —14.0.4.630 included MariaDB 10.0, 18.09 includes MariaDB 10.2, Stable includes MariaDB 10.5
Network Security Toolkit —20-5663 defaulted to MariaDB 5.5, 32-11992 includes MariaDB 10.4
NuTyX —14.11 included MariaDB 10.0, defaulted to MariaDB 10.1 in 8.2.1, 20.12.1 includes MariaDB 10.5
OpenELEC
OpenEuler —21.9 includes 10.5 , 22.03 LTS includes MariaDB 10.5
Open Mandriva —Defaulted to MariaDB 10.0 in 2014.2, includes MariaDB 10.5 in 4.2
openSUSE — MariaDB 5.5 became the default relational database in openSUSE 12.3 , and MariaDB 10.4 the default since 15.2
Oracle Linux — 7.3 includes MariaDB 5.5. 8.0 includes MariaDB 10.3
Paldo —Defaults to MariaDB 10.5 in Stable
Parabola GNU/Linux —Includes MariaDB 10.1 since 3.7
Parrot Security —Based on Debian's testing branch (stretch), Parrot Security switched from MySQL to MariaDB 10.0 in 3.1, 4.7 includes
MariaDB 10.3
Parted Magic —Defaulted to MariaDB 5.5 in 2015_11_13
PCLinuxOS —Replaced MySQL with MariaDB 10.1 in 2017.03
Pisi Linux —Defaulted to MariaDB 10.0 in 1.1
Plamo —Defaulted to MariaDB 5.5 in 5.3.1, 7.3 includes MariaDB 10.2
PoliArch —Defaulted to MariaDB 5.5 in 13.1, 15.1 includes MariaDB 10.0
Red Hat Enterprise Linux — MariaDB 5.5 was included as the default "MySQL" database since RHEL 7, RHEL 9 includes MariaDB
10.5
ROSA —Defaulted to MariaDB 10.0 in R4 and MariaDB 10.1 in R9.
Sabayon —Included MariaDB 10.0 in 14.12, includes MariaDB 10.3 since 19.03
Scientific Linux —Defaulted to MariaDB 5.5 in 7.3
Slackware — MariaDB 5.5 replaced MySQL as default in 14.1. 14.2 includes MariaDB 10.0, current includes MariaDB 10.5
SliTaz GNU/Linux —Includes MariaDB 10.0 in 5.0-rolling
SME Server — started to use MariaDB 5.5 from 10.0
Springdale Linux —Defaulted to MariaDB 5.5 in 7.2, 8.1 includes MariaDB 10.3
SuliX — Defaults to MariaDB 5.5 in 8.
SUSE Linux Enterprise — MariaDB 10.0 is the default relational database option on 12-SP2, 15-SP2 includes MariaDB 10.4
Ubuntu —MariaDB 5.5 was included in Trusty Tahr 14.04. 20.04 includes MariaDB 10.3 , and 22.04 includes 10.6 .
Void — Includes MariaDB 10.5 in current
Wifislax — Defaulted to MariaDB 10.0 in 4.11.1

BSD Distributions
Dragonfly BSD — 3.8 included MariaDB 5.5. 5.8.0 includes MariaDB 10.4.
FreeBSD — MariaDB is available in the ports tree and the FreeBSD Manual has instructions on Installing Applications: Packages and
Ports . MariaDB 10.5 is included in 12.2
MariaDB on FreshPorts
NetBSD — 6.1 and 7.0 include MariaDB 5.5.
OpenBSD — MariaDB 10.0 was included in 5.7, 6.8 includes MariaDB 10.5.

macOS
Homebrew — 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.
MacPorts —This provides mariadb and mariadb-server . A quick guide on how to install it.

2.1.2.10 Running Multiple MariaDB Server


Processes
Contents
1. Configuring Multiple MariaDB Server
Processes
2. Starting Multiple MariaDB Server
Processes
1. Service Managers
1. Systemd
2. Starting the Server Process Manually
1. mysqld
2. mysqld_safe
3. mysqld_multi
3. Other Options

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


1442/3812
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 , port , and socket . The following example shows these options set
in an option file:

[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 .
To see the current values set for an instance, see 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 for more information.

Service Managers
sysVinit and systemd are the most common Linux service managers. launchd is used in MacOS X. Upstart 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 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.

Starting the Server Process Manually


mysqld
mysqld 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, then you can use the --defaults-file option:

mysqld --defaults-file=/etc/my_instance1.cnf

mysqld_safe
mysqld_safe is a wrapper that can be used to start the mysqld server process. The script has some built-in
safeguards, such as automatically restarting the server process if it dies. See mysqld_safe for more information.
If you want to force each instance to read only a single option file, then you can use the --defaults-file option:

mysqld_safe --defaults-file=/etc/my_instance1.cnf

mysqld_multi
mysqld_multi is a wrapper that can be used to start the mysqld server process if you plan to run multiple server
processes on the same host. See mysqld_multi for more information.

1443/3812
Other Options
In some cases, there may be easier ways to run multiple MariaDB Server instances on the same server, such as:
Using dbdeployer.
Starting multiple Docker containers.

2.1.2.11 Installing MariaDB Alongside MySQL


MariaDB was 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 - 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:

1444/3812
[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 mysqladmin 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/mysqladmin add --defaults-file=/opt/mariadb-data/my.cnf. The lines should look like:

wait_for_ready () {
[...]
if $bindir/mysqladmin --defaults-file=/opt/mariadb-data/my.cnf ping >/dev/null 2>&1; then

Run mysql_install_db by explicitly giving it the my.cnf file as argument:

[root@mariadb-near-mysql opt]# cd mariadb


[root@mariadb-near-mysql mariadb]# scripts/mysql_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
1445/3812
2.1.2.12 GPG
Contents
1. Debian / Ubuntu key
2. RPM / Source key
3. Configuring

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 , 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

The instructions in the repository configuration tool for Ubuntu 16.04 "Xenial" and Debian "Stretch" and higher have
been updated to reference this new key. Repositories for previous versions of Debian and Ubuntu still use the old key,
so no changes are needed there.

RPM / Source key


The GPG Key ID of the MariaDB signing key we use for yum/dnf/zypper repositories and to sign our source code
tarballs is 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 is 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
See the repository configuration tool for details on configuring repositories that use these keys.

2.1.2.13 MariaDB Deprecation Policy


Contents
1. Current Package Platforms
2. Deprecated Package Platforms
3. Support for Deprecated Platforms
4. See Also

The MariaDB Foundation tries to support as many different Operating Systems, Linux Distributions, and processor
architectures as possible. However, when a distribution or OS stops receiving security and other updates it becomes
difficult for the MariaDB project to provide freely packages for that platform. In such cases, our policy is to deprecate the
platform and stop providing binary packages for it.
This policy and related deprecated dates are from the MariaDB Foundation . For information on the MariaDB
Corporation's policies related to supporting software, see the Engineering Policies page.

Current Package Platforms


1446/3812
The MariaDB project builds packages for the following:

Platform Planned Deprecation Date


Windows 8.1 Jan 2023
Ubuntu 18.04 "Bionic" Apr 2023
Windows Server 2012 R2 Oct 2023
Red Hat Enterprise Linux 7.x (x86_64 only) Jun 2024
CentOS 7.x (x86_64 only) Jun 2024
Debian 10 "Buster" (i386, amd64 and arm64) Jun 2024
SLES 12.x Oct 2024
Ubuntu 20.04 "Focal" Apr 2025
Debian 11 "Bullseye" Jun 2026
Ubuntu 22.04 "Jammy" Apr 2027
SLES 15.x Jul 2028
Red Hat Enterprise Linux 8.x Jun 2029
Red Hat Enterprise Linux 9.x Jun 2032

Fedora 35 approximately 1 month after release of Fedora 37


Fedora 36 approximately 1 month after release of Fedora 38
SLES 12.5 6 months after release of SLES 12.6
SLES 15.0 6 months after release of SLES 15.1

Ubuntu Release Information (End of Standard Support)


Debian LTS Information (i386, amd64 and arm64 only)
General Debian Release Information
Red Hat Enterprise Linux Release Information
Fedora Release Information
FreeBSD Security Information
openSUSE Lifetime Information
SLES Lifecycle Information
Windows client Lifecycle Information
Windows Server Lifecycle Information

Deprecated Package Platforms


The MariaDB project no longer builds packages for the following Operating Systems and Linux Distributions:

Deprecation
Platform Final MariaDB Version(s)
Date
Debian 10 "Buster" MariaDB 10.3.36, MariaDB 10.4.26, MariaDB 10.5.17, MariaDB 10.6.9,
Jul 2022
(ppc64el) MariaDB 10.7.5, MariaDB 10.8.4
MariaDB 10.5.16, MariaDB 10.6.8, MariaDB 10.7.4, MariaDB 10.8.3,
Ubuntu 21.10 "Impish" Jul 2022
MariaDB 10.9.1
MariaDB 10.2.44 , MariaDB 10.3.35, MariaDB 10.4.25, MariaDB 10.5.16,
Debian 9 "Stretch" Jun 2022
MariaDB 10.6.8, MariaDB 10.7.4, MariaDB 10.8.3, MariaDB 10.9.1
Red Hat Enterprise MariaDB 10.2.44 , MariaDB 10.3.35, MariaDB 10.4.25, MariaDB 10.5.16,
May 2022
Linux 7.x (non-x86_64) MariaDB 10.6.8, MariaDB 10.7.4, MariaDB 10.8.3, MariaDB 10.9.1
CentOS 7.x (non- MariaDB 10.2.44 , MariaDB 10.3.35, MariaDB 10.4.25, MariaDB 10.5.16,
May 2022
x86_64) MariaDB 10.6.8, MariaDB 10.7.4, MariaDB 10.8.3, MariaDB 10.9.1
MariaDB 10.5.16, MariaDB 10.6.8, MariaDB 10.7.4, MariaDB 10.8.3,
Fedora 34 May 2022 MariaDB 10.9.1

Ubuntu 21.04 "Hirsute" Feb 2022 MariaDB 10.7.2, MariaDB 10.6.6, MariaDB 10.5.14
Fedora 33 Feb 2022 MariaDB 10.7.2, MariaDB 10.6.6, MariaDB 10.5.14, MariaDB 10.4.23
MariaDB 10.7.2, MariaDB 10.6.6, MariaDB 10.5.14, MariaDB 10.4.23,
CentOS 8.x Feb 2022
MariaDB 10.3.33

1447/3812
Ubuntu 20.10 "Groovy" Jul 2021 MariaDB 10.6.4, MariaDB 10.5.12, MariaDB 10.4.21, MariaDB 10.3.31
Fedora 32 Apr 2021 MariaDB 10.5.10, MariaDB 10.4.19, MariaDB 10.3.29
Ubuntu 16.04 LTS
Apr 2021 MariaDB 10.5.10, MariaDB 10.4.19, MariaDB 10.3.29, MariaDB 10.2.38
"Xenial"
Mint 18 LTS "Serena" Apr 2021 MariaDB 10.5.10, MariaDB 10.4.19, MariaDB 10.3.29, MariaDB 10.2.38
Fedora 31 Nov 2020 MariaDB 10.5.7, MariaDB 10.4.16, MariaDB 10.3.26
Red Hat Enterprise
Nov 2020 MariaDB 10.4.16, MariaDB 10.3.26, MariaDB 10.2.35 , MariaDB 10.1.48
Linux 6.x
CentOS 6.x Nov 2020 MariaDB 10.4.16, MariaDB 10.3.26, MariaDB 10.2.35 , MariaDB 10.1.48
Fedora 30 Aug 2020 MariaDB 10.5.5, MariaDB 10.4.14, MariaDB 10.3.24
Ubuntu 19.10 "Eoan" Jul 2020 MariaDB 10.5.5, MariaDB 10.4.14, MariaDB 10.3.24
Debian 8 "Jessie" Jun 2020 MariaDB 10.4.13, MariaDB 10.3.23, MariaDB 10.2.32 , MariaDB 10.1.45
Ubuntu 19.04 "Disco" Jan 2020 MariaDB 10.4.12, MariaDB 10.3.22
Windows Server 2008 Jan 2020 MariaDB 10.4.12, MariaDB 10.3.22
Windows Server 2008
Jan 2020 MariaDB 10.4.12, MariaDB 10.3.22
R2
Windows 7 Jan 2020 MariaDB 10.4.12, MariaDB 10.3.22
Fedora 29 Dec 2019 MariaDB 10.4.11, MariaDB 10.3.21
Ubuntu 18.10 "Cosmic" Jul 2019 MariaDB 10.4.7, MariaDB 10.3.17, MariaDB 10.2.26 , MariaDB 10.1.41
openSUSE 42.3 Jun 2019 MariaDB 10.4.7, MariaDB 10.3.16, MariaDB 10.2.25 , MariaDB 10.1.41
Fedora 28 May 2019 MariaDB 10.4.5, MariaDB 10.3.15, MariaDB 10.2.24
Ubuntu 14.04 LTS MariaDB 10.4.4, MariaDB 10.3.14, MariaDB 10.2.23 , MariaDB 10.1.40 ,
Apr 2019
"Trusty" MariaDB 5.5.64
Mint 17.1 LTS MariaDB 10.4.4, MariaDB 10.3.14, MariaDB 10.2.23 , MariaDB 10.1.40 ,
Apr 2019
"Rebecca" MariaDB 5.5.64
MariaDB 10.4.4, MariaDB 10.3.14, MariaDB 10.2.23 , MariaDB 10.1.40 ,
Mint 17 LTS "Qiana" Apr 2019
MariaDB 5.5.64
SLES 11.4 Mar 2019 MariaDB 10.1.40 , MariaDB 5.5.64
Fedora 27 Nov 2018 MariaDB 10.3.11, MariaDB 10.2.19
Ubuntu 17.10 "Artful" Jul 2018 MariaDB 10.3.8, MariaDB 10.2.16 , MariaDB 10.1.34
Fedora 26 May 2018 MariaDB 10.3.7, MariaDB 10.2.15 , MariaDB 10.1.33
Debian 7 "Wheezy" May 2018 MariaDB 10.3.7, MariaDB 10.2.15 , MariaDB 10.1.33
Fedora 25 Feb 2018 MariaDB 10.3.5, MariaDB 10.2.13 , MariaDB 10.1.31
Ubuntu 17.04 "Zesty" Jan 2018 MariaDB 10.3.4, MariaDB 10.2.12 , MariaDB 10.1.30
openSUSE 42.2 Jan 2018 MariaDB 10.3.4, MariaDB 10.2.12 , MariaDB 10.1.30
Red Hat Enterprise MariaDB 10.3.3, MariaDB 10.2.12 , MariaDB 10.1.30 , MariaDB 10.0.33
Nov 2017
Linux 7.2 , MariaDB 5.5.58
MariaDB 10.3.3, MariaDB 10.2.12 , MariaDB 10.1.30 , MariaDB 10.0.33
CentOS 7.2 Nov 2017
, MariaDB 5.5.58
Fedora 24 Aug 2017 MariaDB 10.2.8
Ubuntu 16.10
Jul 2017 MariaDB 10.2.7 , MariaDB 10.1.26 , MariaDB 10.0.32
"Yakkety"
Ubuntu 12.04 LTS
Apr 2017 MariaDB 10.1.24 , MariaDB 10.0.31 , MariaDB 5.5.56
"Precise"
Mint 13 LTS "Maya" Apr 2017 MariaDB 10.1.24 , MariaDB 10.0.31 , MariaDB 5.5.56
Red Hat Enterprise
Mar 2017 MariaDB 10.1.24 , MariaDB 10.0.31 , MariaDB 5.5.56
Linux 7.1
CentOS 7.1 Mar 2017 MariaDB 10.1.24 , MariaDB 10.0.31 , MariaDB 5.5.56

1448/3812
Red Hat Enterprise
Mar 2017 MariaDB 10.1.22 , MariaDB 10.0.30 , MariaDB 5.5.54
Linux 5
CentOS 5 Mar 2017 MariaDB 10.1.22 , MariaDB 10.0.30 , MariaDB 5.5.54
Fedora 23 Feb 2017 MariaDB 10.2.4 , MariaDB 10.1.22 , MariaDB 10.0.30
OpenSUSE 13 Jan 2017 MariaDB 10.2.4 , MariaDB 10.1.22 , MariaDB 10.0.30
Fedora 22 Aug 2016 MariaDB 10.1.17 , MariaDB 10.0.27
Ubuntu 15.10 "Wily" Jul 2016 MariaDB 10.1.16 , MariaDB 10.0.26
Windows 2003 Server Apr 2016 MariaDB 10.1.13 , MariaDB 10.0.24 , MariaDB 5.5.48
Windows XP Apr 2016 MariaDB 10.1.13 , MariaDB 10.0.24 , MariaDB 5.5.48
Debian 6 "Squeeze" Feb 2016 MariaDB 10.0.24 , MariaDB 5.5.48

Ubuntu 15.04 "Vivid" Jan 2016 MariaDB 10.1.11 , MariaDB 10.0.24

Fedora 21 Dec 2015 MariaDB 10.1.10 , MariaDB 10.0.23


Fedora 20 Oct 2015 MariaDB 10.0.22 , MariaDB 5.5.46
Ubuntu 14.10 "Utopic" Jul 2015 MariaDB 10.0.22 , MariaDB 5.5.46
Ubuntu 10.04 LTS
Apr 2015 MariaDB 10.0.18 , MariaDB 5.5.43
"Lucid"
Mint 9 LTS "Isadora" Apr 2015 MariaDB 10.0.18 , MariaDB 5.5.43
Fedora 19 Apr 2015 MariaDB 10.0.18 , MariaDB 5.5.43
FreeBSD 9.2 Sep 2014
Ubuntu 13.10 "Saucy" Jul 2014 MariaDB 10.0.14 , MariaDB 5.5.40
Mint 16 "Petra" Jul 2014 MariaDB 10.0.14 , MariaDB 5.5.40
Ubuntu 12.10
Apr 2014 MariaDB 10.0.11 , MariaDB 5.5.37
"Quantal"
Mint 14 "Nadia" Apr 2014 MariaDB 10.0.11 , MariaDB 5.5.37
Ubuntu 13.04 "Raring" Jan 2014 MariaDB 10.0.8 , MariaDB 5.5.35
Mint 15 "Olivia" Jan 2014 MariaDB 10.0.8 , MariaDB 5.5.35
Fedora 18 Dec 2013 MariaDB 10.0.8 , MariaDB 5.5.35
Fedora 17 Aug 2013 MariaDB 10.0.5 , MariaDB 5.5.34
Ubuntu 8.04 LTS
Apr 2013 MariaDB 10.0.2 , MariaDB 5.5.31
"Hardy"
Ubuntu 11.10 "Oneiric" Apr 2013 MariaDB 10.0.2 , MariaDB 5.5.31
Mint 12 "Lisa" Apr 2013 MariaDB 10.0.2 , MariaDB 5.5.31
Fedora 16 Feb 2013 MariaDB 10.0.1 , MariaDB 5.5.29
Ubuntu 10.10
Jan 2013 MariaDB 10.0.1 , MariaDB 5.5.29
"Maverick"
Ubuntu 11.04 "Natty" Jan 2013 MariaDB 10.0.1 , MariaDB 5.5.29
Debian 5 "Lenny" Jan 2013 MariaDB 10.0.1 , MariaDB 5.5.29
Debian 4 "Etch"
Ubuntu 9.10 "Karmic"
Ubuntu 9.04 "Jaunty"
Ubuntu 8.10 "Intrepid"

Support for Deprecated Platforms


If your chosen Linux Distribution or Operating System is deprecated, packages or support are not completely
unavailable. The MariaDB Corporation provides support for all versions of MariaDB back to even very old MySQL
versions. This includes packaged binaries. For specific dates related to each version and more details on the MariaDB
Corporation's policies, see the Engineering Policies page.
1449/3812
See Also
MariaDB Bug Fixing Policy
MariaDB Maintenance Policy
MariaDB Engineering Policies

2.1.2.14 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.
Why to Automate MariaDB Deployments and Management
The reasons to automate deployment and configuration of MariaDB.

A Comparison Between Automation Systems


A summary of the differences between automation systems, to help evaluating them.

Ansible and MariaDB


General information and hints on automating MariaDB deployments with Ansible.

Puppet and MariaDB


General information on how to automate MariaDB deployments and configuration with Puppet.

Vagrant and MariaDB


General information on how to setup development MariaDB servers with Vagrant.

Docker and MariaDB


General information on how to setup MariaDB containers with Docker.

Kubernetes and MariaDB


General information and tips on deploying MariaDB on Kubernetes.

Automating Upgrades with MariaDB.Org Downloads REST API


How to use MariaDB.Org Downloads APIs to automate upgrades.

HashiCorp Vault and MariaDB


An overview of secret management with Vault for MariaDB users.

Orchestrator Overview
Using Orchestrator to automate failover and replication operations.

Rotating Logs on Unix and Linux


2 Rotating logs on Unix and Linux with logrotate.

Automating MariaDB Tasks with Events


Using MariaDB events for automating tasks.

2.1.2.14.1 Why to Automate MariaDB


Deployments and Management
MariaDB includes a powerful configuration system. 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.

Contents
1. Infrastructure as Code
2. Automated Failover
3. Resources

Infrastructure as Code
Several tools exist to deploy and manage several servers automatically. These tools operate at a higher level, and
1450/3812
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 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.
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 format.

Resources
Continuous configuration automation on Wikipedia .
Infrastructure as code on Wikipedia .

Content initially contributed by Vettabase Ltd .

2.1.2.14.2 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.

Contents
1. Code Structure Differences
1. Ansible Code Structure
2. Puppet Code Structure
2. Architectural Differences
1. Ansible Architecture
2. Puppet Architecture
1. Agent-Master Architecture
2. Standalone Architecture
3. Inventory
3. Storing Secrets
4. Ecosystems and Communities
1. Ansible Ecosystem
2. Puppet Ecosystem
5. See Also

1451/3812
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 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.
1452/3812
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 .
In the simplest case, Ansible allows encrypting secrets in playbooks and decrypting them during execution using
ansible-vault . 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 , who can provide support and consulting.
Ansible Galaxy 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 lists partners that can provide support and consulting about Puppet.
Puppet Forge 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.

1453/3812
See Also
For more information about the systems mentioned in this page, from MariaDB users perspective:
Ansible and MariaDB.
Puppet and MariaDB.

Content initially contributed by Vettabase Ltd .

2.1.2.14.3 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.
Ansible Overview for MariaDB Users
Overview of Ansible and how it works with MariaDB.

Deploying to Remote Servers with Ansible


How to invoke Ansible to run commands or apply roles on remote hosts.

Deploying Docker Containers with Ansible


How to deploy and manage Docker containers with Ansible.

Existing Ansible Modules and Roles for MariaDB


Links to existing Ansible modules and roles for MariaDB.

Installing MariaDB .deb Files with Ansible


How to install MariaDB from .deb files using Ansible.

Running mariadb-tzinfo-to-sql with Ansible


Updating the timezone tables with mariadb-tzinfo-to-sql using Ansible.

Managing Secrets in Ansible


How to store passwords as part of an Ansible repository.

2.1.2.14.3.1 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 in Ansible documentation.

Contents
1. Automation Hubs
2. Design Principles
3. Concepts
1. Example
4. Architecture
5. Ansible Resources and References

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 . 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 . 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.

1454/3812
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 tasks. 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.
1455/3812
"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, 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. 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
AWX
Ansible Tower
Ansible Galaxy
Ansible on Wikipedia
Ansible Automation Platform YouTube channel
Ansible: Getting Started
MariaDB Deployment and Management with Ansible (video)
Further information about the concepts discussed in this page can be found in Ansible documentation:
Basic Concepts .
Glossary .

Content initially contributed by Vettabase Ltd .

2.1.2.14.3.2 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 first, to understand Ansible general concepts.

Contents
1. Pinging Remote Servers
2. Running Commands on Remote Servers
3. Applying Roles to Remote Servers
1. Check mode
4. References

Pinging Remote Servers


1456/3812
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. 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.
1457/3812
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 tool.
ansible-playbook tool.
Validating tasks: check mode and diff mode .

Content initially contributed by Vettabase Ltd .

2.1.2.14.3.3 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 and Docker Compose. 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.
In this page we'll discuss how to use Ansible to manage Docker containers.

Contents
1. How to Deploy a Container with Ansible
2. References

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 .
docker_container module.

Content initially contributed by Vettabase Ltd .

2.1.2.14.3.4 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.
1458/3812
Contents
1. Modules
1. Other Useful Modules
1. shell and command
2. copy and template
3. Other Common Modules
2. Roles
3. See Also

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 in Ansible Galaxy contains at least the following modules:
mysql_db : manages MySQL databases.
mysql_info : gathers information about a MySQL server.
mysql_query : runs SQL queries against MySQL.
mysql_replication : configures and operates asynchronous replication.
mysql_user : creates, modifies and deletes MySQL users.
mysql_variables : 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 on GitHub.

Other Useful Modules


Let's see some other modules that are useful to manage MariaDB servers.

shell and command


Modules like shell and command allow one to run system commands.
To deploy on Windows, win_shell and win_command 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. 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 to remote servers.
The copy module 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

1459/3812
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 module, which compiles and copies templates written in Jinja .
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 , apt or yum . Package is package manager-agnostic. Use them to install, uninstall and upgrade
packages.
user , useful to create the system user and group that run MariaDB binary.
file 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 allows to create configuration files (like my.cnf) more dynamically, using the Jinja template
language.
service 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 and to probably be able to use some MariaDB specific features. 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 . Most roles are also available on GitHub.
You can also search roles using the ansible-galaxy tool:

ansible-galaxy search mariadb

See Also
MariaDB Deployment and Management with Ansible (video)

Content initially contributed by Vettabase Ltd .

2.1.2.14.3.5 Installing MariaDB .deb Files with


Ansible
This page refers to the operations described in Installing MariaDB .deb Files. 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.
1460/3812
Adding apt Repositories
To add a 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 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 and ansible.builtin.apt_repository 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 for MariaDB we can use the ansible.builtin.apt_key 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 .


1461/3812
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']
ansible_fact['distribution_major_version']
ansible_fact['os_family']
There is also a system-independent package module , but if the package names depend on the target system using it
may be of very little benefit.

See Also
Installing MariaDB .deb Files

Content initially contributed by Vettabase Ltd .

2.1.2.14.3.6 Running mariadb-tzinfo-to-sql with


Ansible
For documentation about the mariadb-tzinfo-to-sql utility, see mysql_tzinfo_to_sql. 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
1462/3812
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 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 .

2.1.2.14.3.7 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.

Contents
1. The SSH Password or Keys
2. Avoiding Sharing Secrets
3. ansible-vault

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 and an SSH configuration file as
ANSIBLE_NETCONF_SSH_CONFIG . These settings can be specified in Ansible configuration file or as environment
variables.
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 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. To know the hash of a password without even creating a user, we can use the PASSWORD()
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
1463/3812
secrets is usually a good idea. Ansible provides a native way to handle secrets: ansible-vault .
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 .

2.1.2.14.4 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.
Puppet Overview for MariaDB Users
Overview of Puppet and how it works with MariaDB.

Bolt Examples
How to invoke Bolt to run commands or apply roles on remote hosts.

Puppet hiera Configuration System


Using hiera to handle Puppet configuration files.

Deploying Docker Containers with Puppet


How to deploy and manage Docker containers with Puppet.

Existing Puppet Modules for MariaDB


Links to existing Puppet modules for MariaDB.

2.1.2.14.4.1 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 . 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 in Puppet documentation.

Contents
1. Design Principles
1. Defining Resources
2. Defining Nodes
2. Concepts
3. Architecture
1. Agent-master Architecture
2. Standalone Architecture
3. PuppetDB
4. External Node Classifiers
5. Bolt
4. hiera
5. Puppet Resources

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.
1464/3812
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:
1465/3812
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 . They can be core facts (collected by default) or custom facts (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.

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 to get an idea of what you can do with Bolt.
1466/3812
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 for more information.

Puppet Resources
Puppet documentation .
forge.puppet.com .
Puppet on GitHub .
Puppet on Wikipedia .
More information about the topics discussed in this page can be found in the Ansible documentation:
Puppet Glossary in Puppet documentation.
Overview of Puppet's architecture in Puppet documentation.
PuppetDB documentation .
Classifying nodes in Puppet documentation.
Hiera in Puppet documentation.
Bolt documentation .

Content initially contributed by Vettabase Ltd .

2.1.2.14.4.2 Bolt Examples


Contents
1. Inventory Files
2. Running Commands on Targets
3. Copying Files
4. Running Scripts on Targets
5. Running Tasks on Targets
6. Applying Puppet Code on Targets
7. Bolt Resources and References

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 ecosystem.
For information about installing Bolt, see Installing Bolt 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:

1467/3812
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 .
Bolt on GitHub .
1468/3812
Further information about the concepts explained in this page can be found in Bolt documentation:
Inventory Files in Bolt documentation.
Applying Puppet code in Bolt documentation.

Content initially contributed by Vettabase Ltd .

2.1.2.14.4.3 Puppet hiera Configuration System


hiera is part of Puppet. 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.

Contents
1. hiera Configuration Files
2. Configuration files

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 .

2.1.2.14.4.4 Deploying Docker Containers with


1469/3812
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.
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.

Contents
1. How to Install, Upgrade or Uninstall
Docker with Puppet
2. How to Build or Pull Docker Images with
Puppet
3. How to Deploy Containers with Puppet
4. References

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:

1470/3812
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 , in Puppet documentation.

Content initially contributed by Vettabase Ltd .

2.1.2.14.4.5 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.

Contents
1. Puppet Forge
2. Acceptance Tests
3. Supported Modules for MariaDB
4. Resources and References

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 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.

1471/3812
Resources and References
Puppet Forge website.
Puppet Development Kit documentation.
Modules overview in Puppet documentation.
Beginner's guide to writing modules in Puppet documentation.
Puppet Supported Modules page in Puppet Forge.

Content initially contributed by Vettabase Ltd .

2.1.2.14.5 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.
Vagrant Overview for MariaDB Users
Vagrant architecture, general concepts and basic usage.

Creating a Vagrantfile
How to create a new Vagrant box running MariaDB.

Vagrant Security Concerns


Security matters related to Vagrant machines.

Running MariaDB ColumnStore Docker containers on Linux, Windows and


MacOS
Docker allows for a simple setup of a ColumnStore single server instance for evaluation purposes

2.1.2.14.5.1 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 in Vagrant documentation.
In this page we discuss basic Vagrant concepts.

Contents
1. Vagrant Concepts
1. Example
2. Vagrantfiles
3. Providers
4. Provisioners
5. Plugins
6. Changes in Vagrant 3.0
2. Vagrant Commands
3. Vagrant Resources and References

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
1472/3812
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:

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 . 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 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 .
Vagrant Google Compute Engine (GCE) Provider .
Vagrant Azure Provider .
OpenVZ .
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 in Vagrant
documentation. The 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.

1473/3812
Other providers use automation software to provision the machine. There are provisioners that allow one to use Ansible,
Puppet, 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 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 . 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 .
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 (not necessarily Go). Vagrantfiles can also be written in HCL , HashiCorp
Configuration Language.

Vagrant Commands
This is a list of the most common Vagrant commands. For a complete list, see Command-Line Interface 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 .
app.vagrantup.com .
1474/3812
Vagrant Community .
Vagrant on Wikipedia .
Vagrant on HashiCorp Learn .

Content initially contributed by Vettabase Ltd .

2.1.2.14.5.2 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.

Contents
1. A Basic Vagrantfile
2. Providers
3. Provisioners
1. The shell Provisioner
2. Uploading Files
3. Provisioning Vagrant with Ansible
4. Provisioning Vagrant with Puppet
4. Sharing Files Between the Host and a
Guest System
5. Network Communications
1. Private Networks
2. Public Networks
3. Exposing Ports
4. Use Cases
6. References

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 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 , VMWare , Hyper-V ...), a container manager (Docker ), or remote cloud
hosts (AWS , Google Compute Engine ...).
1475/3812
Some providers are developed by third parties. app.vagrant.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 .
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 .

The shell Provisioner


In the example above, the 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
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. 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.
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:

1476/3812
Vagrant.configure("2") do |config|
...
config.vm.provision "ansible" do |ansible|
ansible.playbook = "vagrant.yml"
end
end

With the Ansible provisioner , 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 runs the playbook in the vagrant
machine.
For more information, see Using Vagrant and Ansible in the Ansible documentation. For an introduction to Ansible for
MariaDB users, see Ansible and MariaDB.

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 and the Puppet Agent Provisioner .
For an introduction to Puppet for MariaDB users, see Puppet and MariaDB.

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;
1477/3812
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
1478/3812
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 of three MariaDB servers, and the application servers communicate with them
via a proxy layer (ProxySQL, HAProxy, or MaxScale ). 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 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 .
Providers .
Synced Folders .
Ansible Provisioner .
Puppet Apply Provisioner .
Puppet Agent Provisioner .
See also Ruby documentation .

Content initially contributed by Vettabase Ltd .

2.1.2.14.5.3 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.

Contents
1. Access to the Vagrant Machine
2. Synced Folders
3. Reporting Security Bugs

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 for details.

Content initially contributed by Vettabase Ltd .


1479/3812
2.1.2.14.5.4 Running MariaDB ColumnStore
Docker containers on Linux, Windows and
MacOS
Contents
1. Introduction
2. Windows Linux Subsystem
3. Docker

Introduction
Docker 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 Docker image
uses a base OS of CentOS and currently require separate download of the CentOS RPM install bundle.

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.

Docker
Docker manages lightweight containers that allows for creation of lightweight and reproducible containers with a
dedicated function. On Windows and MacOS systems, Docker 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 docker image can be found at MariaDB on docker hub .

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 Docker containers, see Installing and Using MariaDB via Docker.
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 for more
information.

2.1.2.14.6 Docker and MariaDB


Docker is an open source container manager that can be used to quickly create ephemeral containers running specific
software. Docker containers can be used for production, development or testing, though it is not the preferred choice to
run MariaDB in production.
Benefits of Managing Docker Containers with Orchestration Software
Benefits of managing Docker with Automation Software.

Installing and Using MariaDB via Docker


5 Creating and managing a MariaDB Docker container.

Running MariaDB ColumnStore Docker containers on Linux, Windows and


MacOS
Docker allows for a simple setup of a ColumnStore single server instance for evaluation purposes

Creating a Custom Docker Image


How to write a Dockerfile to create custom Docker images.
1480/3812
Setting Up a LAMP Stack with Docker Compose
2 How to use Docker Compose to set up containers running a LAMP stack.

Docker Security Concerns


Security matters related to Docker containers.

MariaDB Container Cheat Sheet


Get the images Images can be found on MariaDB Docker Hub. To get the list o...

MariaDB Docker Environment Variables


Environment variables can be passed on the docker run command line.

There are 9 related questions .

2.1.2.14.6.1 Benefits of Managing Docker


Containers with Orchestration Software
In this page we'll discuss why automating Docker containers with software like Ansible or Puppet may be desirable in
some cases. To talk about this, we'll first need to discuss why Docker containers are defined ephemeral , and how this
applies to containerized database servers (particularly MariaDB).
During the discussion, we should keep in mind that Docker 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.

Docker's Ephemeral Nature


Docker images are compiled from Dockerfiles. Containers are created from 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, Docker has features called volumes and volume containers. We won't discuss the difference here, let's
focus on their purpose. 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 Docker 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 mysql_upgrade, but apart from that,

1481/3812
everything should just work.
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 Docker Containers


Docker containers can be deployed in the following ways:
Manually. See Installing and Using MariaDB via Docker. 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, 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 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 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. Docker can
work with Vagrant in two ways:
As a provisioner. 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. Vagrant will deploy one or more Docker 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 Docker Containers with


Automation Software
Docker 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:
Docker containers allow working without modifying the host system, and their creation is very fast. Much faster
than virtual machines. This makes Docker 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 Docker is 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 Docker is design to run a 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 Docker 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 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.

1482/3812
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 Docker 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 Docker network, using the standard 22 port (or another port of your choice) for all containers.

See Also
See these pages on how to manage Docker containers with different automation technologies:
Deploying Docker Containers with Ansible.
Deploying Docker Containers with Puppet.

Content initially contributed by Vettabase Ltd .

2.1.2.14.6.2 Installing and Using MariaDB via


Docker
Contents
1. Installing Docker on Your System with
the Universal Installation Script
1. Starting dockerd
2. Using MariaDB Images
1. Downloading an Image
2. Creating a Container
3. Running and Stopping the Container
1. Automatic Restart
2. Pausing Containers
4. Troubleshooting a Container
5. Accessing the Container
6. Connecting to MariaDB from Outside
the Container
1. Forcing a TCP Connection
2. Port Configuration for Clustered
Containers and Replication
3. Installing MariaDB on Another Image
1. Daemonizing the Operating System
2. Installing MariaDB
4. See Also

Sometimes we want to install a specific version of MariaDB, MariaDB ColumnStore, or MaxScale 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 in Docker documentation.

Installing Docker on Your System with the Universal


1483/3812
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 , 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. For example:

1484/3812
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

1485/3812
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 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 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 mysqladmin shutdown or the SHUTDOWN 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.
1486/3812
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 in the way we prefer.

See Also
1487/3812
Official MariaDB Docker Images Webinar .
Docker official site .
Docker Hub .
Docker documentation .

2.1.2.14.6.3 Running MariaDB ColumnStore


Docker containers on Linux, Windows and
MacOS
2.1.2.14.6.4 Creating a Custom Docker Image
OCI containers, frequently 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.

Contents
1. Images Architecture
2. Dockerfile Syntax
1. Using Variables
3. Versioning and Deploying Images
1. Container registries
2. Choosing Image Names and Tags
3. Pushing and Pulling Images
4. Docker Content Trust
4. Good Practices and Caveats
5. References

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
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:

Dockerfile Syntax
Here's a simple Dockerfile example:

1488/3812
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 ["mysqld"]

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 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: mysqld. 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 mysqld directly, rather than running mysqld_safe or running MariaDB as a
service. Containers restart can be handled by the container service. See 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

...

RUN mysqld --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. Here is an example:

ARG UBUNTU_VERSION
FROM ubuntu:$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.

1489/3812
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 containter 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 images created by both 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 don't contain the name of the maintainer. 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.5 is called mariadb:10.5 .
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 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.1 .

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.

1490/3812
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 .
docker build .
Repositories .
Deploy a registry server .
Content trust in Docker .
See also:
Privacy-Enhanced Mail on Wikipedia.

Content initially contributed by Vettabase Ltd .

2.1.2.14.6.5 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 in Docker documentation.

Contents
1. The docker-compose.yml File
1. About Volumes
2. Using Variables
2. Docker Compose Commands
3. Docker Compose Resources and
References

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:

1491/3812
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, 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:

1492/3812
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 in the Docker documentation.
Compose file in the Docker documentation.
Docker Compose on GitHub.
Further information about the concepts explained in this page can be found in Docker documentation:
Environment variables in Compose .
Overview of docker-compose CLI .
Compose command-line reference .

Content initially contributed by Vettabase Ltd .

2.1.2.14.6.6 Docker Security Concerns


When using Docker containers in production, it is important to be aware of Docker security concerns.

1493/3812
Contents
1. Host System Security
2. Images Security
3. References

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.
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 on Docker documentation.
Linux namespaces on Wikipedia.
cgroups on Wikipedia.
runC repository .

Content initially contributed by Vettabase Ltd .

2.1.2.14.6.7 MariaDB Container Cheat Sheet


Get the images
Images can be found on MariaDB Docker Hub .
To get the list of images run

$ docker images ls

Create the network

1494/3812
$ 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 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 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

1495/3812
See Also
Installing and using MariaDB via Docker

2.1.2.14.6.8 MariaDB Docker Environment


Variables
Contents
1. MARIADB_ROOT_PASSWORD /
MYSQL_ROOT_PASSWORD
2. MARIADB_ALLOW_EMPTY_ROOT_PASSWORD
/
MYSQL_ALLOW_EMPTY_PASSWORD
3. MARIADB_RANDOM_ROOT_PASSWORD
/
MYSQL_RANDOM_ROOT_PASSWORD
4. MARIADB_ROOT_HOST /
MYSQL_ROOT_HOST
5. MARIADB_MYSQL_LOCALHOST_USER
/
MARIADB_MYSQL_LOCALHOST_GRANTS
6. MARIADB_DATABASE /
MYSQL_DATABASE
7. MARIADB_INITDB_SKIP_TZINFO /
MYSQL_INITDB_SKIP_TZINFO

When you start the %%IMAGE%% image, you can adjust the initialization of the MariaDB 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, 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 / MYSQL_ROOT_PASSWORD
This specifies the password that will be set for the MariaDB root superuser account. In the above example, it was set to
my-secret-pw.

MARIADB_ALLOW_EMPTY_ROOT_PASSWORD /
MYSQL_ALLOW_EMPTY_PASSWORD
Set to a non-empty value, like yes, 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_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.
1496/3812
The mysql@localhost user gets 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 can result in confidentiality, integrity and availability risks, so use
a minimal set. See the example below on using Mariabackup. The healthcheck.sh script also documents the required
privileges for each health check test.

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 / MYSQL_PASSWORD
These are used in conjunction to create a new user and to set that user's password. Both user and password variables
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 note that there is no need to 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_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 mysql_upgrade/mariadb-
upgrade 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.

2.1.2.14.7 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.
Kubernetes Overview for MariaDB Users
An overview of Kubernetes and how it works with MariaDB.

Kubernetes Operators for MariaDB


An overview of Kubernetes operators that can be used with MariaDB

2.1.2.14.8 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 in
Kubernetes documentation.

1497/3812
Contents
1. Architecture
1. Nodes
1. kubelet
2. kube-proxy
3. Container Runtime
2. Controllers
3. Control Plane
1. API Server
2. kube-controller-manager
3. etcd
4. kube-scheduler
5. cloud-controller-manager
4. Clients and Tools
1. kubectl
2. kubeadm
3. kind and minikube
2. Kubernetes Resources and References

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.
Controllersconstantly 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 and Kubernetes 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 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 page in the Kubernetes documentation. More information about the Container Runtime Interface can be
found on GitHub .
Originally, Kubernetes used Docker as a container runtime. This was later deprecated, but Docker images can still be
used using any container runtime.

1498/3812
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 is working by issuing SHOW REPLICA STATUS
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 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 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 .
Kubernetes on Wikipedia.
1499/3812
Kubernetes organization on GitHub.
OperatorHub.io
Kubernetes Community Forums .
(video) MariaDB database clusters on Kubernetes , by Pengfei Ma, at MariaDB Server Fest 2020.
Series of posts by Anel Husakovic on the MariaDB Foundation blog:
Start MariaDB in K8s
MariaDB & K8s: Communication between containers/Deployments
MariaDB & K8s: Create a Secret and use it in MariaDB deployment
MariaDB & K8s: Deploy MariaDB and WordPress using Persistent Volumes
Create statefulset MariaDB application in K8s
MariaDB replication using containers
MariaDB & K8s: How to replicate MariaDB in K8s

Content initially contributed by Vettabase Ltd .

2.1.2.14.9 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 .

Contents
1. Custom Operators
2. MariaDB Operator
3. Other Operators

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), 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
OperatorHub.io has a MariaDB operator . At the time of this writing it is in alpha stage, so please check its maturity
before using it.
MariaDB operator is open source and is released under the terms of the MIT license. The source code is available on
GitHub . The README.md file shows usage examples.
It defines the following custom resources:
MariaDB server.
MariaDB Backup. mariabackup is used.
MariaDB Monitor. Prometheus metrics are exposed on port 9090.

Other Operators
If you know about other MariaDB operators, feel free to add them to this page (see Writing and Editing Knowledge Base
Articles ).
MySQL and Percona Server operators should work as well, though some changes may be necessary to fix
incompatibilities or take advantage of certain MariaDB features.

Content initially contributed by Vettabase Ltd .

2.1.2.14.10 Automating Upgrades with


MariaDB.Org Downloads REST API
1500/3812
The MariaDB Foundation maintains a Downloads REST API. See the Downloads API documentation 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 , to call HTTP URLs and get their output.
js , 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' [email protected] <<< '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 .

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:

1501/3812
#!/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 .

2.1.2.14.11 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, 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 .

Contents
1. Vault Features
2. Vault Architecture
3. Dev Mode
4. Vault Resources and References

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.

1502/3812
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 in Vault documentation.

Vault Resources and References


Documentation .
MySQL/MariaDB Database Secrets Engine .
MySQL Storage Backend .

Content initially contributed by Vettabase Ltd .

2.1.2.14.12 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 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 page. It is also included in the PMM monitoring
solution.
To install Orchestrator, see:
The install.md for a manual installation;
The links in README.md , to install Orchestrator using automation tools.

Contents
1. Supported Topologies
2. Architecture
3. CLI Examples
4. Orchestrator Resources and References

Supported Topologies
Currently, Orchestrator fully supports MariaDB GTID, replication, and semi-synchronous replication. While Orchestrator
does not support Galera specific logic, it works with Galera clusters. For details, see Supported Topologies and
Versions 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 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
1503/3812
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 .
Documentation .
Raft consensus protocol website .
The README.md file lists some related community projects, including modules to automate Orchestrator with Puppet
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 .

2.1.2.14.13 Rotating Logs on Unix and Linux


2.1.2.14.14 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
1504/3812
page is about using events for automation. For more information about events themselves, and how to work with them,
see event scheduler.

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, 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.
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 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 to a table and drop the oldest one (partition rotation).

Content initially contributed by Vettabase Ltd .

2.1.2.15 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:
1505/3812
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.

Contents
1. Repositories
1. MariaDB Repository
2. MariaDB MaxScale Repository
2. Supported Distributions
3. Using the MariaDB Package Repository
Setup Script
1. Options
1. --mariadb-server-version
2. --mariadb-maxscale-version
3. --os-type and --os-version
4. --write-to-stdout
2. Platform-Specific Behavior
1. Platform-Specific Behavior on
RHEL and CentOS
2. Platform-Specific Behavior on
Debian and Ubuntu
3. Platform-Specific Behavior on
SLES
4. Installing Packages with the MariaDB
Package Repository
1. Installing Packages on RHEL and
CentOS
2. Installing Packages on Debian and
Ubuntu
3. Installing Packages on SLES
5. Versions

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, client libraries , plugins, and Mariabackup.
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 .
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. 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.

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 .
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
1506/3812
the --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 , 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 . If you would like to know
how much a subscription to use MariaDB MaxScale would cost, see MariaDB Corporation's subscription pricing .

Supported Distributions
The script supports Linux distributions that are officially supported by MariaDB Corporation's MariaDB TX subscription
. 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 . Some Linux distributions also include MariaDB
in their own repositories.

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 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-
Override the default MariaDB Server version. By default, the script will use 'mariadb-10.5'.
version=<version>

--mariadb-
maxscale-version= Override the default MariaDB MaxScale version. By default, the script will use 'latest'.
<version>

--os-type=<type> Override detection of OS type. Acceptable values include debian , ubuntu , rhel , and sles .

1507/3812
--os-version=
Override detection of OS version. Acceptable values depend on the OS type you specify.
<version>

--skip-key-
Skip importing GPG signing keys.
import

--skip-maxscale Skip the 'MaxScale' repository.


--skip-server Skip the 'MariaDB Server' repository.
--skip-tools Skip the 'Tools' repository.
--skip-check-
Skip tests for required prerequisites for this script.
installed

Write output to stdout instead of to the OS's repository configuration file. This will also skip
--write-to-
importing GPG public keys and updating the package cache on platforms where that behavior
stdout
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. 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, 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.2
mariadb-10.3
mariadb-10.4
mariadb-10.5
mariadb-10.6
mariadb-10.7
If you want to pin the repository of a specific minor release, such as MariaDB 10.3.9, then you can also specify the
minor release. For example, mariadb-10.6.4 . This may be helpful if you want to avoid upgrades. However, avoiding
upgrades is not recommended, since minor releases can 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.

1508/3812
--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 .

1509/3812
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. 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 . 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. 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 .
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. 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 . For example:

sudo zypper install maxscale

Versions
Version sha256sum
2022-08-22 733cf126b03f73050e242102592658913d10829a5bf056ab77e7f864b3f8de1f
2022-08-15 f99e1d560bd72a3a23f64eaede8982d5494407cafa8f995de45fb9a7274ebc5c
2022-06-14 d4e4635eeb79b0e96483bd70703209c63da55a236eadd7397f769ee434d92ca8
2022-02-08 b9e90cde27affc2a44f9fc60e302ccfcacf71f4ae02071f30d570e6048c28597
2022-01-18 c330d2755e18e48c3bba300a2898b0fc8ad2d3326d50b64e02fe65c67b454599

2.1.3 Upgrading MariaDB


1510/3812
Upgrading Between Major MariaDB Versions
1 MariaDB is designed for easy upgrades.

Upgrading Between Minor Versions on Linux


1 Upgrading between minor versions of MariaDB, e.g. from MariaDB 10.4.12 to MariaDB 10.4.13

Upgrading from MariaDB 10.6 to MariaDB 10.7


How to upgrade from MariaDB 10.6 to MariaDB 10.7.

Upgrading from MariaDB 10.5 to MariaDB 10.6


2 How to upgrade from MariaDB 10.5 to MariaDB 10.6.

Upgrading from MariaDB 10.4 to MariaDB 10.5


How to upgrade from MariaDB 10.4 to MariaDB 10.5.

Upgrading from MariaDB 10.3 to MariaDB 10.4


How to upgrade from MariaDB 10.3 to MariaDB 10.4.

Upgrading from MariaDB 10.2 to MariaDB 10.3


2 How to upgrade from MariaDB 10.2 to MariaDB 10.3.

Upgrading from MariaDB 10.1 to MariaDB 10.2


12 How to upgrade from MariaDB 10.1 to MariaDB 10.2.

Upgrading from MariaDB 10.0 to MariaDB 10.1


3 How to upgrade from MariaDB 10.0 to MariaDB 10.1.

Upgrading from MariaDB 5.5 to MariaDB 10.0


5 How to upgrade from MariaDB 5.5 to MariaDB 10.0.

Upgrading from MariaDB 5.3 to MariaDB 5.5


How to upgrade from MariaDB 5.3 to MariaDB 5.5

Upgrading MariaDB on Windows


19 Upgrading MariaDB on Windows

Upgrading Galera Cluster


Upgrading MariaDB Galera Cluster.

Upgrading from MySQL to MariaDB


Upgrading from MySQL to MariaDB.

There are 23 related questions .

2.1.3.1 Upgrading Between Major MariaDB


Versions
Contents
1. Requirements for Doing an Upgrade
Between Major Versions
2. Recommended Steps
1. Step by step instructions for upgrades
3. Work Done by mysql_upgrade
4. Post Upgrade Work
5. If Something Goes Wrong
1. Disaster Recovery
6. Downgrading
7. See Also

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 5.5.x to MariaDB 10.5.x), usually in a few seconds. This is also mainly true for
any MySQL version < 8.0 to MariaDB 10.4 and up.
Upgrades are normally easy because:
All MariaDB table data files are backward compatible
1511/3812
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 slave can be of any newer version than the master.
MariaDB Corporation regularly runs tests to check that one can upgrade from MariaDB 5.5 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, you have to follow the Galera upgrading instructions!

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 is not supported.
Backup the database (just in case). At least, take a copy of the mysql data directory with mysqldump --add-drop-
table mysql as most of the upgrade changes are done there (adding new fields and new system tables etc).
Ensure that the innodb_fast_shutdown variable is not 2 (fast crash shutdown) or 3. The default of this variable is
1. The safest option for upgrades is 0, but the shutdown time may be notably larger with 0 than for 1 as there are
a lot more cleanups done for 0.
innodb_force_recovery must be less than 3 .
Cleanly shutdown of the server. This is necessary because even if data files are compatible between versions,
recovery logs may not be.
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 mysql_upgrade. Note that
when installing the new rpms, mysql_upgrade may be run automatically. There is no problem with running
mysql_upgrade many times.

Recommended Steps
If you have a master-slave setup, first upgrade one slave and when you have verified that the slave works well,
upgrade the rest of the slaves (if any). Then upgrade one slave to master, upgrade the master, and change the
master to a slave.
If you don't have a master-slave setup, then take a backup, shutdown MariaDB 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 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 mysql_upgrade will fix that.
Run mysql_upgrade
Restart MariaDB server.

Work Done by mysql_upgrade


The main work done when upgrading is done by running mysql_upgrade. The main things it does are:
Updating the system tables in the mysql database to the newest version. This is very quick.
mysql_upgrade also runs mysqlcheck --check-upgrade 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 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.
Check the manual for new features 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, optimizer trace or optimizer_switch to fix the queries.

1512/3812
If Something Goes Wrong
First, check the MariaDB error log 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 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 mysql_install_db 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 or CREATE TABLE statements and you have a mysqldump 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 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 mysqldump)
Delete the new MariaDB installation
Install the old MariaDB version
Start the server with mysqld --skip-grant-tables
Install the old mysql database
Execute in the mysql client FLUSH PRIVILEGES

See Also
Upgrading from MySQL to MariaDB
Upgrading from MariaDB 10.6 to MariaDB 10.7
Upgrading from MariaDB 10.5 to MariaDB 10.6
Upgrading from MariaDB 10.4 to MariaDB 10.5
Upgrading from MariaDB 10.3 to MariaDB 10.4
Upgrading from MariaDB 10.2 to MariaDB 10.3
Upgrading from MariaDB 10.1 to MariaDB 10.2
Upgrading from MariaDB 10.0 to MariaDB 10.1
Upgrading from MariaDB 5.5 to MariaDB 10.0
Galera upgrading instructions
innodb_fast_shutdown

2.1.3.2 Upgrading Between Minor Versions on


Linux
For Windows, see Upgrading MariaDB on Windows instead.

For MariaDB Galera Cluster, see Upgrading Between Minor Versions 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.

To upgrade between minor versions of MariaDB on Linux/Unix (for example from MariaDB 10.3.12 to MariaDB 10.3.13),
the following procedure is suggested:
1. Stop MariaDB .
1513/3812
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
4. Make any desired changes to configuration options in option files, such as my.cnf .
5. Start MariaDB .
6. Run mysql_upgrade .
mysql_upgrade does two things:
1. Ensures that the system tables in the mysql 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 from MariaDB 10.4 to MariaDB 10.5
Upgrading from MariaDB 10.3 to MariaDB 10.4
Upgrading from MariaDB 10.2 to MariaDB 10.3
Upgrading from MariaDB 10.1 to MariaDB 10.2
Upgrading from MariaDB 10.0 to MariaDB 10.1
Upgrading from MariaDB 5.5 to MariaDB 10.0

2.1.3.3 Upgrading from MariaDB 10.6 to


MariaDB 10.7
Contents
1. How to Upgrade
2. Incompatible Changes Between 10.6 and
10.7
1. Compression
2. Options That Have Been Removed or
Renamed
3. See Also

Note that MariaDB 10.7 is only maintained for one year . MariaDB 10.6 is currently the latest long-term
maintenance release.

How to Upgrade
For Windows, see Upgrading MariaDB on Windows.

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.

The suggested upgrade procedure is:


1. Modify the repository configuration, so the system's package manager installs MariaDB 10.7. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Updating the MariaDB ZYpp repository to
a New Major Release for more information.
2. Stop MariaDB.
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.
1514/3812
On Debian, Ubuntu, and other similar Linux distributions, see Installing MariaDB Packages with APT for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
5. Make any desired changes to configuration options in option files, such as my.cnf . This includes removing any
options that are no longer supported.
6. Start MariaDB.
7. Run mariadb-upgrade.
mariadb-upgrade does two things:
1. Ensures that the system tables in the mysql 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:

Compression
If a non-zlib compression algorithm was used in InnoDB or Mroonga before upgrading to 10.7, those tables will be
unreadable until the appropriate compression library is installed. See Compression Plugins#Upgrading.

Options That Have Been Removed or Renamed


The following options should be removed or renamed if you use them in your option files:

Option Reason
wsrep_replicate_myisam Use wsrep_mode instead.
wsrep_strict_ddl Use wsrep_mode instead.

See Also
The features in MariaDB 10.7
Upgrading from MariaDB 10.5 to MariaDB 10.6
Upgrading from MariaDB 10.4 to MariaDB 10.5
Upgrading from MariaDB 10.3 to MariaDB 10.4

2.1.3.4 Upgrading from MariaDB 10.5 to


MariaDB 10.6
Contents
1. How to Upgrade
2. Incompatible Changes Between 10.5 and
10.6
1. Reserved Word
2. InnoDB COMPRESSED Row Format
3. Character Sets
4. Options That Have Changed Default
Values
5. Options That Have Been Removed or
Renamed
6. Deprecated Options
3. Major New Features To Consider
4. See Also

How to Upgrade
For Windows, see Upgrading MariaDB on Windows.

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.
1515/3812
The suggested upgrade procedure is:
1. Modify the repository configuration, so the system's package manager installs MariaDB 10.6. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Updating the MariaDB ZYpp repository to
a New Major Release for more information.
2. Stop MariaDB.
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
5. Make any desired changes to configuration options in option files, such as my.cnf . This includes removing any
options that are no longer supported.
6. Start MariaDB.
7. Run mariadb-upgrade.
mariadb-upgrade does two things:
1. Ensures that the system tables in the mysql 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 )

Reserved Word
New reserved word: OFFSET. This can no longer be used as an identifier without being quoted.

InnoDB COMPRESSED Row Format


From MariaDB 10.6.0 until MariaDB 10.6.5, 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, COMPRESSED tables are no longer read-only by default.
From MariaDB 10.6.0 to MariaDB 10.6.5, set the innodb_read_only_compressed variable to OFF to make the tables
writable.

Character Sets
From MariaDB 10.6, the utf8 character set (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 system variable.

Options That Have Changed Default Values


Option Old default value New default value
character_set_client utf8 utf8mb3
character_set_connection utf8 utf8mb3
character_set_results utf8 utf8mb3
character_set_system utf8 utf8mb3
innodb_flush_method fsync O_DIRECT

1516/3812
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:

Option Reason
innodb_adaptive_max_sleep_delay
innodb_background_scrub_data_check_interval
innodb_background_scrub_data_compressed
innodb_background_scrub_data_interval
innodb_background_scrub_data_uncompressed
innodb_buffer_pool_instances
The variable is still present, but the *innodb and *none options
innodb_checksum_algorithm have been removed as the crc32 algorithm only is supported from
MariaDB 10.6.
innodb_commit_concurrency
innodb_concurrency_tickets
innodb_file_format
innodb_large_prefix
innodb_lock_schedule_algorithm
innodb_log_checksums
innodb_log_compressed_pages
innodb_log_files_in_group
innodb_log_optimize_ddl
innodb_page_cleaners
innodb_replication_delay
innodb_scrub_log
innodb_scrub_log_speed
innodb_sync_array_size
innodb_thread_concurrency
innodb_thread_sleep_delay
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 Use wsrep_mode instead.

wsrep_strict_ddl Use wsrep_mode instead.

Major New Features To Consider


See also System Variables Added in MariaDB 10.6.

See Also
The features in MariaDB 10.6
Upgrading from MariaDB 10.4 to MariaDB 10.5
Upgrading from MariaDB 10.3 to MariaDB 10.4
Upgrading from MariaDB 10.2 to MariaDB 10.3
1517/3812
2.1.3.5 Upgrading from MariaDB 10.4 to
MariaDB 10.5
Contents
1. How to Upgrade
2. Incompatible Changes Between 10.4 and
10.5
1. Binary name changes
2. GRANT PRIVILEGE changes
3. Options That Have Changed Default
Values
4. Options That Have Been Removed or
Renamed
5. Deprecated Options
3. Major New Features To Consider
4. See Also

How to Upgrade
For Windows, see Upgrading MariaDB on Windows 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.

The suggested upgrade procedure is:


1. Modify the repository configuration, so the system's package manager installs MariaDB 10.5. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Updating the MariaDB ZYpp repository to
a New Major Release for more information.
2. Stop MariaDB.
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
5. Make any desired changes to configuration options in option files, such as my.cnf . This includes removing any
options that are no longer supported.
6. Start MariaDB.
7. Run mysql_upgrade.
mysql_upgrade does two things:
1. Ensures that the system tables in the#mysql 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.
1518/3812
Usually that shouldn't cause any changed behavior, but when starting the MariaDB server via systemd, or via the
mysqld_safe 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 ON OFF
innodb_checksum_algorithm crc32 full_crc32
innodb_log_optimize_ddl ON OFF
slave_parallel_mode conservative optimistic
performance_schema_max_cond_classes 80 90
performance_schema_max_file_classes 50 80
performance_schema_max_mutex_classes 200 210
performance_schema_max_rwlock_classes 40 50
performance_schema_setup_actors_size 100 -1
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:

Option Reason
Deprecated and functionality replaced by innodb_checksum_algorithms in MariaDB
innodb_checksums
10.0.
idle_flush_pct Has had no effect since merging InnoDB 5.7 from mysql-5.7.9 (MariaDB 10.2.2 ).
Deprecated in MariaDB 10.0. Use READ COMMITTED transaction isolation level
innodb_locks_unsafe_for_binlog
instead.
innodb_rollback_segments Deprecated and replaced by innodb_undo_logs in MariaDB 10.0.
innodb_stats_sample_pages Deprecated in MariaDB 10.0. Use innodb_stats_transient_sample_pages instead.
max_long_data_size Deprecated and replaced by max_allowed_packet in MariaDB 5.5.
multi_range_count Deprecated and has had no effect since MariaDB 5.3.
thread_concurrency Deprecated and has had no effect since MariaDB 5.5.

timed_mutexes Deprecated and has had no effect since MariaDB 5.5.

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 No need for thread throttling any more.

1519/3812
innodb_background_scrub_data_check_interval Problematic ‘background scrubbing’ code removed.
innodb_background_scrub_data_interval Problematic ‘background scrubbing’ code removed.
innodb_background_scrub_data_compressed Problematic ‘background scrubbing’ code removed.
innodb_background_scrub_data_uncompressed Problematic ‘background scrubbing’ code removed.
innodb_buffer_pool_instances Having more than one buffer pool is no longer necessary.
innodb_commit_concurrency No need for thread throttling any more.
innodb_concurrency_tickets No need for thread throttling any more.
Redo log was unnecessarily split into multiple files. Limited to 1
innodb_log_files_in_group
from MariaDB 10.5.
innodb_log_optimize_ddl Prohibited optimizations.
innodb_page_cleaners Having more than one page cleaner task no longer necessary.
innodb_replication_delay No need for thread throttling any more.
innodb_scrub_log Never really worked as intended, redo log format is being redone.
innodb_scrub_log_speed Never really worked as intended, redo log format is being redone.
innodb_thread_concurrency No need for thread throttling any more.
innodb_thread_sleep_delay No need for thread throttling any more.
It always makes sense to use the maximum number of rollback
innodb_undo_logs
segments.
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:
The S3 storage engine allows one to archive MariaDB tables in Amazon S3, or any third-party public or private
cloud that implements S3 API.
ColumnStore columnar storage engine.
See also System Variables Added in MariaDB 10.5.

See Also
The features in MariaDB 10.5
Upgrading from MariaDB 10.3 to MariaDB 10.4
Upgrading from MariaDB 10.2 to MariaDB 10.3
Upgrading from MariaDB 10.1 to MariaDB 10.2

2.1.3.6 Upgrading from MariaDB 10.3 to


MariaDB 10.4
Contents
1. How to Upgrade
2. Incompatible Changes Between 10.3 and
10.4
1. Options That Have Changed Default
Values
2. Options That Have Been Removed or
Renamed
3. Authentication and TLS
3. Major New Features To Consider
4. See Also

How to Upgrade
For Windows, see Upgrading MariaDB on Windows instead.

For MariaDB Galera Cluster, see Upgrading from MariaDB 10.3 to MariaDB 10.4 with Galera Cluster instead.
1520/3812
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.

The suggested upgrade procedure is:


1. Modify the repository configuration, so the system's package manager installs MariaDB 10.4. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Updating the MariaDB ZYpp repository to
a New Major Release for more information.
2. Stop MariaDB.
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
5. Make any desired changes to configuration options in option files, such as my.cnf . This includes removing any
options that are no longer supported.
6. Start MariaDB.
7. Run mysql_upgrade .
mysql_upgrade does two things:
1. Ensures that the system tables in the mysql 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 1213,1205 1158,1159,1160,1161,1205,1213,1429,2013,12701
wsrep_debug OFF NONE
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:

Option Reason

Authentication and TLS


See Authentication from MariaDB 10.4 for an overview of the changes.
The unix_socket authentication plugin is now default on Unix-like systems.
TLSv1.0 is disabled by default in MariaDB 10.4. See tls_version and TLS Protocol Versions.

Major New Features To Consider


You might consider using the following major new features in MariaDB 10.4:
Galera has been upgraded from Galera 3 to Galera 4.
System-versioning extended with support for application-time periods.
1521/3812
User password expiry
Account Locking
See also System Variables Added in MariaDB 10.4.

See Also
The features in MariaDB 10.4
Upgrading from MariaDB 10.3 to MariaDB 10.4 with Galera Cluster
Upgrading from MariaDB 10.2 to MariaDB 10.3
Upgrading from MariaDB 10.1 to MariaDB 10.2
Upgrading from MariaDB 10.0 to MariaDB 10.1

2.1.3.7 Upgrading from MariaDB 10.2 to


MariaDB 10.3
Contents
1. How to Upgrade
2. Incompatible Changes Between 10.2 and
10.3
1. Options That Have Changed Default
Values
2. Options That Have Been Removed or
Renamed
3. Reserved Words
4. SQL_MODE=ORACLE
5. Functions
6. mysqldump
7. MariaDB Backup and Percona
XtraBackup
8. Privileges
3. Major New Features To Consider
4. See Also

How to Upgrade
For Windows, see Upgrading MariaDB on Windows instead.

For MariaDB Galera Cluster, see Upgrading from MariaDB 10.2 to MariaDB 10.3 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.

The suggested upgrade procedure is:


1. Modify the repository configuration, so the system's package manager installs MariaDB 10.3. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Updating the MariaDB ZYpp repository to
a New Major Release for more information.
2. Stop MariaDB. The server should be cleanly shut down, with no incomplete transactions remaining.
innodb_fast_shutdown must be set to 0 or 1 and 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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with

1522/3812
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
5. Make any desired changes to configuration options in option files, such as my.cnf . This includes removing any
options that are no longer supported.
6. Start MariaDB.
7. Run mysql_upgrade .
mysql_upgrade does two things:
1. Ensures that the system tables in the mysql 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 (empty) fsync
innodb_spin_wait_delay 6 4
performance_schema_max_stage_classes 150 160
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:

Option Reason
innodb_buffer_pool_populate Used in XtraDB-only
innodb_cleaner_lsn_age_factor Used in XtraDB-only
innodb_corrupt_table_action Used in XtraDB-only
innodb_empty_free_list_algorithm Used in XtraDB-only
innodb_fake_changes Used in XtraDB-only
The InnoDB file format is now Barracuda, and the old Antelope file
innodb_file_format
format is no longer supported.
No longer necessary as the Antelope InnoDB file format is no longer
innodb_file_format_check
supported.
No longer necessary as the Antelope InnoDB file format is no longer
innodb_file_format_max
supported.
innodb_foreground_preflush Used in XtraDB-only
innodb_instrument_semaphores
innodb_kill_idle_transaction Used in XtraDB-only
Large index key prefixes were made default from MariaDB 10.2, and
innodb_large_prefix
limiting tables to small prefixes is no longer permitted in MariaDB 10.3.
innodb_locking_fake_changes Used in XtraDB-only
innodb_log_arch_dir Used in XtraDB-only
innodb_log_arch_expire_sec Used in XtraDB-only
innodb_log_archive Used in XtraDB-only
innodb_log_block_size Used in XtraDB-only
Translated to innodb_log_checksums (NONE to OFF, everything else
innodb_log_checksum_algorithm to ON); only existed to allow easier upgrade from earlier XtraDB
versions.
innodb_mtflush_threads Replaced by the innodb_page_cleaners system variable.
innodb_sched_priority_cleaner Used in XtraDB-only
1523/3812
innodb_show_locks_held Used in XtraDB-only
innodb_show_verbose_locks Used in XtraDB-only
innodb_support_xa XA transactions are always supported.
innodb_use_fallocate
innodb_use_global_flush_log_at_trx_commit Used in XtraDB-only
innodb_use_mtflush Replaced by the innodb_page_cleaners system variable.
innodb_use_stacktrace Used in XtraDB-only
innodb_use_trim

Reserved Words
New reserved words: EXCEPT and INTERSECT. These can no longer be used as identifiers without being
quoted.

SQL_MODE=ORACLE
MariaDB 10.3 has introduced major new Oracle compatibility features. If you upgrade and are using this setting,
please check the changes carefully.

Functions
As a result of implementing Table Value Constructors, the VALUES function has been renamed to VALUE().
Functions that used to only return 64-bit now can return 32-bit results (MDEV-12619 ). This could cause
incompatibilities with strongly-typed clients.

mysqldump
mysqldump in MariaDB 10.3 includes logic to cater for the mysql.transaction_registry table. mysqldump from an
earlier MariaDB release cannot be used on MariaDB 10.3 and beyond.

MariaDB Backup and Percona XtraBackup


Percona XtraBackup is not compatible with MariaDB 10.3. Installations currently using XtraBackup should
upgrade to MariaDB Backup before upgrading to MariaDB 10.3.

Privileges
If a user has the SUPER privilege but not the DELETE HISTORY privilege, running mysql_upgrade will grant
DELETE HISTORY as well.

Major New Features To Consider


You might consider using the following major new features in MariaDB 10.3:
System-versioned tables
Sequences
See also System Variables Added in MariaDB 10.3.

See Also
The features in MariaDB 10.3
Upgrading from MariaDB 10.2 to MariaDB 10.3 with Galera Cluster
Upgrading from MariaDB 10.1 to MariaDB 10.2
Upgrading from MariaDB 10.0 to MariaDB 10.1

2.1.3.8 Upgrading from MariaDB 10.1 to


MariaDB 10.2

1524/3812
Contents
1. How to Upgrade
2. Incompatible Changes Between 10.1 and
10.2
1. InnoDB Instead of XtraDB
2. Options That Have Changed Default
Values
3. Options That Have Been Removed or
Renamed
4. Reserved Words
5. TokuDB
6. Replication
7. SQL Mode
8. Auto_increment
9. TLS
3. Major New Features To Consider
4. See Also

How to Upgrade
For Windows, see Upgrading MariaDB on Windows instead.

For MariaDB Galera Cluster, see Upgrading from MariaDB 10.1 to MariaDB 10.2 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.

The suggested upgrade procedure is:


1. Modify the repository configuration, so the system's package manager installs MariaDB 10.2. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Updating the MariaDB ZYpp repository to
a New Major Release for more information.
2. Set innodb_fast_shutdown to 0 . It can be changed dynamically with SET GLOBAL . For example:
SET GLOBAL innodb_fast_shutdown=0;
This step is not necessary when upgrading to MariaDB 10.2.5 or later. Omitting it can make the upgrade
process far faster. See MDEV-12289 for more information.
3. Stop MariaDB.
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
6. Make any desired changes to configuration options in option files, such as my.cnf . This includes removing any
options that are no longer supported.
7. Start MariaDB.
8. Run mysql_upgrade .
mysql_upgrade does two things:
1. Ensures that the system tables in the mysql 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


1525/3812
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 uses InnoDB as the default storage engine, rather than XtraDB, used in MariaDB 10.1 and before. See
Why does MariaDB 10.2 use InnoDB instead of XtraDB? 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 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, sql_mode, binlog_format, binlog_checksum and
innodb_checksum_algorithm.

Option Old default value New default value


aria_recover(_options) NORMAL BACKUP, QUICK
binlog_annotate_row_events OFF ON
binlog_checksum NONE CRC32
binlog_format STATEMENT MIXED
group_concat_max_len 1024 1048576
innodb_autoinc_lock_mode 1 2
innodb_buffer_pool_dump_at_shutdown OFF ON
innodb_buffer_pool_dump_pct 100 25
innodb_buffer_pool_instances 8 Varies
innodb_buffer_pool_load_at_startup OFF ON
innodb_checksum_algorithm innodb crc32
innodb_file_format Antelope Barracuda
innodb_large_prefix OFF ON
innodb_lock_schedule_algorithm VATS FCFS
innodb_log_compressed_pages OFF ON
innodb_max_dirty_pages_pct_lwm 0.001000 0
innodb_max_undo_log_size 1073741824 10485760
innodb_purge_threads 1 4
innodb_strict_mode OFF ON
innodb_undo_directory . NULL
innodb_use_atomic_writes OFF ON
innodb_use_trim OFF ON
lock_wait_timeout 31536000 86400
log_slow_admin_statements OFF ON
log_slow_slave_statements OFF ON
log_warnings 1 2
max_allowed_packet 4M 16M
max_long_data_size 4M 16M
myisam_recover_options NORMAL BACKUP, QUICK

optimizer_switch See Optimizer Switch for


details.
replicate_annotate_row_events OFF ON
server_id 0 1
slave_net_timeout 3600 60

1526/3812
STRICT_TRANS_TABLES,
NO_AUTO_CREATE_USER, ERROR_FOR_DIVISION_BY_ZERO,
sql_mode
NO_ENGINE_SUBSTITUTION NO_AUTO_CREATE_USER,
NO_ENGINE_SUBSTITUTION
thread_cache_size 0 Auto
thread_pool_max_threads 1000 65536

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:

Option Reason
aria_recover Renamed to aria_recover_options to match myisam_recover_options.
innodb_additional_mem_pool_size Deprecated in MariaDB 10.0.
innodb_api_bk_commit_interval Memcache never implemented in MariaDB.
innodb_api_disable_rowlock Memcache never implemented in MariaDB.
innodb_api_enable_binlog Memcache never implemented in MariaDB.
innodb_api_enable_mdl Memcache never implemented in MariaDB.
|innodb_api_trx_level Memcache never implemented in MariaDB.
innodb_use_sys_malloc Deprecated in MariaDB 10.0.

Reserved Words
New reserved words: OVER, RECURSIVE and ROWS. These can no longer be used as identifiers without being
quoted.

TokuDB
TokuDB has been split into a separate package, mariadb-plugin-tokudb.

Replication
Replication from legacy MySQL servers may require setting binlog_checksum to NONE.

SQL Mode
SQL_MODE 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 columns are no longer permitted in CHECK constraints, DEFAULT value expressions and virtual
columns. They were permitted in earlier versions, but did not work correctly.

TLS
Starting with MariaDB 10.2, when the user specifies the --ssl option with a client or utility, the client or utility will not
verify the server certificate by default. In order to verify the server certificate, the user must specify the --ssl-verify-
server-cert option to the client or utility. For more information, see the list of options for the mysql client.

Major New Features To Consider


You might consider using the following major new features in MariaDB 10.2:
Window Functions
mysqlbinlog now supports continuous binary log backups
Recursive Common Table Expressions
JSON functions
See also System Variables Added in MariaDB 10.2.

See Also
1527/3812
The features in MariaDB 10.2
Upgrading from MariaDB 10.1 to MariaDB 10.2 with Galera Cluster
Upgrading from MariaDB 10.0 to MariaDB 10.1
Upgrading from MariaDB 5.5 to MariaDB 10.0

2.1.3.9 Upgrading MariaDB on Windows


Contents
1. Minor upgrades
2. General information on upgrade and
version coexistence
3. General recommendations
4. Upgrade Wizard
5. mysql_upgrade_service
6. Migration to 64 bit MariaDB from 32 bit
7. Upgrading ZIP-based installations.

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, 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
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 is used to
accomplish this. On Windows, the MySQL upgrade is a complicated multiple-step manual process.
Since MariaDB 5.2.6 , 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.
1528/3812
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.

2.1.3.10 Upgrading Galera Cluster


Upgrading Between Minor Versions with Galera Cluster
2 Upgrading between minor versions of MariaDB with Galera Cluster, e.g. from ...

Upgrading from MariaDB 10.3 to MariaDB 10.4 with Galera Cluster


2 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


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


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
2 Cluster
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
How to upgrade from MariaDB Galera Cluster 5.5 to MariaDB Galera Cluster 10.0

There are 1 related questions .

1529/3812
2.1.3.10.1 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 to MariaDB 10.3.13) 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.

For each node, perform the following steps:


1. Stop MariaDB .
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
3. Make any desired changes to configuration options in option files, such as my.cnf . This includes removing any
system variables or options that are no longer supported.
4. Start MariaDB .
5. Run mysql_upgrade with the --skip-write-binlog option.
mysql_upgrade does two things:
1. Ensures that the system tables in the mysql 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.

2.1.3.10.2 Upgrading from MariaDB 10.3 to


MariaDB 10.4 with Galera Cluster
MariaDB starting with 10.1
Since MariaDB 10.1, the MySQL-wsrep patch has been merged into MariaDB Server. Therefore, in MariaDB 10.1
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, Galera Cluster ships with the MariaDB Server. Upgrading a Galera Cluster node is very
similar to upgrading a server from MariaDB 10.3 to MariaDB 10.4. For more information on that process as well as
incompatibilities between versions, see the Upgrade Guide.

Performing a Rolling Upgrade


The following steps can be used to perform a rolling upgrade from MariaDB 10.3 to MariaDB 10.4 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 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.
1530/3812
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 release to MariaDB 10.4, then the versions will be
compatible. MariaDB 10.3 uses Galera 3 (i.e. Galera wsrep provider versions 25.3.x), and MariaDB 10.4
uses Galera 4 (i.e. Galera wsrep provider versions 26.4.x). This means that upgrading to MariaDB 10.4
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 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) during the rolling
upgrade. The gcache size can be configured by setting gcache.size 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.

Then, for each node, perform the following steps:


1. Modify the repository configuration, so the system's package manager installs MariaDB 10.4. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see 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 .
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
6. Make any desired changes to configuration options in option files, 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 for more
information.
8. Start MariaDB .
9. Run mysql_upgrade with the --skip-write-binlog option.
mysql_upgrade does two things:
1. Ensures that the system tables in the mysql 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.

2.1.3.10.3 Upgrading from MariaDB 10.2 to


MariaDB 10.3 with Galera Cluster
MariaDB starting with 10.1
1531/3812
Since MariaDB 10.1, the MySQL-wsrep patch has been merged into MariaDB Server. Therefore, in MariaDB 10.1
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, Galera Cluster ships with the MariaDB Server. Upgrading a Galera Cluster node is very
similar to upgrading a server from MariaDB 10.2 to MariaDB 10.3. For more information on that process as well as
incompatibilities between versions, see the Upgrade Guide.

Performing a Rolling Upgrade


The following steps can be used to perform a rolling upgrade from MariaDB 10.2 to MariaDB 10.3 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 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 release to MariaDB 10.3, then the versions will be
compatible. Both MariaDB 10.2 and MariaDB 10.3 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 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) during the rolling
upgrade. The gcache size can be configured by setting gcache.size 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.

Then, for each node, perform the following steps:


1. Modify the repository configuration, so the system's package manager installs MariaDB 10.3. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see 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 .
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
6. Make any desired changes to configuration options in option files, 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 for more
information.
8. Start MariaDB .
9. Run mysql_upgrade with the --skip-write-binlog option.
1532/3812
mysql_upgrade does two things:
1. Ensures that the system tables in the mysql 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.

2.1.3.10.4 Upgrading from MariaDB 10.1 to


MariaDB 10.2 with Galera Cluster
MariaDB starting with 10.1
Since MariaDB 10.1, the MySQL-wsrep patch has been merged into MariaDB Server. Therefore, in MariaDB 10.1
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.

Contents
1. Performing a Rolling Upgrade
1. Additional details
1. Checking Status of the State
Transfer
1. State Transfers that Provide
Access to the Server
2. State Transfers that Require the
Server to be Down

Beginning in MariaDB 10.1, Galera Cluster ships with the MariaDB Server. Upgrading a Galera Cluster node is very
similar to upgrading a server from MariaDB 10.1 to MariaDB 10.2. For more information on that process as well as
incompatibilities between versions, see the Upgrade Guide.

Performing a Rolling Upgrade


The following steps can be used to perform a rolling upgrade from MariaDB 10.1 to MariaDB 10.2 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 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 release to MariaDB 10.2, then the versions will be
compatible. Both MariaDB 10.1 and MariaDB 10.2 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 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) during the rolling
upgrade. The gcache size can be configured by setting gcache.size 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.

Then, for each node, perform the following steps:

1533/3812
1. Modify the repository configuration, so the system's package manager installs MariaDB 10.2. For example,
On Debian, Ubuntu, and other similar Linux distributions, see 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 for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see 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 to 0 . It can be changed dynamically with SET GLOBAL . For example:
SET GLOBAL innodb_fast_shutdown=0;
This step is not necessary when upgrading to MariaDB 10.2.5 or later. Omitting it can make the upgrade
process far faster. See MDEV-12289 for more information.
4. Stop MariaDB .
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 for
more information.
On RHEL, CentOS, Fedora, and other similar Linux distributions, see Installing MariaDB Packages with
YUM for more information.
On SLES, OpenSUSE, and other similar Linux distributions, see Installing MariaDB Packages with ZYpp for
more information.
7. Make any desired changes to configuration options in option files, 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, the innodb_lock_schedule_algorithm
system variable must be set to FCFS . In MariaDB 10.2.12 and later, this system variable is automatically
set to this value when Galera Cluster is enabled. In MariaDB 10.2.11 and before, this system variable
must be set to this value manually. See 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 for more
information.
9. Start MariaDB .
10. Run mysql_upgrade with the --skip-write-binlog option.
mysql_upgrade does two things:
1. Ensures that the system tables in the mysql 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) or a State Snapshot Transfer(SST). 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) or a State Snapshot Transfer(SST) that uses the mysqldump 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 and wsrep_cluster_state_uuid status variables. When they equal each other, the node is
in sync with the cluster.

1534/3812
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) 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. 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)

2.1.3.11 Upgrading from MySQL to MariaDB


Upgrading from MySQL to MariaDB
5 Upgrading from MySQL to MariaDB.

Moving from MySQL to MariaDB in Debian 9


1 MariaDB 10.1 is the default mysql server in Debian 9 "Stretch"

Screencast for Upgrading MySQL to MariaDB


Screencast for upgrading MySQL 5.1.55 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 i...

Upgrading to MariaDB From MySQL 5.0 or Older


Upgrading to MariaDB from MySQL 5.0 (or older version)

2.1.3.11.1 Upgrading from MySQL to MariaDB


Contents
1. Upgrading on Windows
2. Upgrading my.cnf
3. Other Things to Think About
4. See Also

For all practical purposes, you can view MariaDB as an upgrade of MySQL:
Before upgrading, please check if there are any known incompatibilities between your MySQL release and the
MariaDB release you want to move to.
In particular, note that the JSON type in MariaDB is a LONGTEXT, while in MySQL it's a binary type. See Making
MariaDB understand MySQL JSON .
If you are using MySQL 8.0 or above, you have to use mysqldump to move your database to MariaDB.
For upgrading from very old MySQL versions, see Upgrading to MariaDB from MySQL 5.0 (or older version) .
Within the same base version (for example MySQL 5.5 -> MariaDB 5.5, MySQL 5.6 -> MariaDB 10.0 and MySQL
5.7 -> MariaDB 10.2) 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 mysql_upgrade (just as you would with 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, mysql_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.

1535/3812
Upgrading on Windows
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 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 for internal temporary files instead of MyISAM. If you have a lot
of temporary files, you should add and set aria-pagecache-buffer-size to the same value as you have for key-
buffer-size .
If you don't use MyISAM tables, you can set key-buffer-size to a very low value, like 64K.
If using MariaDB 10.1 or earlier, and your applications often connect and disconnect to MariaDB, you should set
up 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 memory allocator. 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 . For example using : thread_handling=pool-of-threads and thread_pool_size=128 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 ).
MariaDB has LGPL versions of the C connector and Java Client . 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 or some of the other new storage engines that
MariaDB provides.

See Also
MariaDB has a lot of new features that you should know about.
MariaDB versus MySQL - Compatibility
Migrating to MariaDB
You can find general upgrading informations on the MariaDB installation page.
There is a Screencast for upgrading MySQL to MariaDB.
Upgrading to MariaDB in Debian 9

2.1.3.11.2 Moving from MySQL to MariaDB in


Debian 9
MariaDB 10.1 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 in Debian 9
"Stretch".

1536/3812
Contents
1. Background information
2. Before you upgrade
1. Backup before you begin
2. Changed, renamed, and removed
options
1. Options with changed default
values
2. Options that have been removed or
renamed
3. Suggested upgrade procedure for
replication
4. Other resources to consult before
beginning your upgrade
3. Upgrading to MariaDB 10.1 from MySQL
5.5
4. Upgrading to MariaDB 10.1 from an older
version of MariaDB
5. MariaDB Galera Cluster
6. Configuration options for advanced
database users
7. Secure passwordless root accounts only
on new installs
8. See also
9. Comments and suggestions
10. Notes

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 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 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 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. 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.

1537/3812
Option Old default value New default value

aria-sort-buffer-size 128M 256M

back_log 50 150

innodb-concurrency-tickets 500 5000

innodb-log-file-size 5M 48M

innodb_log_compressed_pages ON OFF

innodb-old-blocks-time 0 1000

innodb-open-files 300 400 [2]

innodb-purge-batch-size 20 300

innodb-undo-logs ON 20

join_buffer_size 128K 256K

max_allowed_packet 1M 4M

max-connect-errors 10 100

max-relay-log-size 0 1024M

myisam-sort-buffer-size 8M 128M

optimizer-switch ... Added extended_keys=on, exists_to_in=on


query_alloc_block_size 8192 16384

query_cache_size 0 1M

query_cache_type ON OFF

query_prealloc_size 8192 24576

secure_auth OFF ON

sql_log_bin No longer affects replication of events in a Galera cluster.


sql_mode empty NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION

sync_master_info 0 10000

sync_relay_log 0 10000

sync_relay_log_info 0 10000

table_open_cache 400 2000

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
Replaced with set
engine-condition-pushdown
optimizer_switch='engine_condition_pushdown=on'

innodb-adaptive-flushing-method Removed by XtraDB


innodb-autoextend-increment Removed by XtraDB
innodb-blocking-buffer-pool-restore Removed by XtraDB
innodb-buffer-pool-pages Removed by XtraDB
innodb-buffer-pool-pages-blob Removed by XtraDB
innodb-buffer-pool-pages-index Removed by XtraDB
innodb-buffer-pool-restore-at-
Removed by XtraDB
startup

innodb-buffer-pool-shm-checksum Removed by XtraDB


innodb-buffer-pool-shm-key Removed by XtraDB
innodb-checkpoint-age-target Removed by XtraDB

1538/3812
innodb-dict-size-limit Removed by XtraDB
innodb-doublewrite-file Removed by XtraDB
innodb-fast-checksum Renamed to innodb-checksum-algorithm
innodb-flush-neighbor-pages Renamed to innodb-flush-neighbors
innodb-ibuf-accel-rate Removed by XtraDB
innodb-ibuf-active-contract Removed by XtraDB
innodb-ibuf-max-size Removed by XtraDB
innodb-import-table-from-xtrabackup Removed by XtraDB
innodb-index-stats Removed by XtraDB
innodb-lazy-drop-table Removed by XtraDB
innodb-merge-sort-block-size Removed by XtraDB
innodb-persistent-stats-root-page Removed by XtraDB
innodb-read-ahead Removed by XtraDB
innodb-recovery-stats Removed by XtraDB
innodb-recovery-update-relay-log Removed by XtraDB
innodb-stats-auto-update Renamed to innodb-stats-auto-recalc
innodb-stats-update-need-lock Removed by XtraDB
innodb-sys-stats Removed by XtraDB
innodb-table-stats Removed by XtraDB
innodb-thread-concurrency-timer-
Removed by XtraDB
based

innodb-use-sys-stats-table Removed by XtraDB


rpl_recovery_rank Unused in 10.0+
xtradb-admin-command Removed by XtraDB

Suggested upgrade procedure for replication


If you have a master-slave setup, 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 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 are very
similar. In particular, see the Upgrading from MariaDB 5.5 to MariaDB 10.0 and Upgrading from MariaDB 10.0 to
MariaDB 10.1 articles.
If you need help with upgrading or setting up replication, you can always contact the MariaDB corporation to find
experts to help you with this.

Upgrading to MariaDB 10.1 from MySQL 5.5


The suggested upgrade procedure is:
1. Set 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
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 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
In most cases this should be a fast operation (depending of course on the number of tables)
6. Add new options to my.cnf to enable features
1539/3812
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 from an older version of


MariaDB
If you have installed MariaDB 5.5 or MariaDB 10.0 on your Debian 8 "Jessie" machine from the MariaDB repositories
you will need to upgrade to MariaDB 10.1 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.
If you want to move to using MariaDB 10.1 from the Debian repositories, delete or comment out the MariaDB entries in
your sources.list file. Then upgrade as suggested above.
If you are already using MariaDB 10.1 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 and 10.0. In either case, the
upgrade will at most be just a minor upgrade from one version of MariaDB 10.1 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 is included by default in MariaDB 10.1, 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 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 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 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)
Configuring MariaDB for optimal performance
New features in MariaDB you should considering using
What is MariaDB 10.1
General instructions for upgrading from MySQL to MariaDB

Comments and suggestions


If you have comments or suggestions on things we can add or change to improve this page. Please add them as
1540/3812
comments below.

Notes
1. ↑ 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

2.1.3.11.3 Screencast for Upgrading MySQL to


MariaDB
There is a screencast 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.

2.1.4 Downgrading between Major Versions of


MariaDB
Downgrading MariaDB is not supported. The only reliable way to downgrade is to restore from a full backup made
before upgrading, and start the old version of MariaDB.
Some people have reported successfully downgrading, but there are many possible things that can go wrong, and
downgrading is not tested in any way by the MariaDB developers.
Between major releases, there are often substantial changes, even if none of the new features are used. For example,
both MariaDB 10.2 and MariaDB 10.3 introduce new versions of the redo log.
Even within minor releases, there may be problems, for example MariaDB 10.1.21 fixed a file format incompatibility
bug that prevents a downgrade to earlier MariaDB 10.1 releases.

2.1.5 Compiling MariaDB From Source


2.1.6 Starting and Stopping MariaDB
Starting and Stopping MariaDB Server
Starting MariaDB, including details on service managers.

Configuring MariaDB with Option Files


12 Configuring MariaDB with my.cnf and other option files.

mysqld Configuration Files and Groups


1 Which configuration files and groups mysqld reads.

mysqld Options
2 Lists of all the options for mysqld.

What to Do if MariaDB Doesn't Start


7 Troubleshooting MariaDB when it fails to start.

Running MariaDB from the Build Directory


Running mariadbd (mysqld) directly from the source directory without make install.

mysql.server
Startup script included in MariaDB distributions on Unix

mysqld_safe
Recommended way to start a mysqld server on a non-systemd Unix.

mysqladmin
1 Admin tool for monitoring, creating/dropping databases, stopping mysqld etc.

Switching Between Different Installed MariaDB Versions


Managing different installed MariaDB versions and running them one at a time

1541/3812
Running Multiple MariaDB Server Processes
1 Running multiple MariaDB Server processes on the same server.

Specifying Permissions for Schema (Data) Directories and Tables


2 MariaDB uses the following modes for creating directories and files

mysqld_multi
Manage several mysqld processes.

launchd
launchd is the startup service used in MacOS X.

systemd
2 How systemd is configured on MariaDB packages and how to alter its configuration.

sysVinit
sysVinit is one of the most common service managers for Linux and Unix.

mariadb-admin
Symlink or new name for mysqladmin.

mariadbd
Symlink or new name for mysqld.

mariadbd-multi
Symlink or new name for mysqld_multi.

mariadbd-safe
Symlink or new name for mysqld_safe.

There are 19 related questions .

2.1.6.1 Starting and Stopping MariaDB Server


Contents
1. Service Managers
1. Systemd
2. SysVinit
3. launchd
4. Upstart
2. Starting the Server Process Manually
1. mysqld
2. mysqld_safe
3. mysqld_multi
4. mysql.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 and systemd are the most common Linux service managers. launchd is used in MacOS X. Upstart 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 by default.
For information on how to start and stop MariaDB with this service manager, see systemd: Interacting with the MariaDB
Server Process.

SysVinit
RHEL/CentOS 6 and below, and Debian 7 Wheezy and below use sysVinit by default.

1542/3812
For information on how to start and stop MariaDB with this service manager, see sysVinit: Interacting with the MariaDB
Server Process.

launchd
launchd is used in MacOS X.

Upstart
Ubuntu 14.10 and below use Upstart by default.

Starting the Server Process Manually


mysqld
mysqld is the actual MariaDB Server binary. It can be started manually on its own.

mysqld_safe
mysqld_safe is a wrapper that can be used to start the mysqld server process. The script has some built-in safeguards,
such as automatically restarting the server process if it dies. See mysqld_safe for more information.

mysqld_multi
mysqld_multi is a wrapper that can be used to start the mysqld server process if you plan to run multiple server
processes on the same host. See mysqld_multi for more information.

mysql.server
mysql.server is a wrapper that works as a standard sysVinit script. However, it can be used independently of sysVinit as
a regular sh script. The script starts the mysqld server process by first changing its current working directory to the
MariaDB install directory and then starting mysqld_safe. The script requires the standard sysVinit arguments, such as
start , stop , and status . See mysql.server for more information.

2.1.6.2 Configuring MariaDB with Option Files


Contents
1. Global Options Related to Option Files
2. Default Option File Locations
1. Default Option File Locations on
Linux, Unix, Mac
2. Default Option File Locations on
Windows
3. Default Option File Hierarchy
3. Custom Option File Locations
4. Option File Syntax
5. Option Groups
1. Server Option Groups
2. Client Option Groups
3. Tool-Specific Option Groups
4. Custom Option Group Suffixes
6. Including Option Files
7. Including Option File Directories
8. Checking Program Options
9. MySQL 5.6 Obfuscated Authentication
Credential Option File
10. Option Prefixes
11. Options
1. MariaDB Server Options
2. MariaDB Client Options
12. Example Option Files
1. Example Minimal Option File
2. Example Hybrid Option File
13. See Also

You can configure MariaDB to run the way you want by configuring the server with MariaDB's option files. The default

1543/3812
MariaDB option file is called my.cnf on Unix-like operating systems and my.ini on Windows. Depending on how
you've installed 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. They must be given as the first argument on the command-line:

Option Description
--print-defaults Read options from option files, print all option values, and then exit the program.
--no-defaults Don't read options from any option file.
--defaults-file =path Only read options from the given option file.
--defaults-extra-file =path Read this extra option file after all other option files are read.
--defaults-group-suffix In addition to the default option groups, also read option groups with the given
=suffix 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 option was defined when MariaDB was built.
This option is usually defined as /etc when building RPM packages, but it is usually not defined when building DEB
packages or binary tarballs.
When the DEFAULT_SYSCONFDIR 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 , if any
~/.my.cnf User

When the DEFAULT_SYSCONFDIR cmake option was defined, MariaDB looks for the MariaDB option file in the
following locations in the following order:
1544/3812
Location Scope
DEFAULT_SYSCONFDIR/my.cnf Global
$MARIADB_HOME/my.cnf Server (from MariaDB 10.6)
$MYSQL_HOME/my.cnf Server
defaults-extra-file File specified with --defaults-extra-file , if any
~/.my.cnf User

MARIADB_HOME (from MariaDB 10.6) or MYSQL_HOME is the environment variable 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, 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), 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)
%MARIADB_HOME%\my.cnf Server (from MariaDB 10.6)
%MYSQL_HOME%\my.ini Server
%MYSQL_HOME%\my.cnf Server
defaults-extra-file File specified with --defaults-extra-file , if any

The System Windows Directory is the directory returned by the GetSystemWindowsDirectory function. The
value is usually C:\Windows . To find its specific value on your system, open cmd.exe and execute:
echo %WINDIR%

The Windows Directory is the directory returned by the GetWindowsDirectory 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 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\bin , then INSTALLDIR would be C:\Program Files\MariaDB 10.3 .
MARIADB_HOME (from MariaDB 10.6) or MYSQL_HOME is the environment variable containing the path to the
directory holding the server-specific my.cnf file.
Note that if MARIADB_HOME is set (from MariaDB 10.6), 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 option is set, and if the file does not exist, then
MariaDB will raise an error. If the --defaults-file option is set, then MariaDB will only read the option file referred to
1545/3812
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 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 . They must be
given as the first argument on the command-line:

Option Description
--defaults-file =path Only read options from the given option file.
--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 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 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
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 section below for information about available
option prefixes.
See the 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- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[server] Options read by MariaDB Server.

1546/3812
[mysqld] Options read by mysqld , which includes both MariaDB Server and MySQL Server.
[mysqld- Options read by a specific version of mysqld , which includes both MariaDB Server and MySQL
X.Y] Server. For example, [mysqld-10.4] .
[mariadb] Options read by MariaDB Server.
[mariadb-
Options read by a specific version of MariaDB Server. For example, [mariadb-10.4] .
X.Y]

[mariadbd] Options read by MariaDB Server. Available starting with MariaDB 10.4.6.
[mariadbd- Options read by a specific version of MariaDB Server. For example, [mariadbd-10.4] . Available
X.Y] starting with MariaDB 10.4.6.
Options read by MariaDB Server, but only if it is compiled with Galera Cluster support. In MariaDB
[galera] 10.1 and later, all builds on Linux are compiled with Galera Cluster support. When using one of these
builds, options from this option group are read even if the Galera Cluster 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 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
Options read by all MariaDB and MySQL client programs, which includes both MariaDB and MySQL
[client]
clients. For example, mysqldump .
[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] socket and port, which is common between the server and the clients.
[client-
Options read by all MariaDB client programs.
mariadb]

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 , 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.
Options read by Mariabackup. Available starting with MariaDB 10.1.31 and MariaDB 10.2.13
[mariabackup]
.
[xtrabackup] Options read by Mariabackup and Percona XtraBackup .
[mysql_upgrade] Options read by mysql_upgrade , which includes both MariaDB Server and MySQL Server.
[mariadb-
Options read by mysql_upgrade . Available starting with MariaDB 10.4.6.
upgrade]

[sst] Specific options read by the mariabackup SST method and the xtrabackup-v2 SST method.
[mysql] Options read by mysql , which includes both MariaDB Server and MySQL Server.
[mariadb-client] Options read by mysql . Available starting with MariaDB 10.4.6.
[mysqldump] Options read by mysqldump , which includes both MariaDB Server and MySQL Server.
[mariadb-dump] Options read by mysqldump . Available starting with MariaDB 10.4.6.
[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.
[mysqlbinlog] Options read by mysqlbinlog , which includes both MariaDB Server and MySQL Server.
[mariadb-binlog] Options read by mysqlbinlog . Available starting with MariaDB 10.4.6.
[mysqladmin] Options read by mysqladmin , which includes both MariaDB Server and MySQL Server.
1547/3812
[mariadb-admin] Options read by mysqladmin . Available starting with MariaDB 10.4.6.
[mysqlshow] Options read by mysqlshow , which includes both MariaDB Server and MySQL Server.
[mariadb-show] Options read by mysqlshow . Available starting with MariaDB 10.4.6.
[mysqlcheck] Options read by mysqlcheck , which includes both MariaDB Server and MySQL Server.
[mariadb-check] Options read by mysqlcheck . Available starting with MariaDB 10.4.6.
[mysqlslap] Options read by mysqlslap , which includes both MariaDB Server and MySQL Server.
[mariadb-slap] Options read by mysqlslap . Available starting with MariaDB 10.4.6.
Options read by MariaDB Connector/ODBC , but only if the USE_MYCNF parameter has
[odbc]
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 .
It must be given as the first argument on the command-line:

Option Description
--defaults-group-suffix In addition to the default option groups, also read option groups with the given
=suffix suffix.

The default group suffix can also be specified via the MYSQL_GROUP_SUFFIX environment variable.

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 command-line argument:

Option Description
--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 . It must be given
as the first argument on the command-line. For example:

$ mysqldump --print-defaults
mysqldump 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 utility and
providing the names of the option groups that the program reads. For example:

1548/3812
$ my_print_defaults mysqldump 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 utility's --mysqld command-line option provides a shortcut to refer to all of the 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 .
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
Description
Prefix
Sets the option value automatically. Only supported for certain options. Available in MariaDB 10.1.7
autoset
and later.
disable For all boolean options, disables the setting (equivalent to setting it to 0 ). Same as skip .
enable For all boolean options, enables the setting (equivalent to setting it to 1 ).
loose Don't produce an error if the option doesn't exist.
maximum Sets the maximum value for the option.
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.
1549/3812
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.
For a list of options that can be set for MariaDB Server, see the list of options available for mysqld .
Most of the server system variables can also be set in MariaDB's option file.

MariaDB Client Options


MariaDB client options can be set in client option groups.
See the specific page for each client program 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.
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.

1550/3812
# Example mysql config file.

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

# This will be passed to all mysql clients


[client]
password=my_password

# Here are entries for some specific programs


# The following values assume you have at least 32M ram

# The MySQL 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
Troubleshooting Connection Issues
Configuring MariaDB for Remote Client Access
MySQL 5.6: Security through Complacency?

2.1.6.3 mysqld Configuration Files and Groups


For all about configuring mysqld, see Configuring MariaDB with Option Files.

2.1.6.4 mysqld Options


MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadbd is a symlink to mysqld .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadbd is the name of the binary, with mysqld a symlink .

Contents
1. Option Prefixes
1. --autoset-*
2. --disable-*
3. --enable-*
4. --loose-*
5. --maximum-*
6. --skip-*
1551/3812
2. Option File Options
1. --defaults-extra-file
2. --defaults-file
3. --defaults-group-suffix
4. --no-defaults
5. --print-defaults
3. Compatibility Options
1. -a, --ansi
2. --new
3. --old
4. --old-alter-table
5. --old-mode
6. --old-passwords
7. --old-style-user-limits
8. --safe-mode
9. --show-old-temporals
10. --skip-new
11. Compatibility Options and System
Variables
4. Locale Options
1. --character-set-client-handshake
2. --character-set-filesystem
3. --character-set-server
4. --character-sets-dir
5. --collation-server
6. --default-character-set
7. --default-time-zone
8. --default-week-format
9. --language
10. --lc-messages
11. --lc-messages-dir
12. --lc-time-names
13. Locale Options and System Variables
5. Windows Options
1. --console
2. --named-pipe
3. --install
4. --install-manual
5. --remove
6. --slow-start-timeout
7. --standalone
8. Windows Options and System
Variables
6. Replication and Binary Logging Options
1. --abort-slave-event-count
2. --auto-increment-increment
3. --auto-increment-offset
4. --binlog-annotate-row-events
5. --binlog-cache-size
6. --binlog-checksum
7. --binlog-commit-wait-count
8. --binlog-commit-wait-usec
9. --binlog-direct-non-transactional-
updates
10. --binlog-do-db
11. --binlog-expire-logs-seconds
12. --binlog-file-cache-size
13. --binlog-format
14. --binlog-ignore-db
15. --binlog-optimize-thread-scheduling
16. --binlog-row-event-max-size
17. --binlog-row-image
18. --binlog-row-metadata
19. --binlog-stmt-cache-size
20. --default-master-connection
21. --disconnect-slave-event-count
22. --flashback
23. --gtid-cleanup-batch-size
24. --gtid-domain-id
25. --gtid-ignore-duplicates
26. --gtid-strict-mode
27. --init-rpl-role
1552/3812
28. --init-slave
29. --log-basename
30. --log-bin
31. --log-bin-compress
32. --log-bin-compress-min-len
33. --log-bin-index
34. --log-bin-trust-function-creators
35. --log-bin-trust-routine-creators
36. --log-slave-updates
37. --master-host
38. --master-info-file
39. --master-password
40. --master-port
41. --master-retry-count
42. --master-ssl
43. --master-ssl-ca
44. --master-ssl-capath
45. --master-ssl-cert
46. --master-ssl-cipher
47. --master-ssl-key
48. --master-user
49. --master-verify-checksum
50. --max-binlog-cache-size
51. --max-binlog-dump-events
52. --max-binlog-size
53. --max-binlog-stmt-cache-size
54. --max-relay-log-size
55. --read-binlog-speed-limit
56. --relay-log
57. --relay-log-index
58. --relay-log-info-file
59. --relay-log-purge
60. --relay-log-recovery
61. --relay-log-space-limit
62. --replicate-annotate-row-events
63. --replicate-do-db
64. --replicate-do-table
65. --replicate-events-marked-for-skip
66. --replicate-ignore-db
67. --replicate-ignore-table
68. --replicate-rewrite_db
69. --replicate-same-server-id
70. --replicate-wild-do-table
71. --replicate-wild-ignore-table
72. --report-host
73. --report-password
74. --report-port
75. --report-user
76. --rpl-recovery-rank
77. --server-id
78. --slave-ddl-exec-mode
79. --slave-compressed-protocol
80. --slave-domain-parallel-threads
81. --slave-exec-mode
82. --slave-load-tmpdir
83. --slave-max-allowed-packet
84. --slave-net-timeout
85. --slave-parallel-threads
86. --slave-parallel-max-queued
87. --slave-run-triggers-for-rbr
88. --slave-skip-errors
89. --slave-sql-verify-checksum
90. --slave-transaction-retries
91. --slave-transaction-retry-errors
92. --slave-transaction-retry-interval
93. --slave-type-conversions
94. --sporadic-binlog-dump-fail
95. --sync-binlog
96. --sync-master-info
97. --sync-relay-log
98. --sync-relay-log-info
99. --sysdate-is-now
1553/3812
99. --sysdate-is-now
100. Replication and Binary Logging
Options and System Variables
101. Semisynchronous Replication Options
and System Variables
1. rpl-semi-sync-master-enabled
2. rpl-semi-sync-master-timeout
3. rpl-semi-sync-master-trace-level
4. rpl-semi-sync-master-wait-no-slave
5. rpl-semi-sync-master-wait-point
6. rpl-semi-sync-slave-delay-master
7. rpl-semi-sync-slave-kill-conn-
timeout
8. rpl-semi-sync-slave-enabled
9. rpl-semi-sync-slave-trace-level
7. Optimizer Options
1. --alter-algorithm
2. --analyze-sample-percentage
3. --big-tables
4. --bulk-insert-buffer-size
5. --expensive-subquery-limit
6. --join-buffer-size
7. --join-buffer-space-limit
8. --join-cache-level
9. --max-heap-table-size
10. --max-join-size
11. --max-seeks-for-key
12. --max-sort-length
13. --mrr-buffer-size
14. --optimizer-max-sel-arg-weight
15. --optimizer-prune-level
16. --optimizer-search-depth
17. --optimizer-selectivity-sampling-limit
18. --optimizer-switch
19. -optimizer-trace
20. -optimizer-trace-max-mem-size
21. --optimizer-use-condition-selectivity
22. --query-alloc-block-size
23. --query-prealloc-size
24. --range-alloc-block-size
25. --read-buffer-size
26. --record-buffer
27. --rowid-merge-buff-size
28. --table-cache
29. --table-definition-cache
30. --table-open-cache
31. --table-open-cache-instances
32. --tmp-disk-table-size
33. --tmp-memory-table-size
34. --tmp-table-size
35. --use-stat-tables
36. Optimizer Options and System
Variables
8. Storage Engine Options
1. --skip-bdb
2. --external-locking
3. MyISAM Storage Engine Options
1. --concurrent-insert
2. --delayed-insert-limit
3. --delayed-insert-timeout
4. --delayed-queue-size
5. --keep-files-on-create
6. --key-buffer-size
7. --key-cache-age-threshold
8. --key-cache-block-size
9. --key-cache-division-limit
10. --key-cache-file-hash-size
11. --key-cache-segments
12. --log-isam
13. --myisam-block-size
14. --myisam-data-pointer-size
15. --myisam-max-sort-file-size
16. --myisam-mmap-size
1554/3812
16. --myisam-mmap-size
17. --myisam-recover-options
18. --myisam-repair-threads
19. --myisam-sort-buffer-size
20. --myisam-stats-method
21. --myisam-use-mmap
22. MyISAM Storage Engine Options
and System Variables
4. InnoDB Storage Engine Options
1. --ignore-builtin-innodb
2. --innodb
3. --innodb-adaptive-checkpoint
4. --innodb-adaptive-flushing
5. --innodb-adaptive-flushing-lwm
6. --innodb-adaptive-flushing-method
7. --innodb-adaptive-hash-index
8. --innodb-adaptive-hash-index-
partitions
9. --innodb-adaptive-hash-index-parts
10. --innodb-adaptive-max-sleep-delay
11. --innodb-additional-mem-pool-size
12. --innodb-api-bk-commit-interval
13. --innodb-api-disable-rowlock
14. --innodb-api-enable-binlog
15. --innodb-api-enable-mdl
16. --innodb-api-trx-level
17. --innodb-auto-lru-dump
18. --innodb-autoextend-increment
19. --innodb-autoinc-lock-mode
20. --innodb-background-scrub-data-
check-interval
21. --innodb-background-scrub-data-
compressed
22. --innodb-background-scrub-data-
interval
23. --innodb-background-scrub-data-
uncompressed
24. --innodb-blocking-buffer-pool-
restore
25. --innodb-buf-dump-status-
frequency
26. --innodb-buffer-pool-chunk-size
27. --innodb-buffer-pool-dump-at-
shutdown
28. --innodb-buffer-pool-dump-now
29. --innodb-buffer-pool-dump-pct
30. --innodb-buffer-pool-evict
31. --innodb-buffer-pool-filename
32. --innodb-buffer-pool-instances
33. --innodb-buffer-pool-load-abort
34. --innodb-buffer-pool-load-at-startup
35. --innodb-buffer-pool-load-now
36. --innodb-buffer-pool-load-pages-
abort
37. --innodb-buffer-pool-populate
38. --innodb-buffer-pool-restore-at-
startup
39. --innodb-buffer-pool-shm-checksum
40. --innodb-buffer-pool-shm-key
41. --innodb-buffer-pool-size
42. --innodb-change-buffer-max-size
43. --innodb-change-buffering
44. --innodb-change-buffering-debug
45. --innodb-checkpoint-age-target
46. --innodb-checksum-algorithm
47. --innodb-checksums
48. --innodb-cleaner-lsn-age-factor
49. --innodb-cmp
50. --innodb-cmp-per-index-enabled
51. --innodb-cmp-reset
52. --innodb-cmpmem
53. --innodb-cmpmem-reset
54. --innodb-commit-concurrency 1555/3812
54. --innodb-commit-concurrency
55. --innodb-compression-algorithm
56. --innodb-compression-failure-
threshold-pct
57. --innodb-compression-level
58. --innodb-compression-pad-pct-max
59. --innodb-concurrency-tickets
60. --innodb-corrupt-table-action
61. --innodb-data-file-path
62. --innodb-data-home-dir
63. --innodb-deadlock-detect
64. --innodb-deadlock-report
65. --innodb-default-encryption-key-id
66. --innodb-default-page-encryption-
key
67. --innodb-default-row-format
68. --innodb-defragment
69. --innodb-defragment-fill-factor
70. --innodb-defragment-fill-factor-n-
recs
71. --innodb-defragment-frequency
72. --innodb-defragment-n-pages
73. --innodb-defragment-stats-accuracy
74. --innodb-dict-size-limit
75. --innodb-disable-sort-file-cache
76. --innodb-doublewrite
77. --innodb-doublewrite-file
78. --innodb-empty-free-list-algorithm
79. --innodb-enable-unsafe-group-
commit
80. --innodb-encrypt-log
81. --innodb-encrypt-tables
82. --innodb-encrypt-temporary-tables
83. --innodb-encryption-rotate-key-age
84. --innodb-encryption-rotation-iops
85. --innodb-encryption-threads
86. --innodb-extra-rsegments
87. --innodb-extra-undoslots
88. --innodb-fake-changes
89. --innodb-fast-checksum
90. --innodb-fast-shutdown
91. --innodb-fatal-semaphore-wait-
threshold
92. --innodb-file-format
93. --innodb-file-format-check
94. --innodb-file-format-max
95. --innodb-file-io-threads
96. --innodb-file-per-table
97. --innodb-filll-factor
98. --innodb-flush-log-at-trx-commi
99. --innodb-flush-method
100. --innodb-flush-neighbor-pages
101. --innodb-flush-neighbors
102. --innodb-flush-sync
103. --innodb-flushing-avg-loops
104. --innodb-force-load-corrupted
105. --innodb-force-primary-key
106. --innodb-force-recovery
107. --innodb-foreground-preflush
108. --innodb-ft-aux-table
109. --innodb-ft-cache-size
110. --innodb-ft-enable-diag-print
111. --innodb-ft-enable-stopword
112. --innodb-ft-max-token-size
113. --innodb-ft-min-token-size
114. --innodb-ft-num-word-optimize
115. --innodb-ft-result-cache-limit
116. --innodb-ft-server-stopword-table
117. --innodb-ft-sort-pll-degree
118. --innodb-ft-total-cache-size
119. --innodb-ft-user-stopword-table
120. --innodb-ibuf-accel-rate
121. --innodb-ibuf-active-contract 1556/3812
121. --innodb-ibuf-active-contract
122. --innodb-ibuf-max-size
123. --innodb-idle-flush-pct
124. --innodb-immediate-scrub-data-
uncompressed
125. --innodb-import-table-from-
xtrabackup
126. --innodb-index-stats
127. --innodb-instant-alter-column-
allowed
128. --innodb-instrument-semaphores
129. --innodb-io-capacity
130. --innodb-io-capacity-max
131. --innodb-large-prefix
132. --innodb-lazy-drop-table
133. --innodb-lock-schedule-algorithm
134. --innodb-lock-wait-timeout
135. --innodb-lock-waits
136. --innodb-locking-fake-changes
137. --innodb-locks
138. --innodb-locks-unsafe-for-binlog
139. --innodb-log-arch-dir
140. --innodb-log-arch-expire-sec
141. --innodb-log-archive
142. --innodb-log-block-size
143. --innodb-log-buffer-size
144. --innodb-log-checksum-algorithm
145. --innodb-log-checksums
146. --innodb-log-compressed-pages
147. --innodb-log-file-buffering
148. --innodb-log-file-size
149. --innodb-log-files-in-group
150. --innodb-log-group-home-dir
151. --innodb-log-optimize-ddl
152. --innodb-log-write-ahead-size
153. --innodb-lru-flush-size
154. --innodb-lru-scan-depth
155. --innodb-max-bitmap-file-size
156. --innodb-max-changed-pages
157. --innodb-max-dirty-pages-pct
158. --innodb-max-dirty-pages-pct-lwm
159. --innodb-max-purge-lag
160. --innodb-max-purge-lag-delay
161. --innodb-max-purge-lag-wait
162. --innodb-max-undo-log-size
163. --innodb-merge-sort-block-size
164. --innodb-mirrored-log-groups
165. --innodb-monitor-disable
166. --innodb-monitor-enable
167. --innodb-monitor-reset
168. --innodb-monitor-reset-all
169. --innodb-mtflush-threads
170. --innodb-numa-interleave
171. --innodb-old-blocks-pct
172. --innodb-old-blocks-time
173. --innodb-online-alter-log-max-size
174. --innodb-open-files
175. --innodb-optimize-fulltext-only
176. --innodb-page-cleaners
177. --innodb-page-size
178. --innodb-pass-corrupt-table
179. --innodb-prefix-index-cluster-
optimization
180. --innodb-print-all-deadlocks
181. --innodb-purge-batch-size
182. --innodb-purge-rseg-truncate-
frequency
183. --innodb-purge-threads
184. --innodb-random-read-ahead
185. --innodb-read-ahead
186. --innodb-read-ahead-threshold
187. --innodb-read-io-threads
188. --innodb-read-only 1557/3812
188. --innodb-read-only
189. --innodb-recovery-update-relay-log
190. --innodb-replication-delay
191. --innodb-rollback-on-timeout
192. --innodb-rollback-segments
193. --innodb-rseg
194. --innodb-sched-priority-cleaner
195. --innodb-safe-truncate
196. --innodb-scrub-log
197. --innodb-scrub-log-interval
198. --innodb-scrub-log-speed
199. --innodb-show-locks-held
200. --innodb-show-verbose-locks
201. --innodb-sort-buffer-size
202. --innodb-spin-wait-delay
203. --innodb-stats-auto-recalc
204. --innodb-stats-auto-update
205. --innodb-stats-include-delete-
marked
206. --innodb-stats-method
207. --innodb-stats-modified-counter
208. --innodb-stats-on-metadata
209. --innodb-stats-persistent
210. --innodb-stats-persistent-sample-
pages
211. --innodb-stats-sample-pages
212. --innodb-stats-traditional
213. --innodb-stats-transient-sample-
pages
214. --innodb-stats-update-need-lock
215. --innodb-status-file
216. --innodb-status-output
217. --innodb-status-output-locks
218. --innodb-strict-mode
219. --innodb-support-xa
220. --innodb-sync-array-size
221. --innodb-sync-spin-loops
222. --innodb-sys-indexes
223. --innodb-sys-stats
224. --innodb-sys-tables
225. --innodb-table-locks
226. --innodb-table-stats
227. --innodb-temp-data-file-path
228. --innodb-thread-concurrency
229. --innodb-thread-concurrency-timer-
based
230. --innodb-thread-sleep-delay
231. --innodb-tmpdir
232. --innodb-track-changed-pages
233. --innodb-track-redo-log-now
234. --innodb-trx
235. --innodb-undo-directory
236. --innodb-undo-log-truncate
237. --innodb-undo-logs
238. --innodb-undo-tablespaces
239. --innodb-use-atomic-writes
240. --innodb-use-fallocate
241. --innodb-use-global-flush-log-at-trx-
commit
242. --innodb-use-mtflush
243. --innodb-use-native-aio
244. --innodb-use-purge-thread
245. --innodb-use-stacktrace
246. --innodb-use-sys-malloc
247. --innodb-use-sys-stats-table
248. --innodb-use-trim
249. --innodb-write-io-threads
250. --skip-innodb
251. --skip-innodb-checksums
252. --skip-innodb-doublewrite
253. InnoDB Storage Engine Options
and System Variables
1558/3812
5. Aria Storage Engine Options
1. --aria-block-size
2. --aria-checkpoint-interval
3. --aria-checkpoint-log-activity
4. --aria-encrypt-tables
5. --aria-force-start-after-recovery-
failures
6. --aria-group-commit
7. --aria-group-commit-interval
8. --aria-log-dir-path
9. --aria-log-file-size
10. --aria-log-purge-type
11. --aria-max-sort-file-size
12. --aria-page-checksum
13. --aria-pagecache-age-threshold
14. --aria-pagecache-buffer-size
15. --aria-pagecache-division-limit
16. --aria-pagecache-file-hash-size
17. --aria-recover
18. --aria-recover-options
19. --aria-repair-threads
20. --aria-sort-buffer-size
21. --aria-stats-method
22. --aria-sync-log-dir
23. --aria-used-for-temp-tables
24. --deadlock-search-depth-long
25. --deadlock-search-depth-short
26. --deadlock-timeout-long
27. --deadlock-timeout-short
28. Aria Storage Engine Options and
System Variables
6. MyRocks Storage Engine Options
7. S3 Storage Engine Options
1. --s3-access-key
2. --s3-block-size
3. --s3-bucket
4. --s3-debug
5. --s3-host-name
6. --s3-pagecache-age-threshold
7. --s3-pagecache-buffer-size
8. --s3-pagecache-division-limit
9. --s3-pagecache-file-hash-size
10. --s3-port
11. --s3-protocol-version
12. --s3-region
13. --s3-secret-key
14. --s3-slave-ignore-updates
15. --s3-use-http
8. CONNECT Storage Engine Options
1. --connect-class-path
2. --connect-cond-push
3. --connect-conv-size
4. --connect-default-depth
5. --connect-default-prec
6. --connect-enable-mongo
7. --connect-exact-info
8. --connect-force-bson
9. --connect-indx-map
10. --connect-java-wrapper
11. --connect-json-all-path
12. --connect-json-grp-size
13. --connect-json-null
14. --connect-jvm-path
15. --connect-type-conv
16. --connect-use-tempfile
17. --connect-work-size
18. --connect-xtrace
19. CONNECT Storage Engine
Options and System Variables
9. Spider Storage Engine Options
10. Mroonga Storage Engine Options
11. TokuDB Storage Engine Options
1559/3812
11. TokuDB Storage Engine Options
9. Performance Schema Options
1. --performance-schema
2. --performance-schema-accounts-size
3. --performance-schema-consumer-
events-stages-current
4. --performance-schema-consumer-
events-stages-history
5. --performance-schema-consumer-
events-stages-history-long
6. --performance-schema-consumer-
events-statements-current
7. --performance-schema-consumer-
events-statements-history
8. --performance-schema-consumer-
events-statements-history-long
9. --performance-schema-consumer-
events-waits-current
10. --performance-schema-consumer-
events-waits-history
11. --performance-schema-consumer-
events-waits-history-long
12. --performance-schema-consumer-
global-instrumentation
13. --performance-schema-consumer-
statements-digest
14. --performance-schema-consumer-
thread-instrumentation
15. --performance-schema-digests-size
16. --performance-schema-events-stages-
history-long-size
17. --performance-schema-events-stages-
history-size
18. --performance-schema-events-
statements-history-long-size
19. --performance-schema-events-
statements-history-size
20. --performance-schema-events-
transactions-history-long-size
21. --performance-schema-events-
transactions-history-size
22. --performance-schema-events-waits-
history-long-size
23. --performance-schema-events-waits-
history-size
24. --performance-schema-hosts-size
25. --performance-schema-max-cond-
classes
26. --performance-schema-max-cond-
instances
27. --performance-schema-max-digest-
length
28. --performance-schema-max-file-
classes
29. --performance-schema-max-file-
handles
30. --performance-schema-max-file-
instances
31. --performance-schema-max-index-stat
32. --performance-schema-max-memory-
classes
33. --performance-schema-max-metadata-
locks
34. --performance-schema-max-mutex-
classes
35. --performance-schema-max-mutex-
instances
36. --performance-schema-max-prepared-
statement-instances
37. --performance-schema-max-program-
instances
38. --performance-schema-max-sql-text-
length
1560/3812
length
39. --performance-schema-max-rwlock-
classes
40. --performance-schema-max-rwlock-
instances
41. --performance-schema-max-socket-
classes
42. --performance-schema-max-socket-
instances
43. --performance-schema-max-stage-
classes
44. --performance-schema-max-
statement-classes
45. --performance-schema-max-
statement-stack
46. --performance-schema-max-table-
handles
47. --performance-schema-max-table-
instances
48. --performance-schema-max-table-lock-
stat
49. --performance-schema-max-thread-
classes
50. --performance-schema-max-thread-
instances
51. --performance-schema-session-
connect-attrs-size
52. --performance-schema-setup-actors-
size
53. --performance-schema-setup-objects-
size
54. --performance-schema-users-size
55. Performance Schema Options and
System Variables
10. Galera Cluster Options
1. --wsrep-auto-increment-control
2. --wsrep-causal-reads
3. --wsrep-certify-nonPK
4. --wsrep-cluster-address
5. --wsrep-cluster-name
6. --wsrep-convert-LOCK-to-trx
7. --wsrep-data-home-dir
8. --wsrep-dbug-option
9. --wsrep-debug
10. --wsrep-desync
11. --wsrep-dirty-reads
12. --wsrep-drupal-282555-workaround
13. --wsrep-forced-binlog-format
14. --wsrep-gtid-domain-id
15. --wsrep-gtid-mode
16. --wsrep-ignore-apply-errors
17. --wsrep-load-data-splitting
18. --wsrep-log-conflicts
19. --wsrep-max-ws-rows
20. --wsrep-max-ws-size
21. --wsrep-mode
22. --wsrep-mysql-replication-bundle
23. --wsrep-new-cluster
24. --wsrep-node-address
25. --wsrep-node-incoming-address
26. --wsrep-node-name
27. --wsrep-notify-cmd
28. --wsrep-on
29. --wsrep-OSU-method
30. --wsrep-provider
31. --wsrep-provider-options
32. --wsrep-recover
33. --wsrep-reject_queries
34. --wsrep-replicate-myisam
35. --wsrep-restart-slave
36. --wsrep-retry-autocommit
37. --wsrep-slave-FK-checks
38. --wsrep-slave-threads 1561/3812
38. --wsrep-slave-threads
39. --wsrep-slave-UK-checks
40. --wsrep-sr-store
41. --wsrep-sst-auth
42. --wsrep-sst-donor
43. --wsrep-sst-donor-rejects-queries
44. --wsrep-sst-method
45. --wsrep-sst-receive-address
46. --wsrep-start-position
47. --wsrep-strict-ddl
48. --wsrep-sync-wait
49. --wsrep-trx-fragment-size
50. --wsrep-trx-fragment-unit
51. Galera Cluster Options and System
Variables
11. Options When Debugging mysqld
1. --core-file
2. --debug
3. --debug-assert-if-crashed-table
4. --debug-binlog-fsync-sleep
5. --debug-crc-break
6. --debug-flush
7. --debug-no-thread-alarm
8. --debug-no-sync
9. --debug-sync-timeout
10. --gdb
11. --silent-startup
12. --sync-sys
13. --thread-alarm
14. Debugging Options and System
Variables
12. Other Options
1. --allow-suspicious-udfs
2. --autocommit
3. --automatic-sp-privileges
4. --back-log
5. --basedir
6. --bind-address
7. --bootstrap
8. --check-constraint-checks
9. --chroot
10. --column-compression-threshold
11. --column-compression-zlib-level
12. --column-compression-zlib-strategy
13. --column-compression-zlib-wrap
14. --completion-type
15. --connect-timeout
16. --datadir
17. --date-format
18. --datetime-format
19. --deadlock-search-depth-long
20. --deadlock-search-depth-short
21. --deadlock-timeout-long
22. --deadlock-timeout-short
23. --default-password-lifetime
24. --default-regex-flags
25. --default-storage-engine
26. --default-table-type
27. --default-tmp-storage-engine
28. --delay-key-write
29. --des-key-file
30. --disconnect-on-expired-password
31. --div-precision-increment
32. --encrypt-binlog
33. --encrypt-tmp-disk-tables
34. --encrypt-tmp-files
35. --encryption-algorithm
36. --engine-condition-pushdown
37. --eq-range-index-dive-limit
38. --event-scheduler
39. --exit-info
40. --expire-logs-days
41. --explicit-defaults-for-timestamp 1562/3812
41. --explicit-defaults-for-timestamp
42. --extra-max-connections
43. --extra-port
44. --flush
45. --flush-time
46. --ft-boolean-syntax
47. --ft-max-word-len
48. --ft-min-word-len
49. --ft-query-expansion-limit
50. --ft-stopword-file
51. --general-log
52. --general-log-file
53. --getopt-prefix-matching
54. --group-concat-max-len
55. --help
56. --histogram-size
57. --histogram-type
58. --host-cache-size
59. --idle-readonly-transaction-timeout
60. --idle-transaction-timeout
61. --idle-write-transaction-timeout
62. --ignore-db-dirs
63. --in-predicate-conversion-threshold
64. --init-connect
65. --init-file
66. --interactive-timeout
67. --large-pages
68. --local-infile
69. --lock-wait-timeout
70. --log
71. --log-disabled_statements
72. --log-error
73. --log-output
74. --log-queries-not-using-indexes
75. --log-ddl-recovery
76. --log-short-format
77. --log-slow-admin-statements
78. --log-slow-disabled-statements
79. --log-slow-file
80. --log-slow-filter
81. --log-slow-min-examined-row_limit
82. --log-slow-queries
83. --log-slow-query
84. --log-slow-query-file
85. --log-slow-query-time
86. --log-slow-rate-limit
87. --log-slow-slave-statements
88. --log-slow-time
89. --log-slow-verbosity
90. --log-tc
91. --log-tc-size
92. --log-warnings
93. --long-query-time
94. --low-priority-updates
95. --lower-case-table-names
96. --master-connect-retry
97. --max-allowed-packet
98. --max-connections
99. --max-connect-errors
100. --max-delayed-threads
101. --max-digest-length
102. --max-error-count
103. --max-length-for-sort-data
104. --max-long-data-size
105. --max-password-errors
106. --max-prepared-stmt-count
107. --max-recursive-iterations
108. --max-rowid-filter-size
109. --max-session-mem-used
110. --max-sp-recursion-depth
111. --max-statement-time
112. --max-tmp-tables
113. --max-user-connections 1563/3812
113. --max-user-connections
114. --max-write-lock-count
115. --memlock
116. --metadata-locks-cache-size
117. --metadata-locks-hash-instances
118. --min-examined-row-limit
119. --mrr-buffer-size
120. --multi-range-count
121. --mysql56-temporal-format
122. --ndb-use-copying-alter-table
123. --net-buffer-length
124. --net-read-timeout
125. --net-retry-count
126. --net-write-timeout
127. --one-thread
128. --open-files-limit
129. --pid-file
130. --plugin-load
131. --plugin-load-add
132. --plugin-dir
133. --plugin-maturity
134. --port
135. --port-open-timeout
136. --preload-buffer-size
137. --profiling-history-size
138. --progress-report-time
139. --proxy-protocol-networks
140. --query-cache-info
141. --query-cache-limit
142. --query-cache-min-res-unit
143. --query-cache-size
144. --query-cache-strip-comments
145. --query-cache-type
146. --query-cache-wlock-invalidate
147. --read-rnd-buffer-size
148. --read-only
149. --require-secure-transport
150. --safe-show-database
151. --safe-user-create
152. --safemalloc-mem-limit
153. --secure-auth
154. --secure-file-priv
155. --secure-timestamp
156. --session-track-schema
157. --session-track-state-change
158. --session-track-system-variables
159. --session-track-transaction-info
160. --show-slave-auth-info
161. --skip-automatic-sp-privileges
162. --skip-external-locking
163. --skip-grant-tables
164. --skip-host-cache
165. --skip-large-pages
166. --skip-log-error
167. --skip-name-resolve
168. --skip-networking
169. --skip-partition
170. --skip-show-database
171. --skip-slave-start
172. --skip-ssl
173. --skip-symlink
174. --skip-thread-priority
175. --slow-launch-time
176. --slow-query-log
177. --slow-query-log-file
178. --socket
179. --sort-buffer-size
180. --sql-bin-update-same
181. --sql-if-exists
182. --sql-mode
183. --ssl
184. --ssl-ca
1564/3812
185. --ssl-capath
186. --ssl-cert
187. --ssl-cipher
188. --ssl-crl
189. --ssl-crlpath
190. --ssl-key
191. --stack-trace
192. --standard-compliant-cte
193. --stored-program-cache
194. --strict-password-validation
195. --symbolic-links
196. --sync-frm
197. --system-versioning-alter-history
198. --system-versioning-asof
199. --system-versioning-innodb-algorithm-
simple
200. --system-versioning-insert-history
201. --table-lock-wait-timeout
202. --tc-heuristic-recover
203. --tcp-keepalive-interval
204. --tcp-keepalive-probes
205. --tcp-keepalive-time
206. --tcp-nodelay
207. --temp-pool
208. --test-expect-abort
209. --test-ignore-wrong-options
210. --thread-cache-size
211. --thread-concurrency
212. --thread-handling
213. --thread-pool-dedicated-listener
214. --thread-pool-exact-stats
215. --thread-pool-idle-timeout
216. --thread-pool-max-threads
217. --thread-pool-min-threads
218. --thread-pool-prio-kickup-timer
219. --thread-pool-priority
220. --thread-pool-size
221. --thread-pool-stall-limit
222. --thread-stack
223. --timed-mutexes
224. --time-format
225. --tls_version
226. --tmpdir
227. --transaction-isolation
228. --transaction-alloc-block-size
229. --transaction-prealloc-size
230. --transaction-read-only
231. --updatable-views-with-limit
232. --user
233. --userstat
234. --verbose
235. --version
236. --wait-timeout
13. Other Options and System Variables
14. Authentication Plugins - Options and
System Variables
1. Authentication Plugin - ed25519
1. ed25519
2. Authentication Plugin - gssapi
1. gssapi
2. gssapi_keytab_path
3. gssapi_principal_name
4. gssapi_mech_name
3. Authentication Plugin - named_pipe
1. named_pipe
4. Authentication Plugin - pam
1. pam
2. pam_debug
3. pam_use_cleartext_plugin
4. pam_winbind_workaround
5. Authentication Plugin - unix_socket
1. unix_socket
1565/3812
1. unix_socket
15. Encryption Plugins - Options and System
Variables
1. Encryption Plugin -
aws_key_management
1. aws_key_management
2. aws_key_management_key_spec
3. aws_key_management_log_level
4. aws_key_management_master_key_id
5. aws_key_management_mock
6. aws_key_management_region
7. aws_key_management_request_timeout
8. aws_key_management_rotate_key
2. Encryption Plugin -
file_key_management
1. file_key_management
2. file_key_management_encryption_algorithm
3. file_key_management_filekey
4. file_key_management_filename
16. Password Validation Plugins - Options
and System Variables
1. Password Validation Plugin -
simple_password_check
1. simple_password_check
2. simple_password_check_digits
3. simple_password_check_letters_same_case
4. simple_password_check_minimal_length
5. simple_password_check_other_characters
2. Password Validation Plugin -
cracklib_password_check
1. cracklib_password_check
2. cracklib_password_check_dictionary
17. Audit Plugins - Options and System
Variables
1. Audit Plugin - server_audit
1. server-audit
2. server-audit-events
3. server-audit-excl-users
4. server-audit-file-path
5. server-audit-file-rotate-now
6. server-audit-file-rotate-size
7. server-audit-file-rotations
8. server-audit-incl-users
9. server-audit-logging
10. server-audit-mode
11. server-audit-output-type
12. server-audit-query-limit
13. server-audit-syslog-facility
14. server-audit-syslog-ident
15. server-audit-syslog-info
16. server-audit-syslog-priority
2. Audit Plugin - SQL_ERROR_LOG
1. sql_error_log
2. sql_error_log_filename
3. sql_error_log_filename
4. sql_error_log_rate
5. sql_error_log_rotate
6. sql_error_log_rotations
7. sql_error_log_size_limit
3. Audit Plugin -
QUERY_RESPONSE_TIME_AUDIT
1. query_response_time_audit
18. Daemon Plugins - Options and System
Variables
1. Daemon Plugin - handlersocket
1. handlersocket-accept-balance
2. handlersocket-address
3. handlersocket-backlog
4. handlersocket-epoll
5. handlersocket-plain-secret
6. handlersocket-plain-secret-wr
7. handlersocket-port
8. handlersocket-port-wr
1566/3812
8. handlersocket-port-wr
9. handlersocket-rcvbuf
10. handlersocket-readsize
11. handlersocket-sndbuf
12. handlersocket-threads
13. handlersocket-threads-wr
14. handlersocket-timeout
15. handlersocket-verbose
16. handlersocket-wrlock-timeout
19. Information Schema Plugins - Options
and System Variables
1. Information Schema Plugin - DISKS
1. disks
2. Information Schema Plugin - feedback
1. feedback
2. feedback_http_proxy
3. feedback_send_retry_wait
4. feedback_send_timeout
5. feedback_url
6. feedback_user_info
3. Information Schema Plugin -
LOCALES
1. locales
4. Information Schema Plugin -
METADATA_LOCK_INFO
1. metadata_lock_info
5. Information Schema Plugin -
QUERY_CACHE_INFO
1. query_cache_info
6. Information Schema Plugin -
QUERY_RESPONSE_TIME
1. query_response_time
2. query_response_time_flush
3. query_response_time_range_base
4. query_response_time_exec_time_debug
5. query_response_time_stats
7. Information Schema Plugin -
user_variables
1. user_variables
8. Information Schema Plugin -
WSREP_MEMBERSHIP
1. wsrep_membership
9. Information Schema Plugin -
WSREP_STATUS
1. wsrep_status
20. Replication Plugins - Options and
System Variables
1. Replication Plugin -
rpl_semi_sync_master
1. rpl_semi_sync_master
2. rpl-semi-sync-master-enabled
3. rpl-semi-sync-master-timeout
4. rpl-semi-sync-master-trace-level
5. rpl-semi-sync-master-wait-no-slave
6. rpl-semi-sync-master-wait-point
2. Replication Plugin -
rpl_semi_sync_slave
1. rpl_semi_sync_slave
2. rpl-semi-sync-slave-delay-master
3. rpl-semi-sync-slave-kill-conn-
timeout
4. rpl-semi-sync-slave-enabled
5. rpl-semi-sync-slave-trace-level
21. Default Values

This page lists all of the options for mysqld / mariadbd , ordered by topic. For a full alphabetical list of all mysqld
options, as well as server and status variables, see Full list of MariaDB options, system and status variables.
In many cases, the entry here is a summary, and links to the full description.
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.

1567/3812
See mysqld startup options for which files and groups mysqld reads for it's default options.

Option Prefixes
--autoset-*
Description: Sets the option value automatically. Only supported for certain options. Available in MariaDB 10.1.7
and later.

--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.

--defaults-file
Commandline: --defaults-file=name
Description: Only read options from the given option file.
See Configuring MariaDB with Option Files.

--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.

--no-defaults
Commandline: --no-defaults
Description: Don't read options from any option file.
See Configuring MariaDB with Option Files.

--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.

Compatibility Options
1568/3812
The following options have been added to MariaDB to make it more compliant with other MariaDB and MySQL versions:

-a, --ansi
Description: Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level
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 is disabled,
myisam_recover_options is set to DEFAULT (automatically recover crashed MyISAM files) and the query cache is
disabled. For Aria tables, disable bulk insert optimization to enable one to use aria_read_log to recover tables
even if tables are deleted (good for testing recovery).

--skip-new
Description: Disables --new in 5.2. In 5.1 used to disable some new potentially unsafe functions.

Compatibility Options and System Variables


--old
--old-alter-table
--old-mode
--old-passwords
--show-old-temporals

Locale Options
--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 as a server option. Use 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. See
Server Locales for a list of supported locales and their associated languages.
This option is deprecated. Use the lc_messages and lc_messages_dir system variables instead.
See Setting the Language for Error Messages for more information.

Locale Options and System Variables


1569/3812
character-set-filesystem
character-set-client
character-set-connection
character-set-database
character-set-filesystem
character-set-results
character-set-server
character-set-system
character-sets-dir
collation-connection
collation-database
collation-server
default-week-format
default-time-zone
lc-messages
lc-messages-dir
lc-time-names

Windows Options
--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, the last option will take precedence.

--install
Description: Windows-only option that installs the mysqld process as a Windows service.
The Windows service created with this option auto-starts . If you want a service that is started on demand
, then use the --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 "MySQL".
This option is deprecated and may be removed in a future version. See MDEV-19358 for more
information.

--install-manual
Description: Windows-only option that installs the mysqld process as a Windows service.
The Windows service created with this option is started on demand . If you want a service that auto-starts
, use the --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 "MySQL".
This option is deprecated and may be removed in a future version. See MDEV-19358 for more
information.

--remove
Description: Windows-only option that removes the Windows service created by the --install or --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 "MySQL".
This option is deprecated and may be removed in a future version. See 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.

1570/3812
Windows Options and System Variables
The following options and system variables are related to using MariaDB on Windows:
--named-pipe

Replication and Binary Logging Options


The following options are related to replication and the binary log:

--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 to write statements and transactions
affecting databases that match a specified name into its binary log. Since the filtered statements or transactions
will not be present in the binary log, its replication slaves will not be able to replicate them.
This option will not work with cross-database updates with statement-based logging. See the 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 in an option file, 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 for more information.

--binlog-ignore-db
Commandline: --binlog-ignore-db=name
Description: This option allows you to configure a replication master to not write statements and transactions
affecting databases that match a specified name into its binary log. Since the filtered statements or transactions
will not be present in the binary log, its replication slaves will not be able to replicate them.
This option will not work with cross-database updates with statement-based logging. See the 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 in an option file, 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 for more information.

--binlog-row-event-max-size
Commandline: --binlog-row-event-max-size=#
Description: The maximum size of a row-based binary log event in bytes. Rows will be grouped into events
smaller than this size if possible. The value has to be a multiple of 256.
Default value
8192 (>= MariaDB 10.2.4 )
1024 (<= MariaDB 10.2.3 )

--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 and sets binlog_format=ROW .
Introduced: MariaDB 10.2.4

--init-rpl-role
1571/3812
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 as it ensures that your log file names are not dependent on your host name. Sets names for log-
bin, log-bin-index, relay-log, relay-log-index, general-log-file, --log-slow-query-log-file , --log-error-file ,
and pid-file.
Introduced: MariaDB 5.2

--log-bin-trust-routine-creators
Commandline: --log-bin-trust-routine-creators
Description: Deprecated, use log-bin-trust-function-creators.

--master-host
Commandline: --master-host=name
Description: Master hostname or IP address for replication. If not set, the slave 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 where the MASTER_LOG_FILE and MASTER_LOG_POS options (i.e. the
binary log position on the master) and most other CHANGE MASTER options are written. The slave's I/O thread
keeps this binary log position updated as it downloads events.
See CHANGE MASTER TO: Option Persistence for more information.

--master-password
Commandline: --master-password=name
Description: The password the slave thread will authenticate with when connecting to the master. 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 slave will attempt to connect to a master 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 slave will not stop attempting to reconnect. Reconnects are triggered when a slave has timed out. See
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 slave to connect to the master using TLS.

1572/3812
--master-ssl-ca
Commandline: --master-ssl-ca[=name]
Description: Master TLS CA file. Only applies if you have enabled 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-cert
Commandline: --master-ssl-cert[=name]
Description: Master TLS certificate file name. Only applies if you have enabled master-ssl.

--master-ssl-cipher
Commandline: --master-ssl-cipher[=name]
Description: Master TLS cipher. Only applies if you have enabled master-ssl.

--master-ssl-key
Commandline: --master-ssl-key[=name]
Description: Master TLS keyfile name. Only applies if you have enabled master-ssl.

--master-user
Commandline: --master-user=name
Description: The username the slave thread will use for authentication when connecting to the master. The user
must have FILE privilege. If the master 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 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() to NOW() to make it safe for replication. 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 and the binary log:
auto-increment-increment
auto-increment-offset
1573/3812
binlog-annotate-row-events
binlog-cache-size
binlog-checksum
binlog-commit-wait-count
binlog-commit-wait-usec
binlog-direct-non-transactional-updates|
binlog-expire-logs-seconds
binlog-file-cache-size
binlog-format
binlog-optimize-thread-scheduling
binlog-row-image
binlog-row-metadata
binlog-stmt-cache-size
default-master-connection
gtid-cleanup-batch-size
gtid-domain-id
gtid-ignore-duplicates
gtid-strict-mode
init-slave
log-bin
log-bin-compress
log-bin-compress-min-len
log-bin-index
log-bin-trust-function-creators
log-slave-updates
master-verify-checksum
max-binlog-cache-size
max-binlog-size
max-binlog-stmt-cache-size
max-relay-log-size
read-binlog-speed-limit
relay-log
relay-log-index
relay-log-info-file
relay-log-purge
relay-log-recovery
relay-log-space-limit
replicate-annotate-row-events
replicate-do-db
replicate-do-table
replicate-events-marked-for-skip
replicate-ignore-db
replicate-ignore-table
replicate-rewrite-db
replicate-wild-do-table
replicate-wild-ignore-table
report-host
report-password
report-port
report-user
rpl-recovery-rank
server-id
slave-compressed-protocol
slave-ddl-exec-mode
slave-domain-parallel-threads
slave-exec-mode
slave-load-tmpdir
slave-max-allowed-packet
slave-net-timeout
slave-parallel-max-queued
slave-parallel-threads
slave-run-triggers-for-rbr
slave-skip-errors
slave-sql-verify-checksum
slave-transaction-retries
slave_transaction_retry_errors
slave_transaction_retry_interval
slave-type-conversions
sync-binlog
sync-master-info
sync-relay-log

1574/3812
sync-relay-log-info

Semisynchronous Replication Options and System Variables


The options and system variables related to Semisynchronous Replication are described here.

Optimizer Options
--record-buffer
Commandline: --record-buffer=#
Description: Old alias for read_buffer_size.
Removed: MariaDB 5.5

--table-cache
Commandline: --table-open-cache=#
Description: Removed; use --table-open-cache instead.
Removed: MariaDB 5.1.3

Optimizer Options and System Variables


alter-algorithm
analyze-sample-percentage
big-tables
bulk-insert-buffer-size
expensive-subquery-limit
join-buffer-size
join-buffer-space-limit
join-cache-level
max-heap-table-size
max-join-size
max-seeks-for-key
max-sort-length
mrr-buffer-size
optimizer-max-sel-arg-weight
optimizer-prune-level
optimizer-search-depth
optimizer-selectivity-sampling-limit
optimizer-switch
optimizer-trace
optimizer-trace-max-mem-size
optimizer-use-condition-selectivity
query-alloc-block-size
query-prealloc-size
range-alloc-block-size
read-buffer-size
rowid-merge-buff-size
table-definition-cache
table-open-cache
table-open-cache-instances
tmp-disk-table-size
tmp-memory-table-size
tmp-table-size
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

--external-locking
1575/3812
Commandline: --external-locking
Description: Use system (external) locking (disabled by default). With this option enabled you can run
myisamchk to test (not repair) tables while the server is running. Disable with --skip-external-locking. From
MariaDB 10.2.40 , MariaDB 10.3.31, MariaDB 10.4.21, MariaDB 10.5.12, MariaDB 10.6.4 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 storage engine are described below.

--log-isam
Commandline: --log-isam[=file_name]
Description: Enable the MyISAM log, 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 storage engine can be found here. Direct links to many of
them can be found below.
concurrent-insert
delayed-insert-limit
delayed-insert-timeout
delayed-queue-size
keep-files-on-create
key-buffer-size
key-cache-age-threshold
key-cache-block-size
key-cache-division-limit
key-cache-file-hash-size
key-cache-segments
myisam-block-size
myisam-data-pointer-size
myisam-max-sort-file-size
myisam-mmap-size
myisam-recover-options
myisam-repair-threads
myisam-sort-buffer-size
myisam-stats-method
myisam-use-mmap

InnoDB Storage Engine Options


The options related to the InnoDB storage engine are described below.

--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). 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. 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:
1576/3812
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

--innodb-index-stats
Commandline: --innodb-index-stats
Description:
Default: ON
Removed: MariaDB 10.0.0

--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

--innodb-status-file
Commandline: --innodb-status-file
Description:
Default: FALSE

--innodb-sys-indexes
Commandline: --innodb-sys-indexes
Description:
Default: ON

1577/3812
--innodb-sys-stats
Commandline: --innodb-sys-stats
Description:
Default: ON
Removed: MariaDB 10.0.0

--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

--innodb-trx
Commandline: --innodb-trx
Description:
Default: ON

InnoDB Storage Engine Options and System Variables


Some options and system variables related to the InnoDB storage engine can be found here. Direct links to many of
them can be found below.
ignore-builtin-innodb
innodb-adaptive-checkpoint
innodb-adaptive-flushing
innodb-adaptive-flushing-lwm
innodb-adaptive-flushing-method
innodb-adaptive-hash-index
innodb-adaptive-hash-index-partitions
innodb-adaptive-hash-index-parts
innodb-adaptive-max-sleep-delay
innodb-additional-mem-pool-size
innodb-api-bk-commit-interval
innodb-api-disable-rowlock
innodb-api-enable-binlog
innodb-api-enable-mdl
innodb-api-trx-level
innodb-auto-lru-dump
innodb-autoextend-increment
innodb-autoinc-lock-mode
innodb-background-scrub-data-check-interval
innodb-background-scrub-data-compressed
innodb-background-scrub-data-interval
innodb-background-scrub-data-uncompressed
innodb-blocking-buffer-pool-restore
innodb-buf-dump-status-frequency
innodb-buffer-pool-chunk-size
innodb-buffer-pool-dump-at-shutdown
innodb-buffer-pool-dump-now
innodb-buffer-pool-dump-pct
innodb-buffer-pool-evict
innodb-buffer-pool-filename
innodb-buffer-pool-instances
innodb-buffer-pool-load-abort
innodb-buffer-pool-load-at-startup
innodb-buffer-pool-load-now
innodb-buffer-pool-load-pages-abort
innodb-buffer-pool-populate
innodb-buffer-pool-restore-at-startup
1578/3812
innodb-buffer-pool-shm-checksum
innodb-buffer-pool-shm-key
innodb-buffer-pool-size
innodb-change-buffer-max-size
innodb-change-buffering
innodb-change-buffering-debug
innodb-checkpoint-age-target
innodb-checksum-algorithm
innodb-checksums
innodb-cleaner-lsn-age-factor
innodb-cmp-per-index-enabled
innodb-commit-concurrency
innodb-compression-algorithm
innodb-compression-failure-threshold-pct
innodb-compression-level
innodb-compression-pad-pct-max
innodb-concurrency-tickets
innodb-corrupt-table-action
innodb-data-file-path
innodb-data-home-dir
innodb-deadlock-detect
innodb-deadlock-report
innodb-default-encryption-key-id
innodb-default-page-encryption-key
innodb-default-row-format
innodb-defragment
innodb-defragment-fill-factor
innodb-defragment-fill-factor-n-recs
innodb-defragment-frequency
innodb-defragment-n-pages
innodb-defragment-stats-accuracy
innodb-dict-size-limit
innodb_disable_sort_file_cache
innodb-doublewrite
innodb-doublewrite-file
innodb-empty-free-list-algorithm
innodb-enable-unsafe-group-commit
innodb-encrypt-log
innodb-encrypt-tables
innodb-encrypt-temporary-tables
innodb-encryption-rotate-key-age
innodb-encryption-rotation_iops
innodb-encryption-threads
innodb-extra-rsegments
innodb-extra-undoslots
innodb-fake-changes
innodb-fast-checksum
innodb-fast-shutdown
innodb-fatal-semaphore-wait-threshold
innodb-file-format
innodb-file-format-check
innodb-file-format-max
innodb-file-per-table
innodb-fill-factor
innodb-flush-log-at-trx-commit
innodb-flush-method
innodb-flush-neighbor-pages
innodb-flush-neighbors
innodb-flush-sync
innodb-flushing-avg-loops
innodb-force-load-corrupted
innodb-force-primary-key
innodb-force-recovery
innodb-foreground-preflush
innodb-ft-aux-table
innodb-ft-cache-size
innodb-ft-enable-diag-print
innodb-ft-enable-stopword
innodb-ft-max-token-size
innodb-ft-min-token-size
innodb-ft-num-word-optimize
1579/3812
innodb-ft-result-cache-limit
innodb-ft-server-stopword-table
innodb-ft-sort-pll-degree
innodb-ft-total-cache-size
innodb-ft-user-stopword-table
innodb-ibuf-accel-rate
innodb-ibuf-active-contract
innodb-ibuf-max-size
innodb-idle-flush-pct
innodb-immediate-scrub-data-uncompressed
innodb-import-table-from-xtrabackup
innodb-instant-alter-column-allowed
innodb-instrument-semaphores
innodb-io-capacity
innodb-io-capacity-max
innodb-large-prefix
innodb-lazy-drop-table
innodb-lock-schedule-algorithm
innodb-locking-fake-changes
innodb-locks-unsafe-for-binlog
innodb-log-arch-dir
innodb-log-arch-expire-sec
innodb-log-archive
innodb-log-block-size
innodb-log-buffer-size
innodb-log-checksum-algorithm
innodb-log-checksums
innodb-log-compressed-pages
innodb-log-file-buffering
innodb-log-file-size
innodb-log-files-in-group
innodb-log-group-home-dir
innodb-log-optimize-ddl
innodb-log-write-ahead-size
innodb-lru-flush-size
innodb-lru-scan-depth
innodb-max-bitmap-file-size
innodb-max-changed-pages
innodb-max-dirty-pages-pct
innodb-max-dirty-pages-pct-lwm
innodb-max-purge-lag
innodb-max-purge-lag-delay
innodb-max-purge-lag-wait
innodb-max-undo-log-size
innodb-merge-sort-block-size
innodb-mirrored-log-groups
innodb-monitor-disable
innodb-monitor-enable
innodb-monitor-reset
innodb-monitor-reset-all
innodb-mtflush-threads
innodb-numa-interleave
innodb-old-blocks-pct
innodb-old-blocks-time
innodb-online-alter-log-max-size
innodb-open-files
innodb-optimize-fulltext-only
innodb-page-cleaners
innodb-page-size
innodb-pass-corrupt-table
innodb-prefix-index-cluster-optimization
innodb-print-all-deadlocks
innodb-purge-batch-size
innodb-purge-rseg-truncate-frequency
innodb-purge-threads
innodb-random-read-ahead
innodb-read-ahead
innodb-read-ahead-threshold
innodb-read-io-threads
innodb-read-only
innodb-recovery-update-relay-log

1580/3812
innodb-replication-delay
innodb-rollback-on-timeout
innodb-rollback-segments
innodb-safe-truncate
innodb-sched-priority-cleaner
innodb-scrub-log
innodb-scrub-log-interval
innodb-scrub-log-speed
innodb-show-locks-held
innodb-show-verbose-locks
innodb-sort-buffer-size
innodb-spin-wait-delay
innodb-stats-auto-recalc
innodb-stats-auto-update
innodb-stats-include-delete-marked
innodb-stats-method
innodb-stats-modified-counter
innodb-stats-on-metadata
innodb-stats-persistent
innodb-stats-persistent-sample-pages
innodb-stats-sample-pages
innodb-stats-transient-sample-pages
innodb-stats-traditional
innodb-stats-update-need-lock
innodb-status-output
innodb-status-output-locks
innodb-strict-mode
innodb-support-xa
innodb-sync-array-size
innodb-sync-spin-loops
innodb-table-locks
innodb-temp-data-file-path
innodb-thread-concurrency
innodb-thread-concurrency-timer-based
innodb-thread-sleep-delay
innodb-tmpdir
innodb-track-changed-pages
innodb-track-redo-log-now
innodb-undo-directory
innodb-undo-log-truncate
innodb-undo-logs
innodb-undo-tablespaces
innodb-use-atomic-writes
innodb-use-fallocate
innodb-use-global-flush-log-at-trx-commit
innodb-use-mtflush
innodb-use-native_aio
innodb-use-purge-thread
innodb-use-stacktrace
innodb-use-sys-malloc
innodb-use-sys-stats-table
innodb-use-trim
innodb-write-io-threads
skip-innodb
skip-innodb-checksums
skip-innodb-doublewrite

Aria Storage Engine Options


The options related to the Aria storage engine are described below.

--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 storage engine can be found here. Direct links to many of them
1581/3812
can be found below.
aria-block-size
aria-checkpoint-interval
aria-checkpoint-log-activity
aria-encrypt-tables
aria-force-start-after-recovery-failures
aria-group-commit
aria-group-commit-interval
aria-log-file-size
aria-log-purge-type
aria-max-sort-file-size
aria-page-checksum
aria-pagecache-age-threshold
aria-pagecache-buffer-size
aria-pagecache-division-limit
aria-pagecache-file-hash-size
aria-recover
aria-recover-options
aria-repair-threads
aria-sort-buffer-size
aria-stats-method
aria-sync-log-dir
aria-used-for-temp-tables
deadlock-search-depth-long
deadlock-search-depth-short
deadlock-timeout-long
deadlock-timeout-short

MyRocks Storage Engine Options


The options and system variables related to the MyRocks storage engine can be found here.

S3 Storage Engine Options


The options and system variables related to the S3 storage engine can be found here.

CONNECT Storage Engine Options


The options related to the CONNECT storage engine are described below.

CONNECT Storage Engine Options and System Variables


Some options and system variables related to the CONNECT storage engine can be found here. Direct links to many of
them can be found below.
connect-class-path
connect-cond-push
connect-conv-size
connect-default-depth
connect-default-prec
connect-enable-mongo
connect-exact-info
connect-force_bson
connect-indx-map
connect-java-wrapper
connect-json-all-path
connect-json-grp-size
connect-json-null
connect-jvm-path
connect-type-conv
connect-use-tempfile
connect-work-size
connect-xtrace

Spider Storage Engine Options


The options and system variables related to the Spider storage engine can be found here.

Mroonga Storage Engine Options


1582/3812
The options and system variables related to the Mroonga storage engine can be found here.

TokuDB Storage Engine Options


The options and system variables related to the TokuDB storage engine can be found here .

Performance Schema Options


The options related to the Performance Schema are described below.

--performance-schema-consumer-events-stages-current
Commandline: --performance-schema-consumer-events-stages-current
Description: Enable the events-stages-current consumer.
Default: OFF

--performance-schema-consumer-events-stages-history
Commandline: --performance-schema-consumer-events-stages-history
Description: Enable the events-stages-history 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 consumer.
Default: OFF

--performance-schema-consumer-events-statements-current
Commandline: --performance-schema-consumer-events-statements-current
Description: Enable the events-statements-current 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 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 consumer.
Default: OFF

--performance-schema-consumer-events-waits-current
Commandline: --performance-schema-consumer-events-waits-current
Description: Enable the events-waits-current consumer.
Default: OFF

--performance-schema-consumer-events-waits-history
Commandline: --performance-schema-consumer-events-waits-history
Description: Enable the events-waits-history consumer.
Default: OFF

--performance-schema-consumer-events-waits-history-long

1583/3812
Commandline: --performance-schema-consumer-events-waits-history-long
Description: Enable the events-waits-history-long 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 can be found here. Direct links to many of them
can be found below.
performance-schema
performance-schema-accounts-size
performance-schema-digests-size
performance-schema-events-stages-history-long-size
performance-schema-events-stages-history-size
performance-schema-events-statements-history-long-size
performance-schema-events-statements-history-size
performance-schema-events-waits-history-long-size
performance-schema-events-waits-history-size
performance-schema-hosts-size
performance-schema-max-cond-classes
performance-schema-max-cond-instances
performance-schema-max-digest-length
performance-schema-max-file-classes
performance-schema-max-file-handles
performance-schema-max-file-instances
performance-schema-max-mutex-classes
performance-schema-max-mutex-instances
performance-schema-max-rwlock-classes
performance-schema-max-rwlock-instances
performance-schema-max-socket-classes
performance-schema-max-socket-instances
performance-schema-max-stage-classes
performance-schema-max-statement-classes
performance-schema-max-table-handles
performance-schema-max-table-instances
performance-schema-max-thread-classes
performance-schema-max-thread-instances
performance-schema-session-connect-attrs-size
performance-schema-setup-actors-size
performance-schema-setup-objects-size
performance-schema-users-size

Galera Cluster Options


The options related to Galera Cluster are described below.
1584/3812
--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 can be found here. Direct links to many of them can be
found below.
wsrep-auto-increment-control
wsrep-causal-reads
wsrep-certify-nonPK
wsrep-cluster-address
wsrep-cluster-name
wsrep-convert-LOCK-to-trx
wsrep-data-home-dir
wsrep-dbug-option
wsrep-debug
wsrep-desync
wsrep-dirty-reads
wsrep-drupal-282555-workaround
wsrep-forced-binlog-format
wsrep-gtid-domain-id
wsrep-gtid-mode
wsrep-ignore-apply-errors
wsrep-load-data-splitting
wsrep-log-conflicts
wsrep-max-ws-rows
wsrep-max-ws-size
wsrep-mode
wsrep-mysql-replication-bundle
wsrep-node-address
wsrep-node-incoming-address
wsrep-node-name
wsrep-notify-cmd
wsrep-on
wsrep-OSU-method
wsrep-provider
wsrep-provider-options
wsrep-recover
wsrep-reject_queries
wsrep-retry-autocommit
wsrep-slave-FK-checks
wsrep-slave-threads
wsrep-slave-UK-checks
wsrep-sr-store
wsrep-sst-auth
wsrep-sst-donor
wsrep-sst-donor-rejects-queries
wsrep-sst-method
wsrep-sst-receive-address
wsrep-start-position
wsrep-strict-ddl
wsrep-sync-wait
wsrep-trx_fragment_size
wsrep-trx_fragment_unit

Options When Debugging mysqld


--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 to flush transactions to disk. This can thus be used to artificially increase the
1585/3812
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 during startup.
Introduced: MariaDB 10.1.8

--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 from MariaDB 5.5.
Removed: MariaDB 5.5

--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
debug
debug-no-thread-alarm

Other Options
--allow-suspicious-udfs
Commandline: --allow-suspicious-udfs
Description: Allows use of user-defined functions 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 mysql installation scripts, such as mysql_install_db to execute SQL scripts before any

1586/3812
privilege or system tables exist. Do no use while an existing MariaDB instance is running.

--chroot
Commandline: --chroot=name
Description: Chroot mysqld daemon during startup.

--des-key-file
Commandline: --des-key-file=name
Description: Load keys for des_encrypt() 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

--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

--log-short-format
Commandline: --log-short-format
Description: Don't log extra information to update and slow-query logs.

--log-slow-file
Commandline: --log-slow-file=name
Description: Log slow queries 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 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 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 for more information. Also see the the
log_tc_size system variable and the --tc-heuristic-recover option.
Default Value: tc.log
1587/3812
--master-connect-retry
Commandline: --master-connect-retry=#
Description: Deprecated in 5.1.17 and removed in 5.5. The number of seconds the slave 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 mysqld 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
instead.
Removed: MariaDB 10.0.4

--plugin-load
Commandline: --plugin-load=name
Description: This option can be used to configure the server to load specific plugins. 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 option multiple times, or when specifying both
the --plugin-load option and the --plugin-load-add option together. The --plugin-load option resets the
plugin load list, and this can cause unexpected problems if you are not aware. The --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 for more information.
See Plugin Overview: 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. 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 option and the --plugin-load-add option
together. The --plugin-load option resets the plugin load list, and this can cause unexpected problems if you
are not aware. The --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 for more information.
See Plugin Overview: Installing a Plugin with Plugin Load Options for more information.
Introduced: MariaDB 10.0.1

--port-open-timeout
Commandline: --port-open-timeout=#
Description: Maximum time in seconds to wait for the port to become free. (Default: No wait).

1588/3812
--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 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 master.

--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 mysqladmin flush-privileges, mysqladmin reload or FLUSH PRIVILEGES to resume
using the 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. Previously partitioned tables cannot be accessed or modifed.
Tables can still be seen with SHOW TABLES or by viewing the INFORMATION_SCHEMA.TABLES table. Tables
can be dropped with DROP TABLE, 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, slave is not autostarted.

--skip-ssl
Commandline: --skip-ssl
Description: Disable TLS connections.

--skip-symlink
Commandline: --skip-symlink
Description: Don't allow symlinking of tables. Deprecated and removed in MariaDB 5.5. Use symbolic-links with
the skip option prefix instead.
Removed: MariaDB 5.5

--skip-thread-priority
Commandline: --skip-thread-priority
Description: Don't give threads different priorities. Deprecated and removed in MariaDB 10.0.
Removed: MariaDB 10.0

--sql-bin-update-same

1589/3812
Commandline: --sql-bin-update-same=#
Description: The update log was deprecated in version 5.0 and replaced by the binary log, so this option did
nothing since then. Deprecated and removed in MariaDB 5.5.
Removed: MariaDB 5.5

--ssl
Commandline: --ssl
Description: Enable TLS for connection (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 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 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 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 server option and the 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, use --skip-temp-pool to disable.
Deprecated and defaults to 0 from MariaDB 10.5.7, 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 mysqld daemon as user.

--verbose
Commandline: -v , --verbose
Description: Used with help option for detailed help.

Other Options and System Variables


1590/3812
allow-suspicious-udfs
automatic-sp-privileges
back-log
basedir
check-constraint-checks
column-compression-threshold
column-compression-zlib-level
column-compression-zlib-strategy
column-compression-zlib-wrap
completion-type
connect-timeout
datadir
date-format
datetime-format
deadlock-search-depth-long
deadlock-search-depth-short
deadlock-timeout-long
deadlock-timeout-short
default-password-lifetime
default-regex-flags
default-storage-engine
default-table-type
delay-key-write
disconnect-on-expired-password
div-precision-increment
enable-named-pipe
encrypt-binlog
encrypt-tmp-disk-tables
encrypt-tmp-files
encryption-algorithm
engine-condition-pushdown
eq-range-index-dive-limit
event-scheduler
expire-logs-days
explicit-defaults-for-timestamp
extra-max-connections
extra-port
flush
flush-time
ft-boolean-syntax
ft-max-word-len
ft-min-word-len
ft-query-expansion-limit
ft-stopword-file
general-log
general-log-file
group-concat-max-len
histogram-size
histogram-type
host-cache-size
idle-readonly-transaction-timeout
idle-transaction-timeout
idle-write-transaction-timeout
ignore-db-dirs
in-predicate-conversion-threshold
init-connect
init-file
interactive-timeout
large-pages
local-infile
lock-wait-timeout
log
log-disabled-statements
log-error
log-output
log-queries-not-using-indexes
log-slow-admin-statements
log-slow-disabled-statements
log-slow-filter
log-slow-min-examined-row-limit
log-slow-queries

1591/3812
log-slow-query
log-slow-query-file
log-slow-query-time
log-slow-rate-limit
log-slow-slave-statements
log-slow-verbosity
log-tc-size
log-warnings
long-query-time
low-priority-updates
lower-case-table-names
max-allowed-packet
max-connections
max-connect-errors
max-delayed-threads
max-digest-length
max-error-count
max-length-for-sort-data
max-long-data-size
max-password-errors
max-prepared-stmt-count
max-recursive-iterations
max-rowid-filter-size
max-session-mem-used
max-sp-recursion-depth
max-statement-time
max-tmp-tables
max-user-connections
max-write-lock-count
metadata-locks-cache-size
metadata-locks-hash-instances
min-examined-row-limit
mrr-buffer-size
multi-range-count
--mysql56-temporal-format
net-buffer-length
net-read-timeout
net-retry-count
net-write-timeout
open-files-limit
pid-file
plugin-dir
plugin-maturity
port
preload-buffer-size
profiling-history-size
progress-report-time
proxy-protocol-networks
query-cache-limit
query-cache-min-res-unit
query-cache-strip-comments
query-cache-wlock-invalidate
read-rnd-buffer-size
read-only
require-secure-transport
safe-show-database
secure-auth
secure-file-priv
secure-timestamp
session-track-schema
session-track-state-change
session-track-system-variables
session-track-transaction-info
skip-automatic-sp-privileges
skip-external-locking
skip-large-pages
skip-log-error
skip-name-resolve
skip-networking
skip-show-database
slow-launch-time

1592/3812
slow-query-log
slow-query-log-file
socket
sort-buffer-size
sql-if-exists
sql-mode
ssl-ca
ssl-capath
ssl-cert
ssl-cipher
ssl-crl
ssl-crlpath
ssl-key
standards_compliant_cte
stored-program-cache
strict_password_validation
sync-frm
system-versioning-alter-history
system-versioning-asof
system-versioning-innodb-algorithm-simple
system-versioning-insert-history
table-lock-wait-timeout
tcp-keepalive-interval
tcp-keepalive-probes
tcp-keepalive-time
tcp-nodelay
thread-cache-size
thread-concurrency
thread-handling
thread-pool-dedicated-listener
thread-pool-exact-stats
thread-pool-idle-timeout
thread-pool-max-threads
thread-pool-min-threads
thread-pool-oversubscribe
thread-pool-prio-kickup-timer
thread-pool-priority
thread-pool-size
thread-pool-stall-limit
thread-stack
timed-mutexes
time-format
tls-version
tmpdir
transaction-isolation
transaction-alloc-block-size
transaction-prealloc-size
transaction-read-only
updatable-views-with-limit
userstat
version
wait-timeout

Authentication Plugins - Options and System Variables


Authentication Plugin - ed25519
The options related to the ed25519 authentication plugin can be found here.

Authentication Plugin - gssapi


The system variables related to the gssapi authentication plugin can be found here.
The options related to the gssapi authentication plugin can be found here.

Authentication Plugin - named_pipe


The options related to the named_pipe authentication plugin can be found here.

1593/3812
Authentication Plugin - pam
The system variables related to the pam authentication plugin can be found here.
The options related to the pam authentication plugin can be found here.

Authentication Plugin - unix_socket


The options related to the unix_socket authentication plugin can be found here.

Encryption Plugins - Options and System Variables


Encryption Plugin - aws_key_management
The system variables related to the aws_key_management encryption plugin can be found here.
The options elated to the aws_key_management encryption plugin can be found here.

Encryption Plugin - file_key_management


The system variables related to the file_key_management encryption plugin can be found here.
The options related to the file_key_management encryption plugin can be found here.

Password Validation Plugins - Options and System


Variables
Password Validation Plugin - simple_password_check
The system variables related to the simple_password_check password validation plugin can be found here.
The options related to the simple_password_check password validation plugin can be found here.

Password Validation Plugin - cracklib_password_check


The system variables related to the cracklib_password_check password validation plugin can be found here.
The options related to the cracklib_password_check password validation plugin can be found here.

Audit Plugins - Options and System Variables


Audit Plugin - server_audit
Options and system variables related to the server_audit audit plugin can be found here.

Audit Plugin - SQL_ERROR_LOG


The system variables related to the SQL_ERROR_LOG audit plugin can be found here.
The options related to the SQL_ERROR_LOG audit plugin can be found here.

Audit Plugin - QUERY_RESPONSE_TIME_AUDIT


The options related to the QUERY_RESPONSE_TIME_AUDIT audit plugin can be found here.

Daemon Plugins - Options and System Variables


Daemon Plugin - handlersocket
The options for the HandlerSocket plugin are all described on the HandlerSocket Configuration Option page.

Information Schema Plugins - Options and System


Variables
1594/3812
Information Schema Plugin - DISKS
The options related to the DISKS information schema plugin can be found here.

Information Schema Plugin - feedback


The system variables related to the feedback plugin can be found here.
The options related to the feedback plugin can be found here.

Information Schema Plugin - LOCALES


The options related to the LOCALES information schema plugin can be found here.

Information Schema Plugin - METADATA_LOCK_INFO


The options related to the METADATA_LOCK_INFO information schema plugin can be found here.

Information Schema Plugin - QUERY_CACHE_INFO


The options related to the QUERY_CACHE_INFO information schema plugin can be found here.

Information Schema Plugin - QUERY_RESPONSE_TIME


The system variables related to the QUERY_RESPONSE_TIME information schema plugin can be found here.
The options related to the QUERY_RESPONSE_TIME information schema plugin can be found here.

Information Schema Plugin - user_variables


The options related to the user_variables information schema plugin can be found here.

Information Schema Plugin - WSREP_MEMBERSHIP


The options related to the WSREP_MEMBERSHIP information schema plugin can be found here.

Information Schema Plugin - WSREP_STATUS


The options related to the WSREP_STATUS information schema plugin can be found here.

Replication Plugins - Options and System Variables


Replication Plugin - rpl_semi_sync_master
The system variables related to the rpl_semi_sync_master replication plugin can be found here.
The options related to the rpl_semi_sync_master replication plugin can be found here.

Replication Plugin - rpl_semi_sync_slave


The system variables related to the rpl_semi_sync_slave replication plugin can be found here.
The options related to the rpl_semi_sync_slave replication plugin can be found here.

Default Values
You can verify the default values for an option by doing:

mysqld --no-defaults --help --verbose

2.1.6.5 What to Do if MariaDB Doesn't Start

1595/3812
Contents
1. The Error Log and the Data Directory
2. Option Files
1. Invalid Option or Option Value
3. Can't Open Privilege Tables
4. Can't Create Test File
5. InnoDB
1. Cannot Allocate Memory for the
InnoDB Buffer Pool
2. InnoDB Table Corruption
6. MyISAM
7. systemd
8. SELinux

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 - or ask a question at the Starting and Stopping MariaDB page.

The Error Log and the Data Directory


The reason for the failure will almost certainly be written in the error log 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 or log_error system variables in an option file. See 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. 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 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 for more information on checking configuration
options.

Invalid Option or Option Value


Another potential reason for a startup failure is that an option file contains an invalid option or an invalid option value. In
those cases, the error log 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 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 to stop working after an upgrade.

1596/3812
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.
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 are either missing or are in the wrong location. The above error is
quite common after an upgrade if the option files set the basedir or datadir to a non-standard location, but the new
server is using the default location. Therefore, make sure that the basedir and 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 for information on the default locations.
If the system tables really do not exist, then you may need to create them with mysql_install_db . See Installing
System Tables (mysql_install_db) 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 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 upwards have "x" (execute) permissions for all
( user , group , and other ).
Once this is checked look at the systemd and selinux documentation below, or apparmor .

InnoDB
InnoDB 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;
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
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 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:
1597/3812
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
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 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, we can force MyISAM to repair damaged tables.

systemd
If you are using systemd , 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 . See Systemd: Configuring Access to Home Directories for information on how to work
around this.
The default systemd unit file also sets ProtectSystem=full , 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 option is 90 seconds. See
Systemd: 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
for more information.
See systemd documentation for further information on systemd configuration.

SELinux
Security-Enhanced Linux (SELinux) is a Linux kernel module that provides a framework for configuring mandatory
access control (MAC) 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 when SELinux blocks resource accesses even in permissive
mode.
See SELinux for more information.

2.1.6.6 Running MariaDB from the Build


Directory
You can run mysqld 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 or newer,
1598/3812
mariadbd.exe --console

else
mysqld.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 mysqld 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
1599/3812
With the above file in place, go to your MariaDB source directory and execute:

./scripts/mysql_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) in the debugger:

cd sql
ddd ./mariadbd &

Or start mysqld 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/mysql

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

2.1.6.7 mysql.server
Contents
1. Using mysql.server
1. Options
2. Option Files
1. Option Groups
3. Customizing mysql.server
2. Installed Locations
1. Installed SysVinit Locations
1. Manually Installing with SysVinit

The mysql.server startup script is in MariaDB distributions on Linux and Unix. It is a wrapper that works as a standard
sysVinit script. However, it can be used independently of sysVinit as a regular sh script. The script starts the mysqld
server process by first changing its current working directory to the MariaDB install directory and then starting
mysqld_safe . The script requires the standard sysVinit 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 by first changing to the MariaDB install directory and then calling 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>

1600/3812
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- The path name of the file in which the server should write its process ID. If not provided, the
file=file_name default, host_name.pid is used.
--service- How long in seconds to wait for confirmation of server startup. If the server does not start within
startup- this time, mysql.server exits with an error. The default value is 900. A value of 0 means not to
timeout=file_name wait at all for startup. Negative values mean to wait forever (no timeout).
--use-
Use mysqld_safe to start the server. This is the default.
mysqld_safe

--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.
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 from option files:

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 from option files:

Group Description
[mysqld] Options read by mysqld , which includes both MariaDB Server and MySQL Server.
[server] Options read by MariaDB Server.
[mysqld- Options read by a specific version of mysqld , which includes both MariaDB Server and MySQL Server.
X.Y] For example, [mysqld-5.5] .
[mariadb] Options read by MariaDB Server.
[mariadb-
Options read by a specific version of MariaDB Server.
X.Y]

[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] 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.
1601/3812
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, mysql.server may also be installed in other locations and with other names.
If you installed MariaDB on Linux using RPMs, 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 or from a binary tarball that does not install mysql.server automatically, and if you
are on a system that uses sysVinit, then you can manually install mysql.server with sysVinit. 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 for information on configuration options for mysqld .

2.1.6.8 mysqld_safe
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadbd-safe is a symlink to mysqld_safe .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadbd-safe is the name of the server, with mysqld_safe a symlink .

1602/3812
Contents
1. Using mysqld_safe
1. Options
2. Option Files
1. Option Groups
3. Configuring the Open Files Limit
4. Configuring the Core File Size
5. Configuring MariaDB to Write the
Error Log to Syslog
2. Specifying mysqld
3. Specifying datadir
4. Logging
5. Editing mysqld_safe
6. NetWare
7. See Also

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 .
Additionally, the mysql.server init script used by sysVinit 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 . 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.
(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
--autoclose 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- The size of the core file that mysqld should be able to create. The option value is passed to
size=size ulimit -c.
--crash-
Script to call in the event of mysqld crashing.
script=file

--datadir=path The path to the data directory.


The name of an option file to be read in addition to the usual option files. This must be the first
--defaults-extra-
option on the command line if it is used. If the file does not exist or is otherwise inaccessible, the
file=path
server will exit with an error.
--defaults- The name of an option file to be read instead of the usual option files. This must be the first
file=file_name option on the command line if it is used.

--defaults-group-
In addition to the default option groups, also read option groups with this suffix.
suffix=#

--flush-caches Flush and purge buffers/caches before starting the server.


If mysqld_safe cannot find the server, use this option to indicate the path name to the directory
--ledir=path
where the server is located.
1603/3812
--log-
Write the error log to the given file.
error=file_name

--malloc-lib=lib Preload shared library lib if available. See debugging MariaDB for an example.
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
mysqld=prog_nam 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.
This option is similar to the --mysqld option, but you specify only the suffix for the server
--mysqld- program name. The basename is assumed to be mysqld. For example, if you use --mysqld-
version=suffix 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-auto-
Exit after starting mysqld.
restart

--no-defaults Do not read any option files. This must be the first option on the command line if it is used.
--no-watch Exit after starting mysqld.
--numa-
Run mysqld with its memory interleaved on all NUMA nodes.
interleave

--open-files- The number of files that mysqld should be able to open. The option value is passed to ulimit -n.
limit=count Note that you need to start mysqld_safe as root for this to work properly.
--pid-
The path name of the process ID file.
file=file_name

--plugin-
Directory for client-side plugins.
dir=dir_name ,

The port number that the server should use when listening for TCP/IP connections. The port
--port=port_num
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-
Do not try to kill stray mysqld processes at startup. This option works only on Linux.
mysqld

--socket=path The Unix socket file that the server should use when listening for local connections.
--syslog causes error messages to be sent to syslog on systems that support the logger
--syslog , --
program. --skip-syslog suppresses the use of syslog; messages are written to an error log
skip-syslog
file.
For logging to syslog, messages from mysqld_safe and mysqld are written with a tag of
--syslog-tag=tag 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 .
-- Set the TZ time zone environment variable to the given option value. Consult your operating
timezone=timezone system documentation for legal time zone specification formats. Also see Time Zones.
Run the mysqld server as the user having the name user_name or the numeric user ID user_id.
--user={user_name
(“User” in this context refers to a system login account, not a MariaDB user listed in the grant
or user_id}
tables.)

Option Files
In addition to reading options from the command-line, mysqld_safe can also read options from option files. 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.

1604/3812
Option Groups
mysqld_safe reads options from the following option groups from option files:

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.

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 from option files:

Group Description
[mysqld] Options read by mysqld , which includes both MariaDB Server and MySQL Server.
[server] Options read by MariaDB Server.
[mysqld- Options read by a specific version of mysqld , which includes both MariaDB Server and MySQL Server.
X.Y] For example, [mysqld-5.5] .
[mariadb] Options read by MariaDB Server.
[mariadb-
Options read by a specific version of MariaDB Server.
X.Y]

[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] 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 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 about that.
When mysqld_safe starts mysqld , it also uses this option to set the value of the open_files_limit system variable
for mysqld .

Configuring the Core File Size


When using mysqld_safe , if you would like to enable core dumps , 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 , 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
1605/3812
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 .
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 .

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
1606/3812
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 . This can be used to solve issues like this warning from
mysqld: Changed limits: max_open_files: 1024 (requested 5000)"
mysqld Options
systemd

2.1.6.9 mysqladmin
2.1.6.10 Switching Between Different Installed
MariaDB Versions
Contents
1. Stopping a pre-installed MySQL/MariaDB
from interfering with your tests
2. How to create a binary distribution (tar
file)
3. Creating a directory structure for the
different installations
4. Setting up the data directory
1. Setting up a common data directory
2. Setting up different data directories
5. Running a MariaDB server
6. Setting up a .my.cnf file for running
multiple MariaDB main 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 downloads.askmonty.org .

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 mysqladmin 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 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
Compile the source
Create the binary tar ball.
You will then be left with a tar file named something like: mariadb-5.3.2-MariaDB-beta-linux-x86_64.tar.gz

Creating a directory structure for the different


1607/3812
installations
Install the binary tar files under /usr/local/ with the following directory names (one for each MariaDB version you
want to use):
mariadb-5.1
mariadb-5.2
mariadb-5.3
mariadb-5.5
mariadb-10.0
The above assumes you are just testing major versions of MariaDB. If you are testing specific versions, use directory
names like mariadb-5.3.2
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-5.3.2-MariaDB-beta-linux-x86_64.tar.gz
mv -vi mariadb-5.3.2-MariaDB-beta-linux-x86_64 mariadb-5.3
ln -vs mariadb-5.3 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 mysql_install_db

cd /usr/local/
mkdir mariadb-data
cd mariadb
./bin/mysql_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/mysql_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/mysql_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-5.# mariadb
cd mariadb
./bin/mysqld_safe --no-defaults --datadir=/usr/local/mariadb-data &

1608/3812
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-5.2]
# Options for MariaDB 5.2
[mariadb-5.3]
# Options for MariaDB 5.3

If you create an ~/.my.cnf file, you should start mysqld with --defaults-file=~/.my.cnf instead of --no-defaults
in the examples above.

2.1.6.11 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 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
for more information.

Configuring File Permissions with systemd


If your server is started by systemd , then there is a specific way to configure the umask. See Systemd: Configuring the
umask for more information.

2.1.6.12 mysqld_multi
MariaDB starting with 10.4.6

1609/3812
From MariaDB 10.4.6, mariadbd-multi is a symlink to mysqld_multi .

MariaDB starting with 10.5.2


From MariaDB 10.5.2, 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.

Contents
1. Using mysqld_multi
1. Options
2. Option Files
1. Option Groups
3. Authentication and Privileges
2. User Account
3. Example

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 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 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 mysqladmin binary to be used to stop servers. Can be given within groups [mysqld#] .

1610/3812
The mysqld binary to be used. Note that you can also specify mysqld_safe 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
--mysqld=prog_name
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.
The password of the MariaDB account to use when invoking mysqladmin. Note that the
--password=password
password value is not optional for this option, unlike for other MariaDB programs.
--silent Silent mode; disable warnings.
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
--tcp-ip
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 mysqladmin.
--verbose Be more verbose.
--version Display version information and exit.
--wsrep-new-cluster Bootstrap a cluster. Added in MariaDB 10.1.15 .

Option Files
In addition to reading options from the command-line, mysqld_multi can also read options from option files. 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 from option files:

Group Description
[mysqld_multi] Options read by mysqld_multi , which includes both MariaDB Server and MySQL Server.

mysqld_multi also searches option files for 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
Options read by a mysqld instance managed by mysqld_multi , which includes both MariaDB Server
[mysqldN]
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 can also be used for common options that are read by all instances:

1611/3812
Group Description
[mysqld] Options read by mysqld , which includes both MariaDB Server and MySQL Server.
[server] Options read by MariaDB Server.
[mysqld- Options read by a specific version of mysqld , which includes both MariaDB Server and MySQL Server.
X.Y] For example, [mysqld-5.5] .
[mariadb] Options read by MariaDB Server.
[mariadb-
Options read by a specific version of MariaDB Server.
X.Y]

[client- Options read by all MariaDB client programs and the MariaDB Server. This is useful for options like
server] 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 mysqladmin 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.

1612/3812
# 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

2.1.6.13 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
A launchd Tutorial
1613/3812
2.1.6.14 systemd
systemd is a sysVinit 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 and DEBs. It is also included in certain binary
tarballs.
The service name is mariadb.service .
When MariaDB is started with the systemd unit file, it directly starts the mysqld process as the mysql user. Unlike
with sysVinit , the mysqld process is not started with mysqld_safe . As a consequence, options will not be read from
the [mysqld_safe] option group from option files.

1614/3812
Contents
1. Contents of the MariaDB Service's Unit
File
2. Interacting with the MariaDB Server
Process
1. Starting the MariaDB Server Process
on Boot
2. Starting the MariaDB Server Process
3. Stopping the MariaDB Server Process
4. Restarting the MariaDB Server
Process
5. Checking the Status of the MariaDB
Server Process
6. Interacting with Multiple MariaDB
Server Processes
1. Default configuration of Multiple
Instances in 10.4 and Later
2. Custom configuration of Multiple
Instances in 10.4 and Later
3. Configuring Multiple Instances in
10.3 and Earlier
3. Systemd and Galera Cluster
1. Bootstrapping a New Cluster
2. Recovering a Node's Cluster Position
3. SSTs and Systemd
4. Configuring the Systemd Service
1. Useful Systemd Options
2. Configuring the Systemd Service
Timeout
3. Configuring the Open Files Limit
4. Configuring the Core File Size
5. Configuring MariaDB to Write the
Error Log to Syslog
6. Configuring LimitMEMLOCK
7. Configuring Access to Home
Directories
8. Configuring the umask
9. Configuring the data directory
5. Systemd Socket Activation
1. Using Systemd Socket Activation
2. When to Use Systemd Socket
Activation
3. Downsides to Using Systemd Socket
Activiation
4. Configuring Systemd Socket
Activation
5. Extra Port
6. Multi-instance socket activation
6. Systemd Socket Activation for Hosting
Service Providers
1. End User Benefits
2. Hosting Service Provider Benefits
3. Downsides to the Hosting Service
Provider
4. Example on configuration Items for a
per user, systemd socket activitated
multi-instance service
1. A MariaDB Template File
2. Custom Configuration for the
Multiinstance Service
3. Custom Configuration for the Multi-
instance Socket
7. Systemd Journal
8. Converting mysqld_safe Options to
Systemd Options
9. Known Issues

Contents of the MariaDB Service's Unit File


The contents of the mariadb.service file can be examined with systemctl show mariadb.service .

1615/3812
Interacting with the MariaDB Server Process
The service can be interacted with by using the systemctl 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 mysqld has failed
to startup, which causes systemd to kill the mysqld process. To work around this, you can reconfigure the MariaDB
systemd unit to have an infinite timeout.
Note that systemd 236 added the EXTEND_TIMEOUT_USEC environment variable that allows services to extend the
startup timeout during long-running processes. Starting with MariaDB 10.1.33 , MariaDB 10.2.15 , and MariaDB
10.3.6, 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 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 with the name [email protected] is installed in INSTALL_SYSTEMD_UNITDIR on some
systems. See Locating the MariaDB Service's 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 [email protected]

MariaDB's build system cannot include the [email protected] template unit file in RPM packages on platforms
that have cmake versions older than 3.3.0, because these cmake versions have a bug 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 version starting with MariaDB 10.1.39 , MariaDB
10.2.23 , and MariaDB 10.3.14. 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


1616/3812
systemd will also look for an option file for a specific MariaDB instance based on the instance name.

It will use the .%I as the custom option group suffix that is appended to any server option group, 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 at the
path /etc/mynode1.cnf .
When using multiple instances, each instance will of course also need their own datadir , socket and , port (unless
skip_networking is specified). As mysql_install_db#option-groups reads the same sections as the server,
and ExecStartPre= run mysql_install_db 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 [email protected] :

[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 mysqld and mysql_install_db will recognise.
A hosting environment where each user has their own instance may look like (with sudo systemctl edit
[email protected] ):

[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 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 .
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 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 . See mysql_install_db for
information on how to initialize the datadir for additional MariaDB instances.

Systemd and Galera Cluster


Bootstrapping a New Cluster
When using Galera Cluster 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 for more information.

Recovering a Node's Cluster Position


When using Galera Cluster 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 for more information.

1617/3812
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 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. See Introduction to State Snapshot Transfers (SSTs): SSTs and Systemd for
more information.
Note that systemd 236 added the EXTEND_TIMEOUT_USEC environment variable that allows services to extend the
startup timeout during long-running processes. Starting with MariaDB 10.1.35 , MariaDB 10.2.17 , and MariaDB
10.3.8, 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 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/mysqld $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 option, then that is also
listed. Use systemctl edit mariadb.service to create the systemd option under a [Service] section header.

mysqld_safe
systemd option Comments
option
no option ProtectHome=false If any MariaDB files are in /home/
If any MariaDB storage references raw
no option PrivateDevices=false
block devices
If any MariaDB write any files to
no option ProtectSystem=
anywhere under /boot, /usr or /etc
Service startup timeout. See Configuring
no option TimeoutStartSec={time}
the Systemd Service Timeout.
no option
e.g. -600 to lower priority of OOM killer
(see MDEV- OOMScoreAdjust={priority}
for mysqld
9264 )
open-files- Limit on number of open files. See
LimitNOFILE={limit}
limit Configuring the Open Files Limit.
Limit on core file size. Useful when
core-file-
LimitCORE={size} enabling core dumps . See Configuring
size
the Core File Size.
1618/3812
Limit on how much can be locked in
LimitMEMLOCK={size} or infinity memory. Useful when large-pages or
memlock is used
nice Nice={nice value}

See Configuring MariaDB to Write the


syslog StandardOutput=syslog
Error Log to Syslog.
StandardError=syslog

SyslogFacility=daemon

SyslogLevel=err

syslog-tag SyslogIdentifier

flush-
ExecStartPre=/usr/bin/sync
caches

ExecStartPre=/usr/sbin/sysctl -q -w vm.drop_caches=3
malloc-lib Environment=LD_PRELOAD=/path/to/library

numa-
NUMAPolicy=interleave from systemd v243 onwards
interleave

prepending
or: ExecStart=/usr/bin/numactl --interleave=all
ExecStart=/usr/bin/numactl --
/usr/sbin/mysqld $MYSQLD_OPTS $_WSREP_NEW_CLUSTER
interleave=all to existing ExecStart
$_WSREP_START_POSITION
setting
no-auto-
Restart={exit-status}
restart

Note: the systemd 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 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 mysqld has failed to startup, which
causes systemd to kill the mysqld process. To work around this, it can be changed by configuring the
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 .

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 , 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 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.

1619/3812
Configuring the Open Files Limit
When using systemd , rather than setting the open files limit by setting the open-files-limit option for mysqld_safe
or the open_files_limit system variable, the limit can be changed by configuring the LimitNOFILE 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
and restarting the server.
The value of the fs.nr_open parameter can be changed temporarily by executing the 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 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 , rather than setting the core file size by setting the
core-file-size option for mysqld_safe , the limit can be changed by configuring the LimitCORE 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 to the syslog , then that can easily be done by doing
the following:
Ensure that log_error system variable is not set.
Set StandardOutput=syslog .
Set StandardError=syslog .
Set SyslogFacility=daemon .
Set SysLogLevel=err .
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 with a different tag
for each instance.

1620/3812
Configuring LimitMEMLOCK
If using --memlock or the iouring in InnoDB in MariaDB 10.6 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 , the --memlock option could not be used with the MariaDB systemd service.

Configuring Access to Home Directories


MariaDB's systemd unit file restricts access to /home , /root , and /run/user by default. This restriction can be
overridden by setting the 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 mysqld 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
for more information.

Keep in mind that configuring the umask this way will only affect the permissions of files created by the mysqld
process that is managed by systemd . The permissions of files created by components that are not managed by
systemd , such as mysql_install_db , will not be affected.

See Specifying Permissions for Schema (Data) Directories and Tables 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:

1621/3812
sudo systemctl edit mariadb.service

[Service]
ReadWritePaths=/usr/local/mysql/data

Systemd Socket Activation


MariaDB starting with 10.6.0
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 , port, and 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 , however ListenStream and 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.

1622/3812
Extra Port
A systemd socket can be configured as an extra_port, by using the FileDescriptorName=extra in the .socket
file.

The mariadb-extra.socket is already packaged and ready for use.

Multi-instance socket activation


[email protected] is MariaDB's packaged multi-instance defination. It creates multiple UNIX sockets based on the
socket file started.
Starting [email protected] will use the [email protected] defination with %I within the defination replaced with
"bob".
When something connects to a socket defined there, the [email protected] 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 ).
Planned enhancements in InnoDB provide:
an on-demand consumption of memory (MDEV-25340 .
a proactive reduction in memory (MDEV-25341 ).
a memory resource pressure reduction in memory use (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 .
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


1623/3812
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 [email protected]


# systemctl start [email protected]

To enable this on reboot (the same way as a systemd service):

# systemctl enable [email protected]


# systemctl enable [email protected]

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 Multiinstance 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 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 .
If the MariaDB version was upgrade, the upgrade changes are made automaticly
LimitData places a hard upper limit so the user doesn't exceed a portion of the server resources

# cat /etc/systemd/system/[email protected]/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.

1624/3812
# cat /etc/systemd/system/[email protected]/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/[email protected]/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 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 options to systemd options. It reads any explicit settings in the [mysqld_safe] option group from
option files, 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 may be missed by the conversion script and require explicit configuration.
See Configuring the Open Files Limit.

Known Issues

2.1.6.15 sysVinit

1625/3812
Contents
1. Interacting with the MariaDB Server
Process
1. Starting the MariaDB Server Process
on Boot
2. Starting the MariaDB Server Process
3. Stopping the MariaDB Server Process
4. Restarting the MariaDB Server
Process
5. Checking the Status of the MariaDB
Server Process
2. Manually Installing mysql.server with
SysVinit
3. SysVinit and Galera Cluster
1. Bootstrapping a New Cluster

sysVinit is one of the most common service managers. On systems that use sysVinit , the mysql.server 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 command.

Starting the MariaDB Server Process on Boot


On RHEL/CentOS and other similar distributions, the 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 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 or from a binary tarball that does not install mysql.server automatically, and if you
are on a system that uses sysVinit, then you can manually install mysql.server with sysVinit. See mysql.server:
Manually Installing with SysVinit for more information.

SysVinit and Galera Cluster


Bootstrapping a New Cluster
When using Galera Cluster with sysVinit, the first node in a cluster has to be started with service mysql bootstrap .
1626/3812
See Getting Started with MariaDB Galera Cluster: Bootstrapping a New Cluster for more information.

2.1.6.16 Mariadb-admin
2.1.6.17 mariadbd
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadbd is a symlink to mysqld, the MariaDB server.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadbd is the name of the server, with mysqld a symlink .

See mysqld for details.

2.1.6.18 mariadbd-multi
MariaDB starting with 10.4.6
From MariaDB 10.4.6, 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


From MariaDB 10.5.2, mariadbd-multi is the name of the server, with mysqld_multi a symlink .

See mysqld_multi for details.

2.1.6.19 mariadbd-safe
MariaDB starting with 10.4.6
From MariaDB 10.4.6, mariadbd-safe is a symlink to mysqld_safe , the tool for starting mysqld on Linux and Unix
distributions that do not support systemd.

MariaDB starting with 10.5.2


From MariaDB 10.5.2, mariadbd-safe is the name of the binary, with mysqld_safe a symlink .

See mysqld_safe for details.

2.1.7 MariaDB Performance & Advanced


Configurations
Articles of how to setup your MariaDB optimally on different systems
Fusion-io
This category contains information about Fusion-io support in MariaDB

Atomic Write Support


1 Enabling atomic writes to speed up InnoDB on selected SSD cards.

Configuring Linux for MariaDB


Linux kernel settings IO scheduler For optimal IO performance running a da...

Configuring MariaDB for Optimal Performance


1 How to get optimal performance.

Configuring Swappiness
2 Setting Linux swappiness.

1627/3812
There are 5 related questions .

2.1.7.1 Fusion-io
This category contains information about Fusion-io support in MariaDB
Fusion-io Introduction
Fusion-io PCIe SSD cards to speed up MariaDB.

Atomic Write Support


1 Enabling atomic writes to speed up InnoDB on selected SSD cards.

MariaDB 10.0.15 Fusion-io Release Notes


Status: | Release Date: 12 Dec 2014

MariaDB 10.0.15 Fusion-io Changelog


Status: | Release Date: 12 Dec 2014

InnoDB Page Flushing


Configuring when and how InnoDB flushes dirty pages to disk.

2.1.7.1.1 Fusion-io Introduction


Contents
1. Use Cases
2. Atomic Writes
3. Future Suggested Development
4. Settings For Best Performance
5. Example Configuration
6. Card Models
7. Additional Software
8. See Also

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.
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 running on Fusion-io SLC cards on several hosts.

Atomic Writes
1628/3812
Starting with MariaDB 5.5.31 , 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 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 . This has been fixed in kernel versions above 3.5 or RHEL6 kernels
kernel-2.6.32-358 or later (because of bug 807503 being fixed) .
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

Card Models
1629/3812
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

2.1.7.1.2 Atomic Write Support


Contents
1. Partial Write Operations
2. innodb_doublewrite - an Imperfect
Solution
3. Atomic Write - a Faster Alternative to
innodb_doublewrite
4. Enabling Atomic Writes from MariaDB
10.2
5. Enabling Atomic Writes in MariaDB 5.5 to
MariaDB 10.1
1. About innodb_use_atomic_writes (in
MariaDB 5.5 to MariaDB 10.1)
6. Devices that Support Atomic Writes with
MariaDB

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
(also innodb_checksum can be used to detect a partial write).
Doublewrites, controlled by the 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.

1630/3812
Enabling Atomic Writes from MariaDB 10.2
When starting, MariaDB 10.2 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 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 to OFF in your
my.cnf file. It's ON by default.

Enabling Atomic Writes in MariaDB 5.5 to MariaDB 10.1


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 in these versions of
MariaDB.

About innodb_use_atomic_writes (in MariaDB 5.5 to MariaDB 10.1)


The following happens when atomic writes are enabled
if innodb_flush_method is neither O_DIRECT , ALL_O_DIRECT , or O_DIRECT_NO_FSYNC , it is switched to O_DIRECT
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 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:

Devices that Support Atomic Writes with MariaDB


MariaDB currently supports atomic writes on the following devices:
Fusion-io devices with the NVMFS file system . MariaDB 5.5 and above.
Shannon SSD . MariaDB 10.2 and above.

2.1.7.1.3 InnoDB Page Flushing


2.1.7.3 Configuring Linux for MariaDB

1631/3812
Contents
1. Linux kernel settings
1. IO scheduler
2. Resource Limits
1. Configuring the Open Files Limit
2. Configuring the Core File Size
3. Swappiness

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 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 to start mysqld , then see the instructions at mysqld_safe: Configuring the Open Files
Limit.
If you are using systemd to start mysqld , then see the instructions at systemd: 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 :

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 , 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.
1632/3812
If you are using mysqld_safe to start mysqld , then see the instructions at mysqld_safe: Configuring the Core File Size.
If you are using systemd to start mysqld , then see the instructions at systemd: 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 :

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.

2.1.7.4 Configuring MariaDB for Optimal


Performance
Contents
1. my.cnf Files
2. InnoDB Storage Engine
3. Aria Storage Engine
4. MyISAM
5. Lots of Connections
1. A Lot of Fast Connections + Small Set
of Queries + Disconnects
2. Connecting From a Lot of Different
Machines
6. See Also
7. External Links

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 Files
MariaDB is normally configured by editing the my.cnf file.
The following my.cnf example files were included with MariaDB until MariaDB 10.3.0. 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 Storage Engine


InnoDB is normally the default storage engine with MariaDB.
You should set 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_flush_method
innodb_thread_sleep_delay
1633/3812
Some other important InnoDB variables:
innodb_adaptive_max_sleep_delay
innodb_buffer_pool_instances
innodb_max_dirty_pages_pct_lwm
innodb_read_ahead_threshold
innodb_thread_concurrency

Aria 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 to a reasonably large value so that temporary overflow data is not
flushed to disk. The default is 128M.

MyISAM
If you don't use MyISAM tables explicitly (true for most MariaDB 10.4+ users), you can set 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 and if you are running
MariaDB 10.1 or below thread_cache_size.
If you have a lot (> 128) of simultaneous running fast queries, you should consider setting 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 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
Full List of MariaDB Options, System and Status Variables
Server system variables
mysqld options
Performance schema helps you understand what is taking time and resources.
Slow query log is used to find queries that are running slow.
OPTIMIZE TABLE 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

2.1.7.5 Configuring Swappiness


Contents
1. Why to Avoid Swapping
2. Setting Swappiness on Linux
3. Disabling Swap Altogether

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
1634/3812
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 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.

2.1.8 Troubleshooting Installation Issues


Articles relating to installation issues users might run into.
Troubleshooting Connection Issues
9 Common problems when trying to connect to MariaDB.

Installation issues on Windows


5 Issues people have encountered when installing MariaDB on Windows

Troubleshooting MariaDB Installs on Red Hat/CentOS


Issues people have encountered when installing MariaDB on Red Hat / CentOS

Installation issues on Debian and Ubuntu


Solutions to different installation issues on Debian and Ubuntu

What to Do if MariaDB Doesn't Start


7 Troubleshooting MariaDB when it fails to start.

Installing on an Old Linux Version


Typical errors from using an incompatible MariaDB binary on a linux system

1635/3812
Error: symbol mysql_get_server_name, version libmysqlclient_16 not defined
1 Error from using MariaDB's mysql command-line client with MySQL's libmysqlclient.so

Installation Issues with PHP5


17 PHP5 may give an error if used with the old connect method

There are 13 related questions .

2.1.8.1 Troubleshooting Connection Issues


2.1.8.2 Installation issues on Windows
Contents
1. MariaDB 10.4.13
2. Unsupported Versions of Windows
3. MariaDB 5.2.5 and earlier
1. On Windows Vista/7 , changes to
database or my.ini are not persistent,
when mysqld.exe is run from the
command line.
4. Systems with User Account Control

MariaDB 10.4.13
MariaDB 10.4.13 may not start on Windows. See 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 to
find the final supported versions.

MariaDB 5.2.5 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 on how to create a MariaDB service.
Run mysqld.exe from the elevated command prompt .
Change the ACL of the data directory and add full control for the current user.
The Windows installer for MariaDB 5.2.6 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.

2.1.8.3 Troubleshooting MariaDB Installs on


Red Hat/CentOS
1636/3812
2.1.8.4 Installation issues on Debian and
Ubuntu
Solutions to different installation issues on Debian and Ubuntu
Differences in MariaDB in Debian (and Ubuntu)
MariaDB when installed from the Debian repos has a number of differences with standard MariaDB.

Moving from MySQL to MariaDB in Debian 9


1 MariaDB 10.1 is the default mysql server in Debian 9 "Stretch"

Creating a Debian Repository


Instructions for creating your own Debian repository

MariaDB 5.5.33 Debian and Ubuntu Installation Issues


1 Workarounds for some repository issues with the 5.5.33 release.

MariaDB Debian Live Images


Debian live iso images with pre-installed MariaDB (obsolete)

apt-upgrade Fails, But the Database is Running


4 timeout causing apt to fail while the database is running.

There are 9 related questions .

2.1.8.4.1 Differences in MariaDB in Debian


(and Ubuntu)
Contents
1. Option File Locations
2. System Variables
3. Options
4. TLS
5. Authentication
6. See Also
7. More Information

The .deb packages provided by MariaDB Foundation's and MariaDB Corporation's repositories are not identical to the
official .deb 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. 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://anonscm.debian.org/cgit/pkg-mysql/mariadb-10.1.git/tree/debian
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 located at /etc/mysql/my.cnf is handled by the update-alternatives 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 are therefore actually
located in /etc/mysql/mariadb.d/ .

System Variables
Variable MariaDB in Debian Standard MariaDB Notes
character_set_server utf8mb4 latin1 Debian sets a default character set that can support emojis etc.
collation_server utf8mb4_general_ci latin1_swedish_ci

1637/3812
Options
MariaDB in Standard
Option Notes
Debian MariaDB
plugin- Before MariaDB 10.4.3, MariaDB did not enable the unix_socket authentication plugin
auth_socket.so -
load-add by default.This is default in Debian, allowing passwordless login.

TLS
MariaDB binaries from .deb packages provided by Debian's and Ubuntu's default repositories are linked with a
different TLS library than MariaDB binaries from .deb packages provided by MariaDB Foundation's and
MariaDB Corporation's repositories.
MariaDB Server binaries:
In MariaDB 10.4.6 and later, MariaDB Server is statically linked with the bundled wolfSSL libraries in
.deb packages provided by Debian's and Ubuntu's default repositories.
In MariaDB 10.4.5 and before, MariaDB Server is statically linked with the bundled yaSSL libraries in
.deb packages provided by Debian's and Ubuntu's default repositories.
In contrast, MariaDB Server is dynamically linked with the system's OpenSSL libraries in .deb packages
provided by MariaDB Foundation and MariaDB Corporation.
MariaDB client and utility binaries:
In MariaDB 10.4.6 and later, MariaDB's clients and utilities and MariaDB Connector/C are dynamically
linked with the system's GnuTLS libraries in .deb packages provided by Debian's and Ubuntu's default
repositories. libmysqlclient is still statically linked with the bundled wolfSSL libraries.
In MariaDB 10.2 and later, MariaDB's clients and utilities and MariaDB Connector/C are dynamically
linked with the system's GnuTLS libraries in .deb packages provided by Debian's and Ubuntu's default
repositories. libmysqlclient is still statically linked with the bundled yaSSL libraries.
In MariaDB 10.1 and earlier, MariaDB's clients and utilities and libmysqlclient are statically linked with the
bundled yaSSL libraries in .deb packages provided by Debian's and Ubuntu's default repositories.
In contrast, MariaDB's clients and utilities, libmysqlclient , and MariaDB Connector/C are dynamically
linked with the system's OpenSSL libraries in .deb packages provided by MariaDB Foundation's and
MariaDB Corporation's repositories.
See TLS and Cryptography Libraries Used by MariaDB for more information about which libraries are used on
which platforms.

Authentication
The unix_socket authentication plugin is installed by default in new installations that use the .deb 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 mysql_install_db will also be created to authenticate via the unix_socket
authentication plugin in these builds.

See Also
Moving from MySQL to MariaDB in Debian 9

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

2.1.8.4.2 Upgrading from MySQL to MariaDB


2.1.8.4.3 Creating a Debian Repository
2.1.8.4.4 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.
1638/3812
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 , 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 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 .
On systems that support systemd: The startup timeout can be increased by setting TimeoutStartSec systemd
option.

2.1.8.5 What to Do if MariaDB Doesn't Start


2.1.8.6 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 that matches your system.
or
Download the source and build it.

1639/3812
2.1.8.7 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.

2.1.9 Installing System Tables


(mysql_install_db)
2.1.10 mysql_install_db.exe
Contents
1. Functionality
2. Example
3. Removing Database Instances

The mysql_install_db.exe utility is the Windows equivalent of mysql_install_db.

1640/3812
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
-s , -- silent Print less information
-o , -- verbose-bootstrap Include mysqld bootstrap output
-l , -- large-pages Use large pages, since MariaDB 10.6.1
-c , -- config my.ini config template file, since MariaDB 10.6.1

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>

2.1.11 Configuring MariaDB with Option Files


2.1.12 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.
1641/3812
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.
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, overriding the $HOME/.mysql_history setting.
MYSQL_HOME Path to the directory containing the my.cnf file used by the server.
MYSQL_HOST Default host name used by the mysql command line client.
MYSQL_PS1 Command prompt for use by the mysql command line client.
Default password when connecting to mysqld. It is strongly recommended to use a more
MYSQL_PWD
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 to directories that hold executable programs (such as the mysql client, mysqladmin),
PATH
so that these can be run from any location.
TMPDIR Directory where temporary files are created.
TZ Local time zone.
Creation mode when creating files. See Specifying Permissions for Schema (Data)
UMASK
Directories and Tables.
Creation mode when creating directories. See Specifying Permissions for Schema (Data)
UMASK_DIR
Directories and Tables.
On Windows, up to MariaDB 5.5, the default user name when connecting to the mysqld
USER
server. API GetUserName() is used in later versions.

2.1.13 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 for complete details. 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 .

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 .
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.

1642/3812
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 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.

2.1.14 Migrating to MariaDB


Migrating to MariaDB from another DBMS.
Migrating to MariaDB from MySQL
Help with moving from MySQL to MariaDB, features and compatibility

Migrating to MariaDB from SQL Server


Guide to help you migrate from SQL Server to MariaDB.

Migrating to MariaDB from PostgreSQL


Information on migrating from PostgreSQL to MariaDB.

Migrating to MariaDB from Oracle


Help with migrating to MariaDB from Oracle

2.1.14.1 Migrating to MariaDB from MySQL


.
MariaDB versus MySQL - Features
8 MariaDB advantage in delivering enterprise-level high availability, scalability and security.

1643/3812
MariaDB versus MySQL - Compatibility
25 Compatibility and differences with MariaDB related to high availability, security and scalability.

Upgrading from MySQL to MariaDB


5 Upgrading from MySQL to MariaDB.

Incompatibilities and Feature Differences Between MariaDB 10.7 and MySQL 8.0
List of incompatibilities and feature differences between MariaDB 10.7 and MySQL 8.0.

Incompatibilities and Feature Differences Between MariaDB 10.6 and MySQL 8.0
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
1 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
List of incompatibilities and feature differences between MariaDB 10.4 and MySQL 8.0.

Incompatibilities and Feature Differences Between MariaDB 10.3 and MySQL 5.7
List of incompatibilities and feature differences between MariaDB 10.3 and MySQL 5.7.

Incompatibilities and Feature Differences Between MariaDB 10.2 and MySQL 5.7
List of incompatibilities and feature differences between MariaDB 10.2 and MySQL 5.7.

Function Differences Between MariaDB and MySQL


Functions available only in MariaDB.

System Variable Differences between MariaDB and MySQL


Comparison of variable differences between major versions of MariaDB and MySQL.

Upgrading from MySQL 5.7 to MariaDB 10.2


Following compatibility report was done on 10.2.4 and may get some fixing i...

Installing MariaDB Alongside MySQL


5 MariaDB was designed as a drop in place replacement for MySQL, but you can ...

Moving from MySQL to MariaDB in Debian 9


1 MariaDB 10.1 is the default mysql server in Debian 9 "Stretch"

Screencast for Upgrading MySQL to MariaDB


Screencast for upgrading MySQL 5.1.55 to MariaDB

Upgrading to MariaDB From MySQL 5.0 or Older


Upgrading to MariaDB from MySQL 5.0 (or older version)

There are 1 related questions .

2.1.14.1.1 MySQL vs MariaDB: Performance


Title: MariaDB versus MySQL - Features
See also MariaDB vs MySQL - Compatibility

Differences Per Releases


For differences between MySQL 8.0 and MariaDB 10.8 specifically, see Incompatibilities and Feature Differences
Between MariaDB 10.8 and MySQL 8.0
For differences between MySQL 8.0 and MariaDB 10.7 specifically, see Incompatibilities and Feature Differences
Between MariaDB 10.7 and MySQL 8.0
For differences between MySQL 8.0 and MariaDB 10.6 specifically, see Incompatibilities and Feature Differences
Between MariaDB 10.6 and MySQL 8.0
For differences between MySQL 8.0 and MariaDB 10.5 specifically, see Incompatibilities and Feature Differences
Between MariaDB 10.5 and MySQL 8.0
1644/3812
For differences between MySQL 8.0 and MariaDB 10.4 specifically, see Incompatibilities and Feature Differences
Between MariaDB 10.4 and MySQL 8.0
For differences between MySQL 5.7 and MariaDB 10.3 specifically, see Incompatibilities and Feature Differences
Between MariaDB 10.3 and MySQL 5.7
For differences between MySQL 5.7 and MariaDB 10.2 specifically, see Incompatibilities and Feature Differences
Between MariaDB 10.2 and MySQL 5.7
For a detailed breakdown of system variable differences, see:
System variable differences between MariaDB 10.9 and MySQL 8.0
System variable differences between MariaDB 10.8 and MySQL 8.0
System variable differences between MariaDB 10.7 and MySQL 8.0
System variable differences between MariaDB 10.6 and MySQL 8.0
System variable differences between MariaDB 10.5 and MySQL 8.0
System variable differences between MariaDB 10.4 and MySQL 8.0
System variable differences between MariaDB 10.3 and MySQL 8.0
System variable differences between MariaDB 10.3 and MySQL 5.7
System variable differences between MariaDB 10.2 and MySQL 5.7
System variable differences between MariaDB 10.1 and MySQL 5.7
System variable differences between MariaDB 10.1 and MySQL 5.6
System variable differences between MariaDB 10.0 and MySQL 5.6
System variable differences between MariaDB 5.5 and MySQL 5.5
For a detailed breakdown of function differences, see:
Function Differences Between MariaDB 10.9 and MySQL 8.0
Function Differences Between MariaDB 10.8 and MySQL 8.0
Function Differences Between MariaDB 10.7 and MySQL 8.0
Function Differences Between MariaDB 10.6 and MySQL 8.0
Function Differences Between MariaDB 10.5 and MySQL 8.0
Function Differences Between MariaDB 10.4 and MySQL 8.0
Function Differences Between MariaDB 10.3 and MySQL 8.0
Function Differences Between MariaDB 10.3 and MySQL 5.7
Function Differences Between MariaDB 10.2 and MySQL 5.7

More Storage Engines


In addition to the standard MyISAM, BLACKHOLE, CSV, MEMORY, ARCHIVE, and MERGE storage engines, the
following are also included with MariaDB Source and Binary packages:
ColumnStore , a column oriented storage engine optimized for Data warehousing.
MyRocks, a storage engine with great compression, in 10.2
Aria, MyISAM replacement with better caching.
FederatedX (drop-in replacement for Federated)
OQGRAPH (In MariaDB 5.2 and later. Disabled in MariaDB 5.5 only.)
SphinxSE (In MariaDB 5.2 and later)
CONNECT in MariaDB 10.0 and later.
SEQUENCE in MariaDB 10.0 and later.
Spider in MariaDB 10.0 and later.
TokuDB (In MariaDB 5.5 and later, removed in 10.6)
Cassandra (In MariaDB 10.0, removed in 10.6)

Speed Improvements
MariaDB now provides much faster privilege checks for setups with many user accounts or many database
The new FLUSH SSL command allows SSL certificates to be reloaded without restarting the server
Many optimizer enhancements in MariaDB 5.3. Subqueries are now finally usable. The complete list and a
comparison with MySQL is here . A benchmark can be found here .
Faster and safer replication: Group commit for the binary log. This makes many setups that use replication and
lots of updates more than 2x times faster .
Parallel replication — new in 10.0
Improvements for InnoDB asynchronous IO subsystem on Windows.
Indexes for the MEMORY(HEAP) engine are faster. According to a simple test, 24% faster on INSERT for integer
index and 60% faster for index on a CHAR(20) column. Fixed in MariaDB 5.5 and MySQL 5.7.
Segmented Key Cache for MyISAM. Can speed up MyISAM tables with up to 4x — new in 5.2
Adjustable hash size for MyISAM and Aria. This can greatly improve shutdown time (from hours to minutes) if
using a lot of MyISAM/Aria tables with delayed keys — new in 10.0.13
CHECKSUM TABLE is faster.
We improved the performance of character set conversions (and removed conversions when they were not really
needed). Overall speed improvement is 1-5 % (according to sql-bench) but can be higher for big result sets with
all characters between 0x00-0x7f.
Pool of Threads in MariaDB 5.1 and even better in MariaDB 5.5 . This allows MariaDB to run with 200,000+
connections and with a notable speed improvement when using many connections.
Several speed improvements when a client connects to MariaDB. Many of the improvements were done in
MariaDB 10.1 and MariaDB 10.2.
1645/3812
There are some improvements to the DBUG code to make its execution faster when debug is compiled in but not
used.
Our use of the Aria storage engine enables faster complex queries (queries which normally use disk-based
temporary tables). The Aria storage engine is used for internal temporary tables, which should give a speedup
when doing complex selects. Aria is usually faster for temporary tables when compared to MyISAM because Aria
caches row data in memory and normally doesn't have to write the temporary rows to disk.
The test suite has been extended and now runs much faster than before, even though it tests more things.

Extensions & New Features


We've added a lot of new features to MariaDB . If a patch or feature is useful, safe, and stable — we make every effort
to include it in MariaDB. The most notable features are:
Support introduced for System-versioned tables. Allows queries to access both current and historic data, aiding in
managing retention, analysis and point-in-time recovery. — new in 10.3
ALTER TABLE... DROP COLUMN can now run as Instant operations. Can also now change the ordering of
columns. — new in 10.4
Support introduced for password expiration, using the user password expiry — new in 10.4
In order to support the use of multiple authentication plugins for a single user, the mysql.user system table has
been retired in favor of the mysql.glob_priv system table. — new in 10.4
The unix_socket authentication plugin is now the default on Unix-like systems. This represents a major change to
authentication in MariaDB — new in 10.4
Support introduced for Optimizer Trace, which provides detailed information on how the Optimizer processes
queries. To enable Optimizer Trace, set the optimizer_trace system variable — new in 10.4
The MariaDB SQL/PL stored procedure dialect (enabled with sql_mode=ORACLE) now supports Oracle style
packages. Support for the following statements are available: CREATE PACKAGE, CREATE PACKAGE BODY,
DROP PACKAGE, DROP PACKAGE BODY, SHOW CREATE PACKAGE, SHOW CREATE PACKAGE BODY —
new in 10.3
Automatic collection of Engine Independent Table Statistics — new in 10.4
Support for the use of parentheses (brackets) for specifying precedence in the ordering of execution for SELECT
statements and Table Value Operations, (including the use of UNION, EXCEPT, INTERSECT operations) — new in
10.4
Support for anchored data types added to local stored procedure variables. — new in 10.3
Support added for Stored Aggregate functions — new in 10.3
Oracle compatible SUBSTR() function is available — new in 10.3
Oracle compatible SEQUENCE support is provided — new in 10.3
Support for anchored data types added to stored routine variables — new in 10.3
Support for anchored data types added to stored routine parameters — new in 10.3
Cursors with parameters are now supported — new in 10.3
INVISIBLE columns are now supported — new in 10.3
Instant ADD COLUMN is now available for InnoDB — new in 10.3
Window functions are supported — new in 10.2
Number of supported decimals in DECIMAL has increased from 30 to 38 — new in 10.2
Recursive Common Table Expressions — new in 10.2
New WITH statement. WITH is a common table expression that allows one to refer to a subquery expression
many times in a query — new in 10.2
CHECK CONSTRAINT — new in 10.2
DEFAULT expression, including DEFAULT for BLOB and TEXT — new in 10.2
Added catchall for list partitions — new in 10.2
Oracle-style EXECUTE IMMEDIATE statement — new in 10.2
Several new JSON functions — new in 10.2
Microsecond Precision in Processlist
Table Elimination
Virtual Columns — new in 5.2
Microseconds in MariaDB — new in 5.3
Extended User Statistics — new in 5.2
KILL all queries for a user — new in 5.3,
KILL QUERY ID - terminates the query by query_id, leaving the connection intact — new in 10.0.5,
Pluggable Authentication — new in 5.2
Storage-engine-specific CREATE TABLE — new in 5.2
Enhancements to INFORMATION SCHEMA.PLUGINS table — new in 5.2
Group commit for the binary log. This makes replication notably faster! — new in 5.3
Added -- rewrite-db mysqlbinlog option to change the used database — new in 5.2
Progress reporting for ALTER TABLE and LOAD DATA INFILE — new in 5.3
Faster joins and subqueries — new in 5.3
HandlerSocket and faster HANDLER calls — new in 5.3
Dynamic Columns support — new in 5.3
GIS Functionality — new in 5.3
Multi-source replication — new in 10.0
Global Transaction ID — new in 10.0
SHOW EXPLAIN gives the EXPLAIN plan for a query running in another thread. — new in 10.0
Roles — new in 10.0
1646/3812
PCRE Regular Expressions (including REGEXP_REPLACE() ) — new in 10.0
CREATE OR REPLACE
DELETE ... RETURNING — new in 10.0
MariaDB supports more collations than MySQL.
For a full list, please see features for each release

Better Testing
More tests in the test suite.
Bugs in tests fixed.
Test builds with different configure options to get better feature testing.
Remove invalid tests. (e.g. don't test feature ''X'' if that feature is not in the tested build)

Fewer Warnings and Fewer Bugs


Bugs are bad. Fix as many bugs as possible and try to not introduce new ones.
Compiler warnings are also bad. Eliminate as many compiler warnings as possible.

Truly Open Source


All code in MariaDB is released under GPL, LGPL or BSD.
MariaDB does not have closed source modules like the ones that can be found in MySQL Enterprise Edition. In
fact, all the closed source features in MySQL 5.5 Enterprise Edition are found in the MariaDB open source
version.
MariaDB client libraries (for C, for Java (JDBC), for Windows (ODBC)) are released under LGPL to allow linking
with closed source software. MySQL client libraries are released under GPL that does not allow linking with
closed source software.
MariaDB includes test cases for all fixed bugs. Oracle doesn't provide test cases for new bugs fixed in MySQL
5.5.
All bugs and development plans are public.
MariaDB is developed by the community in true open source spirit.

Related Links
Compatiblity between MariaDB and MySQL
Moving from MySQL
Troubleshooting Installation Issues

2.1.14.1.2 MariaDB versus MySQL:


Compatibility
See also MariaDB vs MySQL - Features

1647/3812
Contents
1. Replacement for MySQL
1. Drop-in Compatibility of Specific
MariaDB Versions
2. Replication Compatibility
1. MySQL 5.7
2. MySQL 8.0
3. Incompatibilities between Currently
Supported MariaDB Versions and
MySQL
1. Incompatibilities between MariaDB
10.8 and MySQL 8.0
2. Incompatibilities between MariaDB
10.7 and MySQL 8.0
3. Incompatibilities between MariaDB
10.6 and MySQL 8.0
4. Incompatibilities between MariaDB
10.5 and MySQL 8.0
5. Incompatibilities between MariaDB
10.4 and MySQL 8.0
6. Incompatibilities between MariaDB
10.3 and MySQL 5.7
7. Incompatibilities between MariaDB
10.2 and MySQL 5.7
4. Incompatibilities between Currently
Unsupported MariaDB Versions and
MySQL
1. Incompatibilities between MariaDB
10.1 and MySQL 5.7
2. Incompatibilities between MariaDB
10.0 and MySQL 5.6
3. Incompatibilities between MariaDB 5.5
and MySQL 5.5
4. Incompatibilities between MariaDB 5.3
and MySQL 5.1
5. Incompatibilities between MariaDB 5.2
and MySQL 5.1
6. Incompatibilities between MariaDB 5.1
and MySQL 5.1
5. Old, Unsupported Configuration Options
6. Replacing a MySQL RPM
7. Incompatibilities between MariaDB and
MySQL-Proxy
8. Related Links

Replacement for MySQL


Until MariaDB 5.5, MariaDB versions functioned as a "drop-in replacement" for the equivalent MySQL version, with
some limitations. From MariaDB 10.0, it is usually still very easy to upgrade from MySQL.
MariaDB's data files are generally binary compatible with those from the equivalent MySQL version.
All filenames and paths are generally the same.
Data and table definition files (.frm) files are binary compatible.
See note below for an incompatibility with views!
MariaDB's client protocol is binary compatible with MySQL's client protocol.
All client APIs and structs are identical.
All ports and sockets are generally the same.
All MySQL connectors (PHP, Perl, Python, Java, .NET, MyODBC, Ruby, MySQL C connector etc) work
unchanged with MariaDB.
There are some installation issues with PHP5 that you should be aware of (a bug in how the old PHP5
client checks library compatibility).
This means that for many cases, you can just uninstall MySQL and install MariaDB and you are good to go. There is
not generally any need to convert any data files.
However, you must still run mysql_upgrade to finish the upgrade. This is needed to ensure that your mysql privilege and
event tables are updated with the new fields MariaDB uses.
That said, MariaDB has a lot of new options, extension, storage engines and bug fixes that are not in MySQL. You
can find the feature set for the different MariaDB versions on the What is in the different MariaDB Releases page.

1648/3812
Drop-in Compatibility of Specific MariaDB Versions
MariaDB 10.2, MariaDB 10.3, and MariaDB 10.4 function as limited drop-in replacements for MySQL 5.7, as far as
InnoDB is concerned. However, the implementation differences continue to grow in each new MariaDB version.
MariaDB 10.0 and MariaDB 10.1 function as limited drop-in replacements for MySQL 5.6, as far as InnoDB is
concerned. However, there are some implementation differences in some features.
MariaDB 5.5 functions as a drop-in replacement for MySQL 5.5.
MariaDB 5.1, MariaDB 5.2 , and MariaDB 5.3 function as drop-in replacements for MySQL 5.1.

Replication Compatibility
Replication compatibility depends on:
The MariaDB Server version
The MySQL Server version
The role of each server
Replication compatibility details are described below for each MySQL version that is still currently supported.
For replication compatibility details between MariaDB versions, see Cross-Version Replication Compatibility.

MySQL 5.7
MariaDB Server 10.2 and later can replicate from a MySQL 5.7 primary server.
MariaDB Server does not support the MySQL implementation of Global Transaction IDs (GTIDs), so the MariaDB
replica server must use the binary log file and position for replication. If GTID mode is enabled on the MySQL primary
server, the MariaDB replica server will remove the MySQL GTID events and replace them with MariaDB GTID events.
Although MariaDB Server and MySQL 5.7 are compatible at the replication level, they may have some incompatibilities
at the SQL (detailed below). Those differences can cause replication failures in some cases. To decrease the risk of
compatibility issues, it is recommended to set binlog_format to ROW . When you want to replicate from MySQL 5.7 to
MariaDB Server, it is recommended to test your application, so that any compatibility issues can be found and fixed.
MariaDB can't make any claims about whether a MySQL 5.7 replica server can replicate from a MariaDB primary server.

MySQL 8.0
MariaDB Server cannot replicate from a MySQL 8.0 primary server, because MySQL 8.0 has a binary log format that is
incompatible.

Incompatibilities between Currently Supported MariaDB


Versions and MySQL
Incompatibilities between MariaDB 10.8 and MySQL 8.0
See Incompatibilities and Feature Differences Between MariaDB 10.8 and MySQL 8.0 for details.

Incompatibilities between MariaDB 10.7 and MySQL 8.0


See Incompatibilities and Feature Differences Between MariaDB 10.7 and MySQL 8.0 for details.

Incompatibilities between MariaDB 10.6 and MySQL 8.0


See Incompatibilities and Feature Differences Between MariaDB 10.6 and MySQL 8.0 for details.

Incompatibilities between MariaDB 10.5 and MySQL 8.0


See Incompatibilities and Feature Differences Between MariaDB 10.5 and MySQL 8.0 for details.

Incompatibilities between MariaDB 10.4 and MySQL 8.0


See Incompatibilities and Feature Differences Between MariaDB 10.4 and MySQL 8.0 for details.

Incompatibilities between MariaDB 10.3 and MySQL 5.7


See Incompatibilities and Feature Differences Between MariaDB 10.3 and MySQL 5.7 for details.

1649/3812
Incompatibilities between MariaDB 10.2 and MySQL 5.7
See Incompatibilities and Feature Differences Between MariaDB 10.2 and MySQL 5.7 for details.

Incompatibilities between Currently Unsupported


MariaDB Versions and MySQL
Incompatibilities between MariaDB 10.1 and MySQL 5.7
MariaDB 10.1 and above does not support MySQL 5.7's packed JSON objects. MariaDB follows the SQL
standard and stores the JSON as a normal TEXT/BLOB. If you want to replicate JSON columns from MySQL to
MariaDB, you should store JSON objects in MySQL in a TEXT column or use statement based replication. If you
are using JSON columns and want to upgrade to MariaDB, you can either convert the JSON columns to TEXT or
use mysqldump to copy these tables to MariaDB. In MySQL, JSON is compared according to json values. In
MariaDB JSON strings are normal strings and compared as strings.
MariaDB 10.1's InnoDB encryption is implemented differently than MySQL 5.7's InnoDB encryption.
MariaDB 10.1 does not support the ngram and MeCab full-text parser plugins - MDEV-10267 , MDEV-10268 .
MariaDB 10.1 does not support multiple triggers for a table - MDEV-6112 . This is fixed in MariaDB 10.2
MariaDB 10.1 does not support CREATE TABLESPACE for InnoDB.
MariaDB 10.1 does not support MySQL 5.7's “native” InnoDB partitioning handler.
MariaDB does not support MySQL 5.7's X protocol.
MariaDB 10.1 does not support the use of multiple triggers of the same type for a table. This feature was
introduced in MariaDB 10.2.2 .
MariaDB 10.1 does not support MySQL 5.7's transportable tablespaces for partitioned InnoDB tables. ALTER
TABLE ... {DISCARD|IMPORT} PARTITION is not supported. For a workaround see the following blog post .
MariaDB 10.1 does not support MySQL 5.7's online undo tablespace truncation. However, this feature was added
to MariaDB 10.2.
MySQL 5.7 features a new implementation of the performance_schema and a sys schema wrapper. These are
not yet supported in MariaDB.
MySQL 5.7 adds multi-source replication and replication channels. Multi-source replication was added to
MariaDB previously, in MariaDB 10.0, and uses a different syntax.
MySQL 5.7 adds group replication. This feature is incompatible with MariaDB's galera-cluster replication.
MariaDB 10.1 does not support MySQL 5.7's, ACCOUNT LOCK/UNLOCK synax for CREATE USER and ALTER USER
statements.
MariaDB 10.1 does not support MySQL 5.7's ALTER TABLE...RENAME INDEX statements.
MariaDB 10.1 does not support MySQL 5.7's STACKED operation for GET DIAGNOSTICS statements.
MariaDB 10.1 does not support MySQL 5.7's {WITH|WITHOUT} VALIDATION syntax for ALTER TABLE.. EXCHANGE
PARTITION statements.
MariaDB does not support the optional init_vector argument for AES_ENCRYPT and AES_DECRYPT or the
block_encryption_mode variable - MDEV-9069
MariaDB does not support the --initialize option. Use mysql_install_db instead. - MDEV-19010
Also see Incompatibilities between MariaDB 10.0 and MySQL 5.6.
Also see a detailed breakdown of System variable differences between MariaDB 10.1and MySQL 5.7 .

Incompatibilities between MariaDB 10.0 and MySQL 5.6


MySQL does not support MariaDB's Spider Storage Engine.
All MySQL binaries ( mysqld , myisamchk etc.) give a warning if one uses a prefix of an option (such as --big-
table instead of --big-tables ). MariaDB binaries work in the same way as most other Unix commands and
don't give warnings when using unique prefixes.
MariaDB GTID is not compatible with MySQL 5.6. This means that one can't have MySQL 5.6 as a slave for
MariaDB 10.0. However MariaDB 10.0 can be a slave of MySQL 5.6 or any earlier MySQL/MariaDB version.
Note that MariaDB and MySQL also have different GTID system variables, so these need to be adjusted when
migrating.
MariaDB 10.0 multi-source replication is not supported in MySQL 5.6.
To make CREATE TABLE ... SELECT work the same way in statement based and row based replication it's by
default executed as CREATE OR REPLACE TABLE on the slave. One benefit of this is that if the slave dies in
the middle of CREATE ... SELECT it will be able to continue.
One can use the slave-ddl-exec-mode variable to specify how CREATE TABLE and DROP TABLE is
replicated.
See also a detailed breakdown of System variable differences between MariaDB 10.0 and MySQL 5.6 .
MySQL 5.6 has performance schema enabled by default. For performance reasons MariaDB 10.0 has it disabled
by default. You can enable it by starting mysqld with the option --performance-schema .
MariaDB 10.0 does not support the MySQL Memcached plugin. However, data stored using memcached can be
retrieved because the data is stored as InnoDB tables. MariaDB is able to start successfully with an error
message of not being able to find libmemcached.so library.
Users created with MySQL's SHA256 password algorithm cannot be used in MariaDB 10.0 as MariaDB does not
include MySQL's sha256_password plugin.
MariaDB 10.0 does not support delayed replication - MDEV-7145 .
1650/3812
Also see a detailed breakdown of System variable differences between MariaDB 10.0 and MySQL 5.6 .
The low-level temporal format used by TIME, DATETIME and TIMESTAMP is different in MySQL 5.6 and
MariaDB 10.0. (In MariaDB 10.1, the MySQL implementation is used by default - see mysql56_temporal_format.)
MariaDB implements some changes in the SQL query optimizer over what's available in MySQL. This can result
in EXPLAIN statements showing different plans.
MySQL delayed replication, (through MASTER_DELAY ), is not supported in MariaDB 10.0, it was implemented in
MariaDB 10.2.5
MariaDB does not support the optional init_vector argument for AES_ENCRYPT and AES_DECRYPT or the
block_encryption_mode variable - MDEV-9069

Incompatibilities between MariaDB 5.5 and MySQL 5.5


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!
INSERT IGNORE also gives warnings for duplicate key errors. You can turn this off by setting
OLD_MODE=NO_DUP_KEY_WARNINGS_WITH_IGNORE (see OLD_MODE).
Before MariaDB 5.5.31 , X'HHHH' , the standard SQL syntax for binary string literals, erroneously worked in the
same way as 0xHHHH , which could work as a number or string depending on the context. In 5.5.31 this was fixed
to behave as a string in all contexts (and never as a number), introducing an incompatibility with previous
versions of MariaDB, and all versions of MySQL. See CAST and Hexadecimal Literals for more details and
examples.
MariaDB dynamic columns are not supported by MySQL.
MariaDB virtual columns are not supported by MySQL.
MariaDB's HandlerSocket plugin is not supported by MySQL.
MariaDB's Cassandra Storage Engine is not supported by MySQL.
As of MariaDB 5.5.35 , EXTRACT (HOUR FROM ...) adheres to the SQL standard and returns a result from 0 to
23. In MySQL, and earlier versions of MariaDB, the result can be greater than 23.
See also a detailed breakdown of System variable differences between MariaDB 5.5 and MySQL 5.5 .

Incompatibilities between MariaDB 5.3 and MySQL 5.1


Views with definition ALGORITHM=MERGE or ALGORITHM=TEMPTABLE got accidentally swapped
between MariaDB 5.2 and MariaDB 5.3! You have to re-create views created with either of these
definitions!
A few error messages related to wrong conversions are different as MariaDB provides more information in the
message about what went wrong.
Error numbers for MariaDB-specific errors have been moved to start from 1900 so as not to conflict with MySQL
errors.
Microseconds now work in all contexts; MySQL, in some contexts, lost the microsecond part from datetime and
time.
UNIX_TIMESTAMP(constant-date-string) returns a timestamp with 6 decimals in MariaDB while MySQL returns it
without a decimal. This can cause a problem if you are using UNIX_TIMESTAMP() as a partitioning function. You
can fix this by using FLOOR(UNIX_TIMESTAMP(..)) or changing the date string to a date number, like
20080101000000.
MariaDB performs stricter checking of date, datetime and timestamp values. For example UNIX_TIMESTAMP('x')
now returns NULL instead of 0.
The old --maria- startup options are removed. You should use the --aria- prefix instead. (MariaDB 5.2
supports both --maria- and --aria- )
SHOW PROCESSLIST has an extra Progress column which shows progress for some commands. You can disable
it by starting mysqld with either --old-mode=NO_PROGRESS_INFO or with the --old flag (see OLD_MODE).
INFORMATION_SCHEMA.PROCESSLIST has three new columns for progress reporting: STAGE , MAX_STAGE , and
PROGRESS .
Long comments which start with /*M! or /*M!##### are executed.
If you use max_user_connections=0 (which means any number of connections) when starting mysqld, you can't
change the global variable anymore while mysqld remains running. This is because when mysqld is started with
max_user_connections=0 it does not allocate counting structures (which also involve a mutex for each
connection). This would lead to wrong counters if you later changed the variable. If you want to be able to change
this variable at runtime, set it to a high value at startup.
You can set max_user_connections (both the global variable and the GRANT option) to -1 to stop users from
connecting to the server. The global max_user_connections variable does not affect users with the SUPER
privilege.
The IGNORE directive does not ignore all errors (like fatal errors), only things that are safe to ignore.

Incompatibilities between MariaDB 5.2 and MySQL 5.1


The list is the same as between MariaDB 5.1 and MySQL 5.1, with one addition:
A new SQL_MODE value was added: IGNORE_BAD_TABLE_OPTIONS . If it is not set, using a table, field, or index
attribute (option) that is not supported by the chosen storage engine will cause an error. This change might cause
warnings in the error log about incorrectly defined tables from the mysql database, fix that with mysql_upgrade.

1651/3812
For all practical purposes, MariaDB 5.2 is a drop in replacement for MariaDB 5.1 and MySQL 5.1.

Incompatibilities between MariaDB 5.1 and MySQL 5.1


In some few cases MariaDB has to be incompatible to allow MariaDB to provide more and better information than
MySQL.
Here is the list of all known user level incompatibilities you may see when using MariaDB 5.1 instead of MySQL 5.1.
The installation package names start with MariaDB instead of MySQL.
Timings may be different as MariaDB is in many cases faster than MySQL.
mysqld in MariaDB also reads the [mariadb] sections of your my.cnf files.
You can't use a binary only storage engine library with MariaDB if it's not compiled for exactly the same MariaDB
version. (This is because the server internal structure THD is different between MySQL and MariaDB. This is
common also between different MySQL versions). This should not be a problem as most people don't load new
storage engines and MariaDB comes with more storage engines than MySQL.
CHECKSUM TABLE may give different result as MariaDB doesn't ignore NULL's in the columns as MySQL 5.1 does
(Future 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.
The slow query log has more information about the query, which may be a problem if you have a script which
parses the slow query log.
MariaDB by default takes a bit more memory than MySQL because we have by default enabled the Aria storage
engine for handling internal temporary tables. If you need MariaDB to take very little memory (at the expense of
performance), you can set the value of aria_pagecache_buffer_size to 1M (the default is 128M ).
If you are using new command options, new features of MariaDB or new storage engines, you can't move easily
back and forth between MySQL and MariaDB anymore.

Old, 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

Replacing a MySQL RPM


If you uninstalled a 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 old configuration options:

mv -vi /etc/my.cnf.rpmsave /etc/my.cnf

Incompatibilities between MariaDB and MySQL-Proxy


A MySQL client API is able to connect to MariaDB using MySQL-Proxy but a MariaDB client API will receive progress
reporting informations that MySQL-Proxy does not implement, to get full compatibility in all case just disable progress
reporting on the client or server side.
Another option is to use the MariaDB MaxScale proxy , that works with both MySQL and MariaDB.

Related Links
MariaDB vs MySQL - Features
Moving from MySQL to MariaDB
Troubleshooting Installation Issues
Projects and applications that works with MariaDB

2.1.14.1.3 Upgrading from MySQL to MariaDB


2.1.14.1.4 Incompatibilities and Feature
Differences Between MariaDB 10.8 and MySQL
8.0
1652/3812
Contents
1. Storage Engines
2. Extensions and New Features
3. Incompatibilities

MariaDB maintains high levels of compatibility with MySQL, and most applications that use MySQL will work seamlessly
with MariaDB. However, take note of the following incompatibilities and feature differences between MariaDB 10.8 and
MySQL 8.0. It is based on the versions MySQL 8.0.25 and MariaDB 10.8.3. Note that MySQL 8 is an 'evergreen'
release, so features may be added or removed in later releases.

Storage Engines
In addition to the standard InnoDB, MyISAM, BLACKHOLE, CSV, MEMORY, ARCHIVE, and MERGE storage engines,
the following are also available with MariaDB 10.8:
ColumnStore utilizes a massively parallel distributed data architecture and is designed for big data scaling to
process petabytes of data.
MyRocks, a storage engine with great compression
S3 storage engine allows one to archive MariaDB tables in Amazon S3, or any third-party public or private cloud
that implements S3 API.
Aria, MyISAM replacement with better caching.
CONNECT
SEQUENCE
Spider
SphinxSE
FederatedX (drop-in replacement for Federated)
OQGRAPH

Extensions and New Features


The most notable features available in MariaDB , but not in MySQL, are:
Galera is a standard part of MariaDB Server.
Temporal data tables in the form of:
System-versioned tables (allow you to query and operate on historic data).
Application-time periods (allow you to query and operate on a temporal range of data), including the
WITHOUT OVERLAPS clause.
Bitemporal tables (which combine both system-versioning and application-time periods).
DML-only flashback, allowing instances, databases or tables to be rolled back to an old snapshot.
Oracle compatibility mode
Sequences
Invisible Columns
Table Value Constructors
Dynamic Columns support
Semi-sync plugin merged into the server
INTERSECT/INTERSECT ALL and EXCEPT/EXCEPT ALL
OR REPLACE syntax for CREATE statements, such as CREATE OR REPLACE TABLE, CREATE OR REPLACE
DATABASE, etc
DELETE ... RETURNING, INSERT ... RETURNING, REPLACE ... RETURNING
WAIT syntax for setting the lock wait timeout.
UUID data type for storing UUIDs.
INET6 data type for storing IPv6 addresses.
SUPER privileges made more granular.
PROXY protocol support
Multiple compression algorithms available as plugins
Number of supported decimals in DECIMAL has increased from 30 to 38
Added catchall for list partitions
Oracle-style EXECUTE IMMEDIATE statement
Lots of new JSON functions
Microsecond Precision in Processlist
Table Elimination
Virtual Columns
Extended User Statistics
KILL all queries for a user
Storage-engine-specific CREATE TABLE
MariaDB supports more collations than MySQL, including NO PAD collations.
FLUSH SSL command to reload SSL certificates without server restart.
IF NOT EXISTS clause added to INSTALL PLUGIN and IF EXISTS clause added to UNINSTALL PLUGIN and
UNINSTALL SONAME
Enhancements to INFORMATION SCHEMA.PLUGINS table

1653/3812
Group commit for the binary log. This makes replication notably faster!
The binary log in MariaDB can be compressed.
BACKUP STAGE allows one to implement very efficient backups with minimal locking.
Progress reporting for ALTER TABLE and LOAD DATA INFILE
SHOW EXPLAIN gives the EXPLAIN plan for a query running in another thread. MySQL introduced the EXPLAIN
FOR CONNECTION syntax to do the same thing.
PCRE Regular Expressions (including REGEXP_REPLACE())
HandlerSocket and faster HANDLER calls

Incompatibilities
When moving from MySQL 8.0 to MariaDB 10.8, please take note of the following incompatibilities:
For a list of function differences, see Function Differences Between MariaDB 10.8 and MySQL 8.0
For a list of system variable differences, see System Variable Differences Between MariaDB 10.8 and MySQL 8.0
MariaDB's GTID is not compatible with MySQL's. Note that MariaDB and MySQL also have different GTID system
variables, so these need to be adjusted when migrating.
The unix_socket authentication plugin is now default on Unix-like systems, which is a major change to
authentication in MariaDB. See Authentication from MariaDB 10.4 for an overview of the changes.
All mysql* binaries are now named mariadb* (the previous mysql named is retained as a symlink for compatibility
purposes)
Not all character sets and collations are supported across both MySQL and MariaDB. As of 10.8.3, MariaDB
supports 40 character sets and 322 collations (armscii8_general_nopad_ci, armscii8_nopad_bin,
ascbig5_chinese_nopad_ci, big5_nopad_bin, iicp1250_general_nopad_ci, cp1250_nopad_bin,
cp1250_general_nopad_ci, cp1250_nopad_bin, cp1251_general_nopad_ci, cp1251_nopad_bin,
cp1256_general_nopad_ci, cp1256_nopad_bin, cp1257_general_nopad_ci, cp1257_nopad_bin,
cp850_general_nopad_ci, cp850_nopad_bin, cp852_general_nopad_ci, cp852_nopad_bin,
cp866_general_nopad_ci, cp866_nopad_bin, cp932_japanese_nopad_ci, cp932_nopad_bin, dec8_nopad_bin,
dec8_swedish_nopad_ci, eucjpms_japanese_nopad_ci, eucjpms_nopad_bin, eucjpms_japanese_nopad_ci,
eucjpms_nopad_bin, euckr_korean_nopad_ci, euckr_nopad_bin, gb2312_chinese_nopad_ci,
gb2312_nopad_bin, gbk_chinese_nopad_ci, gbk_nopad_bin, geostd8_general_nopad_ci, geostd8_nopad_bin,
greek_general_nopad_ci, greek_nopad_bin, hebrew_general_nopad_ci, hebrew_nopad_bin,
hp8_english_nopad_ci, hp8_nopad_bin, keybcs2_general_nopad_ci, keybcs2_nopad_bin,
koi8r_general_nopad_ci, koi8r_nopad_bin, koi8u_general_nopad_ci, koi8u_nopad_bin, latin1_nopad_bin,
latin1_swedish_nopad_ci, latin2_general_nopad_ci, latin2_nopad_bin, latin5_nopad_bin, latin5_turkish_ci,
latin5_turkish_nopad_ci, latin7_general_nopad_ci, latin7_nopad_bin, macce_general_nopad_ci,
macce_nopad_bin, macroman_general_nopad_ci, macroman_nopad_bin, sjis_japanese_nopad_ci,
sjis_nopad_bin, swe7_nopad_bin, tis620_thai_nopad_ci, tis620_nopad_bin, ucs2_croatian_mysql561_ci,
ucs2_general_mysql500_ci, ucs2_general_nopad_ci, ucs2_myanmar_ci, ucs2_nopad_bin, ucs2_swedish_ci,
ucs2_thai_520_w2, ucs2_unicode_ci, ucs2_unicode_nopad_ci, ujis_japanese_nopad_ci, ujis_nopad_bin,
utf16le_general_nopad_ci, utf16le_nopad_bin, utf16_croatian_mysql561_ci, utf16_general_nopad_ci,
utf16_myanmar_ci, utf16_nopad_bin, utf16_thai_520_w2, utf16_unicode_520_nopad_ci,
utf16_unicode_nopad_ci, utf32_croatian_mysql561_ci, utf32_general_nopad_ci, utf32_myanmar_ci,
utf32_nopad_bin, utf32_thai_520_w2, utf32_unicode_520_nopad_ci, utf32_unicode_nopad_ci,
utf8mb4_general_nopad_ci, utf8mb4_myanmar_ci, utf8mb4_nopad_bin, utf8mb4_thai_520_w2,
utf8mb4_unicode_520_nopad_ci, utf8mb4_unicode_nopad_ci, utf8_croatian_mysql561_ci,
utf8_general_nopad_ci, utf8_myanmar_ci, utf8_nopad_bin, utf8_thai_520_w2, utf8_unicode_520_nopad_ci,
utf8_unicode_ci and utf8_unicode_nopad_ci being the additional ones).

As of 8.0.25, MySQL supports 41 character sets ( gb18030 being the additional one - MDEV-7495 ) and 272
collations (gb18030_bin, gb18030_chinese_ci, gb18030_unicode_520_ci, utf8mb4_0900_ai_ci,
utf8mb4_0900_as_ci, utf8mb4_0900_as_cs, utf8mb4_0900_bin, utf8mb4_cs_0900_ai_ci,
utf8mb4_cs_0900_as_cs, utf8mb4_da_0900_ai_ci, utf8mb4_da_0900_as_cs, utf8mb4_de_pb_0900_ai_ci,
utf8mb4_de_pb_0900_as_cs, utf8mb4_eo_0900_ai_ci, utf8mb4_eo_0900_as_cs, utf8mb4_es_0900_ai_ci,
utf8mb4_es_0900_as_cs, utf8mb4_es_trad_0900_ai_ci, utf8mb4_es_trad_0900_as_cs, utf8mb4_et_0900_ai_ci,
utf8mb4_et_0900_as_cs, utf8mb4_hr_0900_ai_ci, utf8mb4_hr_0900_as_cs, utf8mb4_hu_0900_ai_ci,
utf8mb4_hu_0900_as_cs, utf8mb4_is_0900_ai_ci, utf8mb4_is_0900_as_cs, utf8mb4_ja_0900_as_cs,
utf8mb4_ja_0900_as_cs_ks, utf8mb4_la_0900_ai_ci, utf8mb4_la_0900_as_cs, utf8mb4_lt_0900_ai_ci,
utf8mb4_lt_0900_as_cs, utf8mb4_lv_0900_ai_ci, utf8mb4_lv_0900_as_cs, utf8mb4_pl_0900_ai_ci,
utf8mb4_pl_0900_as_cs, utf8mb4_ro_0900_ai_ci, utf8mb4_ro_0900_as_cs, utf8mb4_ru_0900_ai_ci,
utf8mb4_ru_0900_as_cs, utf8mb4_sk_0900_ai_ci, utf8mb4_sk_0900_as_cs, utf8mb4_sl_0900_ai_ci,
utf8mb4_sl_0900_as_cs, utf8mb4_sv_0900_ai_ci, utf8mb4_sv_0900_as_cs, utf8mb4_tr_0900_ai_ci,
utf8mb4_vi_0900_ai_ci, utf8mb4_vi_0900_as_cs, utf8mb4_zh_0900_as_cs being the additional ones) - MDEV-
20912 .
To make CREATE TABLE ... SELECT work the same way in statement based and row based replication it's by
default executed as CREATE OR REPLACE TABLE on the slave. One benefit of this is that if the slave dies in
the middle of CREATE ... SELECT it will be able to continue.
One can use the slave-ddl-exec-mode variable to specify how CREATE TABLE and DROP TABLE is
replicated.
Users created with MySQL's SHA256 password algorithm cannot be used in MariaDB 10.8 - MDEV-9804 .
MariaDB 10.8 does not support Lateral Derived Tables - MDEV-19078 .
1654/3812
MariaDB 10.8 does not support CIDR notation for user accounts - MDEV-25515 .
MariaDB stores JSON as true text, not in binary format as MySQL. MariaDB's JSON functions are much faster
than MySQL's so there is no need to store in binary format, which would add complexity when manipulating JSON
objects.
For the same reason, MariaDB's JSON data type is an alias for LONGTEXT. If you want to replicate JSON
columns from MySQL to MariaDB, you should store JSON objects in MySQL in a TEXT or LONGTEXT column or
use statement based replication. If you are using JSON columns and want to upgrade to MariaDB, you need to
either convert them to TEXT or use mysqldump to copy these tables to MariaDB. See also Making MariaDB
understand MySQL JSON .
In MySQL, JSON is compared according to json values. In MariaDB JSON strings are normal strings and
compared as strings.
MariaDB 10.8 does not support MySQL's JSON operators ( -> and ->> ) (MDEV-13594 )
MariaDB 10.8 supports the standard by producing null and a warning for JSON_SEARCH when given invalid
data, while MySQL produces an error.
Roles
MariaDB never allows authentication via roles, while MySQL permits this.
MySQL permits activating multiple roles at the same time. MariaDB can achieve the same result by creating
an intermediate aggregate role.
In the INFORMATION_SCHEMA.ENABLED_ROLES table, MySQL reports just the direct list of enabled
roles, while MariaDB reports the enabled role, plus the effective inherited roles.
MySQL extends the INFORMATION_SCHEMA.APPLICABLE_ROLES table .
MySQL includes the tables INFORMATION_SCHEMA.ROLE_TABLE_GRANTS,
INFORMATION_SCHEMA.ROLE_ROUTINE_GRANTS,
INFORMATION_SCHEMA.ROLE_COLUMN_GRANTS, and INFORMATION_SCHEMA
ADMINISTRABLE_ROLE_AUTHORIZATIONS.
MySQL has the performance schema enabled by default. For performance reasons MariaDB 10.8 has it disabled
by default. You can enable it by starting mysqld with the option --performance-schema .
In MariaDB 10.8, using FLUSH TABLES 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, the server will wait for
the end of any transactions that are using the tables. In MySQL, FLUSH TABLES only waits for the statements to
complete.
MariaDB binaries ( mysqld , myisamchk etc.) give a warning if one uses a unique prefix of an option (such as --
big-table instead of --big-tables ). MySQL binaries require the full option name.
MariaDB 10.8 implements InnoDB encryption in a different way to MySQL 8.0.
MySQL's implementation of aborting statements that exceed a certain time to execute can only kill SELECTs,
while MariaDB's can kill any queries (excluding stored procedures).
MariaDB 10.8 does not support MySQL's SELECT /*+ MAX_EXECUTION_TIME(n) */ ... - see Aborting
Statements that Exceed a Certain Time to Execute.
MySQL 8.0 does not support the Query Cache.
MariaDB 10.8 does not support the MySQL Memcached plugin (which has been deprecated in MySQL 8.0).
However, data stored using memcached can be retrieved because the data is stored as InnoDB tables. MariaDB
is able to start successfully with an error message of not being able to find libmemcached.so library.
In MySQL, X'HHHH' , the standard SQL syntax for binary string literals, erroneously works in the same way as
0xHHHH , which could work as a number or string depending on the context. In MariaDB, this has been fixed to
behave as a string in all contexts (and never as a number). See CAST and Hexadecimal Literals for more details
and examples.
In MariaDB 10.8, SHOW CREATE TABLE does not quote the DEFAULT value of an integer. MariaDB 10.2 and
earlier, and MySQL, do. Since MariaDB can support defaults for BLOB and TEXT fields, while MySQL does not,
SHOW CREATE TABLE will also append DEFAULT NULL where no default is explicitly provided to nullable BLOB
or TEXT fields in MariaDB.
Since MariaDB supports INTERSECT and EXCEPT, these are both reserved words and can't be used as an
identifier without being quoted.
As a result of implementing Table Value Constructors, the VALUES function has been renamed to VALUE().
MariaDB's NOWAIT supports SELECT statements, LOCK TABLES and various DDL statements, while MySQL's
NOWAIT only supports SELECT.
MariaDB's NOWAIT cannot be added on views and stored procedures while MySQL's can - MDEV-25247
MariaDB returns an ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction when
unable to lock within the time, while MySQL returns ERROR 3572 (HY000): Statement aborted because lock(s)
could not be acquired immediately and NOWAIT is set
MariaDB does not support the optional init_vector argument for AES_ENCRYPT and AES_DECRYPT or the
block_encryption_mode variable - MDEV-9069
MariaDB does not support the --initialize option. Use mysql_install_db instead. - MDEV-19010
MariaDB 10.8 does not support the ngram and MeCab full-text parser plugins - MDEV-10267 , MDEV-10268 .
MariaDB 10.8 does not support the MySQL X plugin .
MariaDB 10.8 does not support MySQL 8's “native” InnoDB partitioning handler.
MariaDB 10.8 does not support CREATE TABLESPACE for InnoDB.
The MySQL 8.0 and MariaDB 10.8 INFORMATION_SCHEMA.COLUMNS table contain slightly different fields.
MariaDB 10.8 client executables allow the connection protocol to be forced by specifying only connection
properties on the command-line. See mysql Command-line client
The MySQL binary log includes the thread_id, while MariaDB's binary log does not. (MDEV-7850 )
1655/3812
2.1.14.1.5 Incompatibilities and Feature
Differences Between MariaDB 10.7 and MySQL
8.0
Contents
1. Storage Engines
2. Extensions and New Features
3. Incompatibilities

MariaDB maintains high levels of compatibility with MySQL, and most applications that use MySQL will work seamlessly
with MariaDB. However, take note of the following incompatibilities and feature differences between MariaDB 10.7 and
MySQL 8.0. It is based on the versions MySQL 8.0.25 and MariaDB 10.7.0. Note that MySQL 8 is an 'evergreen'
release, so features may be added or removed in later releases.

Storage Engines
In addition to the standard InnoDB, MyISAM, BLACKHOLE, CSV, MEMORY, ARCHIVE, and MERGE storage engines,
the following are also available with MariaDB 107:
ColumnStore utilizes a massively parallel distributed data architecture and is designed for big data scaling to
process petabytes of data.
MyRocks, a storage engine with great compression
S3 storage engine allows one to archive MariaDB tables in Amazon S3, or any third-party public or private cloud
that implements S3 API.
Aria, MyISAM replacement with better caching.
CONNECT
SEQUENCE
Spider
SphinxSE
FederatedX (drop-in replacement for Federated)
OQGRAPH

Extensions and New Features


The most notable features available in MariaDB , but not in MySQL, are:
Galera is a standard part of MariaDB Server.
Temporal data tables in the form of:
System-versioned tables (allow you to query and operate on historic data).
Application-time periods (allow you to query and operate on a temporal range of data), including the
WITHOUT OVERLAPS clause.
Bitemporal tables (which combine both system-versioning and application-time periods).
DML-only flashback, allowing instances, databases or tables to be rolled back to an old snapshot.
Oracle compatibility mode
Sequences
Invisible Columns
Table Value Constructors
Dynamic Columns support
Semi-sync plugin merged into the server
INTERSECT/INTERSECT ALL and EXCEPT/EXCEPT ALL
OR REPLACE syntax for CREATE statements, such as CREATE OR REPLACE TABLE, CREATE OR REPLACE
DATABASE, etc
DELETE ... RETURNING, INSERT ... RETURNING, REPLACE ... RETURNING
WAIT syntax for setting the lock wait timeout.
UUID data type for storing UUIDs.
INET6 data type for storing IPv6 addresses.
SUPER privileges made more granular.
PROXY protocol support
Multiple compression algorithms available as plugins
Number of supported decimals in DECIMAL has increased from 30 to 38
Added catchall for list partitions
Oracle-style EXECUTE IMMEDIATE statement
Lots of new JSON functions
Microsecond Precision in Processlist
Table Elimination
Virtual Columns
Extended User Statistics
KILL all queries for a user
1656/3812
Storage-engine-specific CREATE TABLE
MariaDB supports more collations than MySQL, including NO PAD collations.
FLUSH SSL command to reload SSL certificates without server restart.
IF NOT EXISTS clause added to INSTALL PLUGIN and IF EXISTS clause added to UNINSTALL PLUGIN and
UNINSTALL SONAME
Enhancements to INFORMATION SCHEMA.PLUGINS table
Group commit for the binary log. This makes replication notably faster!
The binary log in MariaDB can be compressed.
BACKUP STAGE allows one to implement very efficient backups with minimal locking.
Progress reporting for ALTER TABLE and LOAD DATA INFILE
SHOW EXPLAIN gives the EXPLAIN plan for a query running in another thread. MySQL introduced the EXPLAIN
FOR CONNECTION syntax to do the same thing.
PCRE Regular Expressions (including REGEXP_REPLACE())
HandlerSocket and faster HANDLER calls

Incompatibilities
When moving from MySQL 8.0 to MariaDB 10.7, please take note of the following incompatibilities:
For a list of function differences, see Function Differences Between MariaDB 10.7 and MySQL 8.0
For a list of system variable differences, see System Variable Differences Between MariaDB 10.7 and MySQL 8.0
MariaDB's GTID is not compatible with MySQL's. Note that MariaDB and MySQL also have different GTID system
variables, so these need to be adjusted when migrating.
The unix_socket authentication plugin is now default on Unix-like systems, which is a major change to
authentication in MariaDB. See Authentication from MariaDB 10.4 for an overview of the changes.
All mysql* binaries are now named mariadb* (the previous mysql named is retained as a symlink for compatibility
purposes)
Not all character sets and collations are supported across both MySQL and MariaDB. As of 10.7.0, MariaDB
supports 40 character sets and 322 collations (armscii8_general_nopad_ci, armscii8_nopad_bin,
ascbig5_chinese_nopad_ci, big5_nopad_bin, iicp1250_general_nopad_ci, cp1250_nopad_bin,
cp1250_general_nopad_ci, cp1250_nopad_bin, cp1251_general_nopad_ci, cp1251_nopad_bin,
cp1256_general_nopad_ci, cp1256_nopad_bin, cp1257_general_nopad_ci, cp1257_nopad_bin,
cp850_general_nopad_ci, cp850_nopad_bin, cp852_general_nopad_ci, cp852_nopad_bin,
cp866_general_nopad_ci, cp866_nopad_bin, cp932_japanese_nopad_ci, cp932_nopad_bin, dec8_nopad_bin,
dec8_swedish_nopad_ci, eucjpms_japanese_nopad_ci, eucjpms_nopad_bin, eucjpms_japanese_nopad_ci,
eucjpms_nopad_bin, euckr_korean_nopad_ci, euckr_nopad_bin, gb2312_chinese_nopad_ci,
gb2312_nopad_bin, gbk_chinese_nopad_ci, gbk_nopad_bin, geostd8_general_nopad_ci, geostd8_nopad_bin,
greek_general_nopad_ci, greek_nopad_bin, hebrew_general_nopad_ci, hebrew_nopad_bin,
hp8_english_nopad_ci, hp8_nopad_bin, keybcs2_general_nopad_ci, keybcs2_nopad_bin,
koi8r_general_nopad_ci, koi8r_nopad_bin, koi8u_general_nopad_ci, koi8u_nopad_bin, latin1_nopad_bin,
latin1_swedish_nopad_ci, latin2_general_nopad_ci, latin2_nopad_bin, latin5_nopad_bin, latin5_turkish_ci,
latin5_turkish_nopad_ci, latin7_general_nopad_ci, latin7_nopad_bin, macce_general_nopad_ci,
macce_nopad_bin, macroman_general_nopad_ci, macroman_nopad_bin, sjis_japanese_nopad_ci,
sjis_nopad_bin, swe7_nopad_bin, tis620_thai_nopad_ci, tis620_nopad_bin, ucs2_croatian_mysql561_ci,
ucs2_general_mysql500_ci, ucs2_general_nopad_ci, ucs2_myanmar_ci, ucs2_nopad_bin, ucs2_swedish_ci,
ucs2_thai_520_w2, ucs2_unicode_ci, ucs2_unicode_nopad_ci, ujis_japanese_nopad_ci, ujis_nopad_bin,
utf16le_general_nopad_ci, utf16le_nopad_bin, utf16_croatian_mysql561_ci, utf16_general_nopad_ci,
utf16_myanmar_ci, utf16_nopad_bin, utf16_thai_520_w2, utf16_unicode_520_nopad_ci,
utf16_unicode_nopad_ci, utf32_croatian_mysql561_ci, utf32_general_nopad_ci, utf32_myanmar_ci,
utf32_nopad_bin, utf32_thai_520_w2, utf32_unicode_520_nopad_ci, utf32_unicode_nopad_ci,
utf8mb4_general_nopad_ci, utf8mb4_myanmar_ci, utf8mb4_nopad_bin, utf8mb4_thai_520_w2,
utf8mb4_unicode_520_nopad_ci, utf8mb4_unicode_nopad_ci, utf8_croatian_mysql561_ci,
utf8_general_nopad_ci, utf8_myanmar_ci, utf8_nopad_bin, utf8_thai_520_w2, utf8_unicode_520_nopad_ci,
utf8_unicode_ci and utf8_unicode_nopad_ci being the additional ones).

As of 8.0.25, MySQL supports 41 character sets ( gb18030 being the additional one - MDEV-7495 ) and 272
collations (gb18030_bin, gb18030_chinese_ci, gb18030_unicode_520_ci, utf8mb4_0900_ai_ci,
utf8mb4_0900_as_ci, utf8mb4_0900_as_cs, utf8mb4_0900_bin, utf8mb4_cs_0900_ai_ci,
utf8mb4_cs_0900_as_cs, utf8mb4_da_0900_ai_ci, utf8mb4_da_0900_as_cs, utf8mb4_de_pb_0900_ai_ci,
utf8mb4_de_pb_0900_as_cs, utf8mb4_eo_0900_ai_ci, utf8mb4_eo_0900_as_cs, utf8mb4_es_0900_ai_ci,
utf8mb4_es_0900_as_cs, utf8mb4_es_trad_0900_ai_ci, utf8mb4_es_trad_0900_as_cs, utf8mb4_et_0900_ai_ci,
utf8mb4_et_0900_as_cs, utf8mb4_hr_0900_ai_ci, utf8mb4_hr_0900_as_cs, utf8mb4_hu_0900_ai_ci,
utf8mb4_hu_0900_as_cs, utf8mb4_is_0900_ai_ci, utf8mb4_is_0900_as_cs, utf8mb4_ja_0900_as_cs,
utf8mb4_ja_0900_as_cs_ks, utf8mb4_la_0900_ai_ci, utf8mb4_la_0900_as_cs, utf8mb4_lt_0900_ai_ci,
utf8mb4_lt_0900_as_cs, utf8mb4_lv_0900_ai_ci, utf8mb4_lv_0900_as_cs, utf8mb4_pl_0900_ai_ci,
utf8mb4_pl_0900_as_cs, utf8mb4_ro_0900_ai_ci, utf8mb4_ro_0900_as_cs, utf8mb4_ru_0900_ai_ci,
utf8mb4_ru_0900_as_cs, utf8mb4_sk_0900_ai_ci, utf8mb4_sk_0900_as_cs, utf8mb4_sl_0900_ai_ci,
utf8mb4_sl_0900_as_cs, utf8mb4_sv_0900_ai_ci, utf8mb4_sv_0900_as_cs, utf8mb4_tr_0900_ai_ci,
utf8mb4_vi_0900_ai_ci, utf8mb4_vi_0900_as_cs, utf8mb4_zh_0900_as_cs being the additional ones) - MDEV-
20912 .
To make CREATE TABLE ... SELECT work the same way in statement based and row based replication it's by
1657/3812
default executed as CREATE OR REPLACE TABLE on the slave. One benefit of this is that if the slave dies in
the middle of CREATE ... SELECT it will be able to continue.
One can use the slave-ddl-exec-mode variable to specify how CREATE TABLE and DROP TABLE is
replicated.
Users created with MySQL's SHA256 password algorithm cannot be used in MariaDB 10.7 - MDEV-9804 .
MariaDB 10.7 does not support Lateral Derived Tables - MDEV-19078 .
MariaDB 10.7 does not support CIDR notation for user accounts - MDEV-25515 .
MariaDB stores JSON as true text, not in binary format as MySQL. MariaDB's JSON functions are much faster
than MySQL's so there is no need to store in binary format, which would add complexity when manipulating JSON
objects.
For the same reason, MariaDB's JSON data type is an alias for LONGTEXT. If you want to replicate JSON
columns from MySQL to MariaDB, you should store JSON objects in MySQL in a TEXT or LONGTEXT column or
use statement based replication. If you are using JSON columns and want to upgrade to MariaDB, you need to
either convert them to TEXT or use mysqldump to copy these tables to MariaDB. See also Making MariaDB
understand MySQL JSON .
In MySQL, JSON is compared according to json values. In MariaDB JSON strings are normal strings and
compared as strings.
MariaDB 10.7 does not support MySQL's JSON operators ( -> and ->> ) (MDEV-13594 )
MariaDB 10.7 supports the standard by producing null and a warning for JSON_SEARCH when given invalid
data, while MySQL produces an error.
Roles
MariaDB never allows authentication via roles, while MySQL permits this.
MySQL permits activating multiple roles at the same time. MariaDB can achieve the same result by creating
an intermediate aggregate role.
In the INFORMATION_SCHEMA.ENABLED_ROLES table, MySQL reports just the direct list of enabled
roles, while MariaDB reports the enabled role, plus the effective inherited roles.
MySQL extends the INFORMATION_SCHEMA.APPLICABLE_ROLES table .
MySQL includes the tables INFORMATION_SCHEMA.ROLE_TABLE_GRANTS,
INFORMATION_SCHEMA.ROLE_ROUTINE_GRANTS,
INFORMATION_SCHEMA.ROLE_COLUMN_GRANTS, and INFORMATION_SCHEMA
ADMINISTRABLE_ROLE_AUTHORIZATIONS.
MySQL has the performance schema enabled by default. For performance reasons MariaDB 10.7 has it disabled
by default. You can enable it by starting mysqld with the option --performance-schema .
In MariaDB 10.7, using FLUSH TABLES 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, the server will wait for
the end of any transactions that are using the tables. In MySQL, FLUSH TABLES only waits for the statements to
complete.
MariaDB binaries ( mysqld , myisamchk etc.) give a warning if one uses a unique prefix of an option (such as --
big-table instead of --big-tables ). MySQL binaries require the full option name.
MariaDB 10.7 implements InnoDB encryption in a different way to MySQL 8.0.
MySQL's implementation of aborting statements that exceed a certain time to execute can only kill SELECTs,
while MariaDB's can kill any queries (excluding stored procedures).
MariaDB 10.7 does not support MySQL's SELECT /*+ MAX_EXECUTION_TIME(n) */ ... - see Aborting
Statements that Exceed a Certain Time to Execute.
MySQL 8.0 does not support the Query Cache.
MariaDB 10.7 does not support the MySQL Memcached plugin (which has been deprecated in MySQL 8.0).
However, data stored using memcached can be retrieved because the data is stored as InnoDB tables. MariaDB
is able to start successfully with an error message of not being able to find libmemcached.so library.
In MySQL, X'HHHH' , the standard SQL syntax for binary string literals, erroneously works in the same way as
0xHHHH , which could work as a number or string depending on the context. In MariaDB, this has been fixed to
behave as a string in all contexts (and never as a number). See CAST and Hexadecimal Literals for more details
and examples.
In MariaDB 10.7, SHOW CREATE TABLE does not quote the DEFAULT value of an integer. MariaDB 10.2 and
earlier, and MySQL, do. Since MariaDB can support defaults for BLOB and TEXT fields, while MySQL does not,
SHOW CREATE TABLE will also append DEFAULT NULL where no default is explicitly provided to nullable BLOB
or TEXT fields in MariaDB.
Since MariaDB supports INTERSECT and EXCEPT, these are both reserved words and can't be used as an
identifier without being quoted.
As a result of implementing Table Value Constructors, the VALUES function has been renamed to VALUE().
MariaDB's NOWAIT supports SELECT statements, LOCK TABLES and various DDL statements, while MySQL's
NOWAIT only supports SELECT.
MariaDB's NOWAIT cannot be added on views and stored procedures while MySQL's can - MDEV-25247
MariaDB returns an ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction when
unable to lock within the time, while MySQL returns ERROR 3572 (HY000): Statement aborted because lock(s)
could not be acquired immediately and NOWAIT is set
MariaDB does not support the optional init_vector argument for AES_ENCRYPT and AES_DECRYPT or the
block_encryption_mode variable - MDEV-9069
MariaDB does not support the --initialize option. Use mysql_install_db instead. - MDEV-19010
MariaDB 10.7 does not support the ngram and MeCab full-text parser plugins - MDEV-10267 , MDEV-10268 .
MariaDB 10.7 does not support the MySQL X plugin .

1658/3812
MariaDB 10.7 does not support MySQL 8's “native” InnoDB partitioning handler.
MariaDB 10.7 does not support CREATE TABLESPACE for InnoDB.
The MySQL 8.0 and MariaDB 10.7 INFORMATION_SCHEMA.COLUMNS table contain slightly different fields.
MariaDB 10.7 client executables allow the connection protocol to be forced by specifying only connection
properties on the command-line. See mysql Command-line client
The MySQL binary log includes the thread_id, while MariaDB's binary log does not. (MDEV-7850 )

2.1.14.1.6 Incompatibilities and Feature


Differences Between MariaDB 10.6 and MySQL
8.0
Contents
1. Storage Engines
2. Extensions and New Features
3. Incompatibilities

MariaDB maintains high levels of compatibility with MySQL, and most applications that use MySQL will work seamlessly
with MariaDB. However, take note of the following incompatibilities and feature differences between MariaDB 10.6 and
MySQL 8.0. It is based on the versions MySQL 8.0.25 and MariaDB 10.6.0. Note that MySQL 8 is an 'evergreen'
release, so features may be added or removed in later releases.

Storage Engines
In addition to the standard InnoDB, MyISAM, BLACKHOLE, CSV, MEMORY, ARCHIVE, and MERGE storage engines,
the following are also available with MariaDB 10.6:
ColumnStore utilizes a massively parallel distributed data architecture and is designed for big data scaling to
process petabytes of data.
MyRocks, a storage engine with great compression
S3 storage engine allows one to archive MariaDB tables in Amazon S3, or any third-party public or private cloud
that implements S3 API.
Aria, MyISAM replacement with better caching.
CONNECT
SEQUENCE
Spider
SphinxSE
FederatedX (drop-in replacement for Federated)
OQGRAPH

Extensions and New Features


The most notable features available in MariaDB , but not in MySQL, are:
Galera is a standard part of MariaDB Server.
Temporal data tables in the form of:
System-versioned tables (allow you to query and operate on historic data).
Application-time periods (allow you to query and operate on a temporal range of data), including the
WITHOUT OVERLAPS clause.
Bitemporal tables (which combine both system-versioning and application-time periods).
DML-only flashback, allowing instances, databases or tables to be rolled back to an old snapshot.
Oracle compatibility mode
Sequences
Invisible Columns
Table Value Constructors
Dynamic Columns support
Semi-sync plugin merged into the server
INTERSECT/INTERSECT ALL and EXCEPT/EXCEPT ALL
OR REPLACE syntax for CREATE statements, such as CREATE OR REPLACE TABLE, CREATE OR REPLACE
DATABASE, etc
DELETE ... RETURNING, INSERT ... RETURNING, REPLACE ... RETURNING
WAIT syntax for setting the lock wait timeout.
INET6 data type for storing IPv6 addresses.
SUPER privileges made more granular.
PROXY protocol support
Number of supported decimals in DECIMAL has increased from 30 to 38
Added catchall for list partitions
Oracle-style EXECUTE IMMEDIATE statement
Lots of new JSON functions
1659/3812
Microsecond Precision in Processlist
Table Elimination
Virtual Columns
Extended User Statistics
KILL all queries for a user
Storage-engine-specific CREATE TABLE
MariaDB supports more collations than MySQL, including NO PAD collations.
FLUSH SSL command to reload SSL certificates without server restart.
IF NOT EXISTS clause added to INSTALL PLUGIN and IF EXISTS clause added to UNINSTALL PLUGIN and
UNINSTALL SONAME
Enhancements to INFORMATION SCHEMA.PLUGINS table
Group commit for the binary log. This makes replication notably faster!
The binary log in MariaDB can be compressed.
BACKUP STAGE allows one to implement very efficient backups with minimal locking.
Progress reporting for ALTER TABLE and LOAD DATA INFILE
SHOW EXPLAIN gives the EXPLAIN plan for a query running in another thread. MySQL introduced the EXPLAIN
FOR CONNECTION syntax to do the same thing.
PCRE Regular Expressions (including REGEXP_REPLACE())
HandlerSocket and faster HANDLER calls

Incompatibilities
When moving from MySQL 8.0 to MariaDB 10.6, please take note of the following incompatibilities:
For a list of function differences, see Function Differences Between MariaDB 10.6 and MySQL 8.0
For a list of system variable differences, see System Variable Differences Between MariaDB 10.6 and MySQL 8.0
MariaDB's GTID is not compatible with MySQL's. Note that MariaDB and MySQL also have different GTID system
variables, so these need to be adjusted when migrating.
The unix_socket authentication plugin is now default on Unix-like systems, which is a major change to
authentication in MariaDB. See Authentication from MariaDB 10.4 for an overview of the changes.
All mysql* binaries are now named mariadb* (the previous mysql named is retained as a symlink for compatibility
purposes)
Not all character sets and collations are supported across both MySQL and MariaDB. As of 10.6.0, MariaDB
supports 40 character sets and 322 collations (armscii8_general_nopad_ci, armscii8_nopad_bin,
ascbig5_chinese_nopad_ci, big5_nopad_bin, iicp1250_general_nopad_ci, cp1250_nopad_bin,
cp1250_general_nopad_ci, cp1250_nopad_bin, cp1251_general_nopad_ci, cp1251_nopad_bin,
cp1256_general_nopad_ci, cp1256_nopad_bin, cp1257_general_nopad_ci, cp1257_nopad_bin,
cp850_general_nopad_ci, cp850_nopad_bin, cp852_general_nopad_ci, cp852_nopad_bin,
cp866_general_nopad_ci, cp866_nopad_bin, cp932_japanese_nopad_ci, cp932_nopad_bin, dec8_nopad_bin,
dec8_swedish_nopad_ci, eucjpms_japanese_nopad_ci, eucjpms_nopad_bin, eucjpms_japanese_nopad_ci,
eucjpms_nopad_bin, euckr_korean_nopad_ci, euckr_nopad_bin, gb2312_chinese_nopad_ci,
gb2312_nopad_bin, gbk_chinese_nopad_ci, gbk_nopad_bin, geostd8_general_nopad_ci, geostd8_nopad_bin,
greek_general_nopad_ci, greek_nopad_bin, hebrew_general_nopad_ci, hebrew_nopad_bin,
hp8_english_nopad_ci, hp8_nopad_bin, keybcs2_general_nopad_ci, keybcs2_nopad_bin,
koi8r_general_nopad_ci, koi8r_nopad_bin, koi8u_general_nopad_ci, koi8u_nopad_bin, latin1_nopad_bin,
latin1_swedish_nopad_ci, latin2_general_nopad_ci, latin2_nopad_bin, latin5_nopad_bin, latin5_turkish_ci,
latin5_turkish_nopad_ci, latin7_general_nopad_ci, latin7_nopad_bin, macce_general_nopad_ci,
macce_nopad_bin, macroman_general_nopad_ci, macroman_nopad_bin, sjis_japanese_nopad_ci,
sjis_nopad_bin, swe7_nopad_bin, tis620_thai_nopad_ci, tis620_nopad_bin, ucs2_croatian_mysql561_ci,
ucs2_general_mysql500_ci, ucs2_general_nopad_ci, ucs2_myanmar_ci, ucs2_nopad_bin, ucs2_swedish_ci,
ucs2_thai_520_w2, ucs2_unicode_ci, ucs2_unicode_nopad_ci, ujis_japanese_nopad_ci, ujis_nopad_bin,
utf16le_general_nopad_ci, utf16le_nopad_bin, utf16_croatian_mysql561_ci, utf16_general_nopad_ci,
utf16_myanmar_ci, utf16_nopad_bin, utf16_thai_520_w2, utf16_unicode_520_nopad_ci,
utf16_unicode_nopad_ci, utf32_croatian_mysql561_ci, utf32_general_nopad_ci, utf32_myanmar_ci,
utf32_nopad_bin, utf32_thai_520_w2, utf32_unicode_520_nopad_ci, utf32_unicode_nopad_ci,
utf8mb4_general_nopad_ci, utf8mb4_myanmar_ci, utf8mb4_nopad_bin, utf8mb4_thai_520_w2,
utf8mb4_unicode_520_nopad_ci, utf8mb4_unicode_nopad_ci, utf8_croatian_mysql561_ci,
utf8_general_nopad_ci, utf8_myanmar_ci, utf8_nopad_bin, utf8_thai_520_w2, utf8_unicode_520_nopad_ci,
utf8_unicode_ci and utf8_unicode_nopad_ci being the additional ones).

As of 8.0.25, MySQL supports 41 character sets ( gb18030 being the additional one - MDEV-7495 ) and 272
collations (gb18030_bin, gb18030_chinese_ci, gb18030_unicode_520_ci, utf8mb4_0900_ai_ci,
utf8mb4_0900_as_ci, utf8mb4_0900_as_cs, utf8mb4_0900_bin, utf8mb4_cs_0900_ai_ci,
utf8mb4_cs_0900_as_cs, utf8mb4_da_0900_ai_ci, utf8mb4_da_0900_as_cs, utf8mb4_de_pb_0900_ai_ci,
utf8mb4_de_pb_0900_as_cs, utf8mb4_eo_0900_ai_ci, utf8mb4_eo_0900_as_cs, utf8mb4_es_0900_ai_ci,
utf8mb4_es_0900_as_cs, utf8mb4_es_trad_0900_ai_ci, utf8mb4_es_trad_0900_as_cs, utf8mb4_et_0900_ai_ci,
utf8mb4_et_0900_as_cs, utf8mb4_hr_0900_ai_ci, utf8mb4_hr_0900_as_cs, utf8mb4_hu_0900_ai_ci,
utf8mb4_hu_0900_as_cs, utf8mb4_is_0900_ai_ci, utf8mb4_is_0900_as_cs, utf8mb4_ja_0900_as_cs,
utf8mb4_ja_0900_as_cs_ks, utf8mb4_la_0900_ai_ci, utf8mb4_la_0900_as_cs, utf8mb4_lt_0900_ai_ci,
utf8mb4_lt_0900_as_cs, utf8mb4_lv_0900_ai_ci, utf8mb4_lv_0900_as_cs, utf8mb4_pl_0900_ai_ci,
utf8mb4_pl_0900_as_cs, utf8mb4_ro_0900_ai_ci, utf8mb4_ro_0900_as_cs, utf8mb4_ru_0900_ai_ci,
1660/3812
utf8mb4_ru_0900_as_cs, utf8mb4_sk_0900_ai_ci, utf8mb4_sk_0900_as_cs, utf8mb4_sl_0900_ai_ci,
utf8mb4_sl_0900_as_cs, utf8mb4_sv_0900_ai_ci, utf8mb4_sv_0900_as_cs, utf8mb4_tr_0900_ai_ci,
utf8mb4_vi_0900_ai_ci, utf8mb4_vi_0900_as_cs, utf8mb4_zh_0900_as_cs being the additional ones) - MDEV-
20912 .
To make CREATE TABLE ... SELECT work the same way in statement based and row based replication it's by
default executed as CREATE OR REPLACE TABLE on the slave. One benefit of this is that if the slave dies in
the middle of CREATE ... SELECT it will be able to continue.
One can use the slave-ddl-exec-mode variable to specify how CREATE TABLE and DROP TABLE is
replicated.
Users created with MySQL's SHA256 password algorithm cannot be used in MariaDB 10.6 - MDEV-9804 .
MariaDB 10.6 does not support CIDR notation for user accounts - MDEV-25515 .
MariaDB stores JSON as true text, not in binary format as MySQL. MariaDB's JSON functions are much faster
than MySQL's so there is no need to store in binary format, which would add complexity when manipulating JSON
objects.
For the same reason, MariaDB's JSON data type is an alias for LONGTEXT. If you want to replicate JSON
columns from MySQL to MariaDB, you should store JSON objects in MySQL in a TEXT or LONGTEXT column or
use statement based replication. If you are using JSON columns and want to upgrade to MariaDB, you need to
either convert them to TEXT or use mysqldump to copy these tables to MariaDB. See also Making MariaDB
understand MySQL JSON .
In MySQL, JSON is compared according to json values. In MariaDB JSON strings are normal strings and
compared as strings.
MariaDB 10.6 does not support MySQL's JSON operators ( -> and ->> ) (MDEV-13594 )
MariaDB 10.6 supports the standard by producing null and a warning for JSON_SEARCH when given invalid
data, while MySQL produces an error.
Roles
MariaDB never allows authentication via roles, while MySQL permits this.
MySQL permits activating multiple roles at the same time. MariaDB can achieve the same result by creating
an intermediate aggregate role.
In the INFORMATION_SCHEMA.ENABLED_ROLES table, MySQL reports just the direct list of enabled
roles, while MariaDB reports the enabled role, plus the effective inherited roles.
MySQL extends the INFORMATION_SCHEMA.APPLICABLE_ROLES table .
MySQL includes the tables INFORMATION_SCHEMA.ROLE_TABLE_GRANTS,
INFORMATION_SCHEMA.ROLE_ROUTINE_GRANTS,
INFORMATION_SCHEMA.ROLE_COLUMN_GRANTS, and INFORMATION_SCHEMA
ADMINISTRABLE_ROLE_AUTHORIZATIONS.
MySQL has the performance schema enabled by default. For performance reasons MariaDB 10.6 has it disabled
by default. You can enable it by starting mysqld with the option --performance-schema .
In MariaDB 10.6, using FLUSH TABLES 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, the server will wait for
the end of any transactions that are using the tables. In MySQL, FLUSH TABLES only waits for the statements to
complete.
MariaDB binaries ( mysqld , myisamchk etc.) give a warning if one uses a unique prefix of an option (such as --
big-table instead of --big-tables ). MySQL binaries require the full option name.
MariaDB 10.6 implements InnoDB encryption in a different way to MySQL 8.0.
MySQL's implementation of aborting statements that exceed a certain time to execute can only kill SELECTs,
while MariaDB's can kill any queries (excluding stored procedures).
MariaDB 10.6 does not support MySQL's SELECT /*+ MAX_EXECUTION_TIME(n) */ ... - see Aborting
Statements that Exceed a Certain Time to Execute.
MySQL 8.0 does not support the Query Cache.
MariaDB 10.6 does not support the MySQL Memcached plugin (which has been deprecated in MySQL 8.0).
However, data stored using memcached can be retrieved because the data is stored as InnoDB tables. MariaDB
is able to start successfully with an error message of not being able to find libmemcached.so library.
In MySQL, X'HHHH' , the standard SQL syntax for binary string literals, erroneously works in the same way as
0xHHHH , which could work as a number or string depending on the context. In MariaDB, this has been fixed to
behave as a string in all contexts (and never as a number). See CAST and Hexadecimal Literals for more details
and examples.
In MariaDB 10.6, SHOW CREATE TABLE does not quote the DEFAULT value of an integer. MariaDB 10.2 and
earlier, and MySQL, do. Since MariaDB can support defaults for BLOB and TEXT fields, while MySQL does not,
SHOW CREATE TABLE will also append DEFAULT NULL where no default is explicitly provided to nullable BLOB
or TEXT fields in MariaDB.
Since MariaDB supports INTERSECT and EXCEPT, these are both reserved words and can't be used as an
identifier without being quoted.
As a result of implementing Table Value Constructors, the VALUES function has been renamed to VALUE().
MariaDB's NOWAIT supports SELECT statements, LOCK TABLES and various DDL statements, while MySQL's
NOWAIT only supports SELECT.
MariaDB's NOWAIT cannot be added on views and stored procedures while MySQL's can - MDEV-25247
MariaDB returns an ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction when
unable to lock within the time, while MySQL returns ERROR 3572 (HY000): Statement aborted because lock(s)
could not be acquired immediately and NOWAIT is set
MariaDB 10.6 does not support Lateral Derived Tables - MDEV-19078 .

1661/3812
MariaDB does not support the optional init_vector argument for AES_ENCRYPT and AES_DECRYPT or the
block_encryption_mode variable - MDEV-9069
MariaDB does not support the --initialize option. Use mysql_install_db instead. - MDEV-19010
MariaDB 10.6 does not support the ngram and MeCab full-text parser plugins - MDEV-10267 , MDEV-10268 .
MariaDB 10.6 does not support the MySQL X plugin .
MariaDB 10.6 does not support MySQL 8's “native” InnoDB partitioning handler.
MariaDB 10.6 does not support CREATE TABLESPACE for InnoDB.
The MySQL 8.0 and MariaDB 10.6 INFORMATION_SCHEMA.COLUMNS table contain slightly different fields.
MariaDB 10.6 client executables allow the connection protocol to be forced by specifying only connection
properties on the command-line. See mysql Command-line client
The MySQL binary log includes the thread_id, while MariaDB's binary log does not. (MDEV-7850 )

2.1.14.1.7 Incompatibilities and Feature


Differences Between MariaDB 10.5 and MySQL
8.0
Contents
1. Storage Engines
2. Extensions and New Features
3. Incompatibilities

MariaDB maintains high levels of compatibility with MySQL, and most applications that use MySQL will work seamlessly
with MariaDB. However, take note of the following incompatibilities and feature differences between MariaDB 10.5 and
MySQL 8.0. It is based on the stable versions MySQL 8.0.22 and MariaDB 10.5.6. Note that MySQL 8 is an 'evergreen'
release, so features may be added or removed in later releases.

Storage Engines
In addition to the standard InnoDB, MyISAM, BLACKHOLE, CSV, MEMORY, ARCHIVE, and MERGE storage engines,
the following are also available with MariaDB 10.5:
ColumnStore utilizes a massively parallel distributed data architecture and is designed for big data scaling to
process petabytes of data.
MyRocks, a storage engine with great compression
S3 storage engine allows one to archive MariaDB tables in Amazon S3, or any third-party public or private cloud
that implements S3 API.
Aria, MyISAM replacement with better caching.
CONNECT
SEQUENCE
Spider
SphinxSE
FederatedX (drop-in replacement for Federated)
OQGRAPH

Extensions and New Features


The most notable features available in MariaDB , but not in MySQL, are:
Galera is a standard part of MariaDB Server.
Temporal data tables in the form of:
System-versioned tables (allow you to query and operate on historic data).
Application-time periods (allow you to query and operate on a temporal range of data), including the
WITHOUT OVERLAPS clause added in 10.5.
Bitemporal tables (which combine both system-versioning and application-time periods).
DML-only flashback, allowing instances, databases or tables to be rolled back to an old snapshot.
Oracle compatibility mode
Sequences
Invisible Columns
Table Value Constructors
Dynamic Columns support
Semi-sync plugin merged into the server
INTERSECT/INTERSECT ALL and EXCEPT/EXCEPT ALL
OR REPLACE syntax for CREATE statements, such as CREATE OR REPLACE TABLE, CREATE OR REPLACE
DATABASE, etc
DELETE ... RETURNING, INSERT ... RETURNING, REPLACE ... RETURNING
WAIT syntax for setting the lock wait timeout.
INET6 data type for storing IPv6 addresses.
SUPER privileges made more granular.
1662/3812
PROXY protocol support
Number of supported decimals in DECIMAL has increased from 30 to 38
Added catchall for list partitions
Oracle-style EXECUTE IMMEDIATE statement
Lots of new JSON functions
Microsecond Precision in Processlist
Table Elimination
Virtual Columns
Extended User Statistics
KILL all queries for a user
Storage-engine-specific CREATE TABLE
MariaDB supports more collations than MySQL, including NO PAD collations.
FLUSH SSL command to reload SSL certificates without server restart.
IF NOT EXISTS clause added to INSTALL PLUGIN and IF EXISTS clause added to UNINSTALL PLUGIN and
UNINSTALL SONAME
Enhancements to INFORMATION SCHEMA.PLUGINS table
Group commit for the binary log. This makes replication notably faster!
The binary log in MariaDB can be compressed.
BACKUP STAGE allows one to implement very efficient backups with minimal locking.
Progress reporting for ALTER TABLE and LOAD DATA INFILE
SHOW EXPLAIN gives the EXPLAIN plan for a query running in another thread. MySQL introduced the EXPLAIN
FOR CONNECTION syntax to do the same thing.
PCRE Regular Expressions (including REGEXP_REPLACE())
HandlerSocket and faster HANDLER calls

Incompatibilities
When moving from MySQL 8.0 to MariaDB 10.5, please take note of the following incompatibilities:
For a list of function differences, see Function Differences Between MariaDB 10.5 and MySQL 8.0
For a list of system variable differences, see System Variable Differences Between MariaDB 10.5 and MySQL 8.0
MariaDB's GTID is not compatible with MySQL's. Note that MariaDB and MySQL also have different GTID system
variables, so these need to be adjusted when migrating.
The unix_socket authentication plugin is now default on Unix-like systems, which is a major change to
authentication in MariaDB. See Authentication from MariaDB 10.4 for an overview of the changes.
All mysql* binaries are now named mariadb* (the previous mysql named is retained as a symlink for compatibility
purposes)
Not all character sets and collations are supported across both MySQL and MariaDB. As of 10.5.4, MariaDB
supports 40 character sets and 322 collations (armscii8_general_nopad_ci, armscii8_nopad_bin,
ascbig5_chinese_nopad_ci, big5_nopad_bin, iicp1250_general_nopad_ci, cp1250_nopad_bin,
cp1250_general_nopad_ci, cp1250_nopad_bin, cp1251_general_nopad_ci, cp1251_nopad_bin,
cp1256_general_nopad_ci, cp1256_nopad_bin, cp1257_general_nopad_ci, cp1257_nopad_bin,
cp850_general_nopad_ci, cp850_nopad_bin, cp852_general_nopad_ci, cp852_nopad_bin,
cp866_general_nopad_ci, cp866_nopad_bin, cp932_japanese_nopad_ci, cp932_nopad_bin, dec8_nopad_bin,
dec8_swedish_nopad_ci, eucjpms_japanese_nopad_ci, eucjpms_nopad_bin, eucjpms_japanese_nopad_ci,
eucjpms_nopad_bin, euckr_korean_nopad_ci, euckr_nopad_bin, gb2312_chinese_nopad_ci,
gb2312_nopad_bin, gbk_chinese_nopad_ci, gbk_nopad_bin, geostd8_general_nopad_ci, geostd8_nopad_bin,
greek_general_nopad_ci, greek_nopad_bin, hebrew_general_nopad_ci, hebrew_nopad_bin,
hp8_english_nopad_ci, hp8_nopad_bin, keybcs2_general_nopad_ci, keybcs2_nopad_bin,
koi8r_general_nopad_ci, koi8r_nopad_bin, koi8u_general_nopad_ci, koi8u_nopad_bin, latin1_nopad_bin,
latin1_swedish_nopad_ci, latin2_general_nopad_ci, latin2_nopad_bin, latin5_nopad_bin, latin5_turkish_ci,
latin5_turkish_nopad_ci, latin7_general_nopad_ci, latin7_nopad_bin, macce_general_nopad_ci,
macce_nopad_bin, macroman_general_nopad_ci, macroman_nopad_bin, sjis_japanese_nopad_ci,
sjis_nopad_bin, swe7_nopad_bin, tis620_thai_nopad_ci, tis620_nopad_bin, ucs2_croatian_mysql561_ci,
ucs2_general_mysql500_ci, ucs2_general_nopad_ci, ucs2_myanmar_ci, ucs2_nopad_bin, ucs2_swedish_ci,
ucs2_thai_520_w2, ucs2_unicode_ci, ucs2_unicode_nopad_ci, ujis_japanese_nopad_ci, ujis_nopad_bin,
utf16le_general_nopad_ci, utf16le_nopad_bin, utf16_croatian_mysql561_ci, utf16_general_nopad_ci,
utf16_myanmar_ci, utf16_nopad_bin, utf16_thai_520_w2, utf16_unicode_520_nopad_ci,
utf16_unicode_nopad_ci, utf32_croatian_mysql561_ci, utf32_general_nopad_ci, utf32_myanmar_ci,
utf32_nopad_bin, utf32_thai_520_w2, utf32_unicode_520_nopad_ci, utf32_unicode_nopad_ci,
utf8mb4_general_nopad_ci, utf8mb4_myanmar_ci, utf8mb4_nopad_bin, utf8mb4_thai_520_w2,
utf8mb4_unicode_520_nopad_ci, utf8mb4_unicode_nopad_ci, utf8_croatian_mysql561_ci,
utf8_general_nopad_ci, utf8_myanmar_ci, utf8_nopad_bin, utf8_thai_520_w2, utf8_unicode_520_nopad_ci,
utf8_unicode_ci and utf8_unicode_nopad_ci being the additional ones).

As of 8.0.21, MySQL supports 41 character sets ( gb18030 being the additional one) and 272 collations
(gb18030_bin, gb18030_chinese_ci, gb18030_unicode_520_ci, utf8mb4_0900_ai_ci, utf8mb4_0900_as_ci,
utf8mb4_0900_as_cs, utf8mb4_0900_bin, utf8mb4_cs_0900_ai_ci, utf8mb4_cs_0900_as_cs,
utf8mb4_da_0900_ai_ci, utf8mb4_da_0900_as_cs, utf8mb4_de_pb_0900_ai_ci, utf8mb4_de_pb_0900_as_cs,
utf8mb4_eo_0900_ai_ci, utf8mb4_eo_0900_as_cs, utf8mb4_es_0900_ai_ci, utf8mb4_es_0900_as_cs,
utf8mb4_es_trad_0900_ai_ci, utf8mb4_es_trad_0900_as_cs, utf8mb4_et_0900_ai_ci, utf8mb4_et_0900_as_cs,
1663/3812
utf8mb4_hr_0900_ai_ci, utf8mb4_hr_0900_as_cs, utf8mb4_hu_0900_ai_ci, utf8mb4_hu_0900_as_cs,
utf8mb4_is_0900_ai_ci, utf8mb4_is_0900_as_cs, utf8mb4_ja_0900_as_cs, utf8mb4_ja_0900_as_cs_ks,
utf8mb4_la_0900_ai_ci, utf8mb4_la_0900_as_cs, utf8mb4_lt_0900_ai_ci, utf8mb4_lt_0900_as_cs,
utf8mb4_lv_0900_ai_ci, utf8mb4_lv_0900_as_cs, utf8mb4_pl_0900_ai_ci, utf8mb4_pl_0900_as_cs,
utf8mb4_ro_0900_ai_ci, utf8mb4_ro_0900_as_cs, utf8mb4_ru_0900_ai_ci, utf8mb4_ru_0900_as_cs,
utf8mb4_sk_0900_ai_ci, utf8mb4_sk_0900_as_cs, utf8mb4_sl_0900_ai_ci, utf8mb4_sl_0900_as_cs,
utf8mb4_sv_0900_ai_ci, utf8mb4_sv_0900_as_cs, utf8mb4_tr_0900_ai_ci, utf8mb4_vi_0900_ai_ci,
utf8mb4_vi_0900_as_cs, utf8mb4_zh_0900_as_cs being the additional ones).
To make CREATE TABLE ... SELECT work the same way in statement based and row based replication it's by
default executed as CREATE OR REPLACE TABLE on the slave. One benefit of this is that if the slave dies in
the middle of CREATE ... SELECT it will be able to continue.
One can use the slave-ddl-exec-mode variable to specify how CREATE TABLE and DROP TABLE is
replicated.
Users created with MySQL's SHA256 password algorithm cannot be used in MariaDB 10.5 - MDEV-9804 .
MariaDB stores JSON as true text, not in binary format as MySQL. MariaDB's JSON functions are much faster
than MySQL's so there is no need to store in binary format, which would add complexity when manipulating JSON
objects.
For the same reason, MariaDB's JSON data type is an alias for LONGTEXT. If you want to replicate JSON
columns from MySQL to MariaDB, you should store JSON objects in MySQL in a TEXT or LONGTEXT column or
use statement based replication. If you are using JSON columns and want to upgrade to MariaDB, you need to
either convert them to TEXT or use mysqldump to copy these tables to MariaDB. See also Making MariaDB
understand MySQL JSON .
In MySQL, JSON is compared according to json values. In MariaDB JSON strings are normal strings and
compared as strings.
MariaDB 10.5 does not support MySQL's JSON operators ( -> and ->> ) (MDEV-13594 )
MariaDB 10.5 supports the standard by producing null and a warning for JSON_SEARCH when given invalid
data, while MySQL produces an error.
Roles
MariaDB never allows authentication via roles, while MySQL permits this.
MySQL permits activating multiple roles at the same time. MariaDB can achieve the same result by creating
an intermediate aggregate role.
In the INFORMATION_SCHEMA.ENABLED_ROLES table, MySQL reports just the direct list of enabled
roles, while MariaDB reports the enabled role, plus the effective inherited roles.
MySQL extends the INFORMATION_SCHEMA.APPLICABLE_ROLES table .
MySQL includes the tables INFORMATION_SCHEMA.ROLE_TABLE_GRANTS,
INFORMATION_SCHEMA.ROLE_ROUTINE_GRANTS,
INFORMATION_SCHEMA.ROLE_COLUMN_GRANTS, and INFORMATION_SCHEMA
ADMINISTRABLE_ROLE_AUTHORIZATIONS.
MySQL has the performance schema enabled by default. For performance reasons MariaDB 10.5 has it disabled
by default. You can enable it by starting mysqld with the option --performance-schema .
In MariaDB 10.5, using FLUSH TABLES 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, the server will wait for
the end of any transactions that are using the tables. In MySQL, FLUSH TABLES only waits for the statements to
complete.
MariaDB binaries ( mysqld , myisamchk etc.) give a warning if one uses a unique prefix of an option (such as --
big-table instead of --big-tables ). MySQL binaries require the full option name.
MariaDB 10.5 implements InnoDB encryption in a different way to MySQL 8.0.
MySQL's implementation of aborting statements that exceed a certain time to execute can only kill SELECTs,
while MariaDB's can kill any queries (excluding stored procedures).
MariaDB 10.5 does not support MySQL's SELECT /*+ MAX_EXECUTION_TIME(n) */ ... - see Aborting
Statements that Exceed a Certain Time to Execute.
MySQL 8.0 does not support the Query Cache.
MariaDB 10.5 does not support the MySQL Memcached plugin (which has been deprecated in MySQL 8.0).
However, data stored using memcached can be retrieved because the data is stored as InnoDB tables. MariaDB
is able to start successfully with an error message of not being able to find libmemcached.so library.
In MySQL, X'HHHH' , the standard SQL syntax for binary string literals, erroneously works in the same way as
0xHHHH , which could work as a number or string depending on the context. In MariaDB, this has been fixed to
behave as a string in all contexts (and never as a number). See CAST and Hexadecimal Literals for more details
and examples.
In MariaDB 10.5, SHOW CREATE TABLE does not quote the DEFAULT value of an integer. MariaDB 10.2 and
earlier, and MySQL, do. Since MariaDB can support defaults for BLOB and TEXT fields, while MySQL does not,
SHOW CREATE TABLE will also append DEFAULT NULL where no default is explicitly provided to nullable BLOB
or TEXT fields in MariaDB.
Since MariaDB supports INTERSECT and EXCEPT, these are both reserved words and can't be used as an
identifier without being quoted.
As a result of implementing Table Value Constructors, the VALUES function has been renamed to VALUE().
MariaDB's NOWAIT supports SELECT statements, LOCK TABLES and various DDL statements, while MySQL's
NOWAIT only supports SELECT.
MariaDB's NOWAIT cannot be added on views and stored procedures while MySQL's can - MDEV-25247
MariaDB returns an ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction when

1664/3812
unable to lock within the time, while MySQL returns ERROR 3572 (HY000): Statement aborted because lock(s)
could not be acquired immediately and NOWAIT is set
MariaDB 10.5 does not support Lateral Derived Tables - MDEV-19078 .
MariaDB does not support the optional init_vector argument for AES_ENCRYPT and AES_DECRYPT or the
block_encryption_mode variable - MDEV-9069
MariaDB does not support the --initialize option. Use mysql_install_db instead. - MDEV-19010
MariaDB 10.5 does not support the ngram and MeCab full-text parser plugins - MDEV-10267 , MDEV-10268 .
MariaDB 10.5 does not support the MySQL X plugin .
MariaDB 10.5 does not support MySQL 8's “native” InnoDB partitioning handler.
MariaDB 10.5 does not support CREATE TABLESPACE for InnoDB.
The MySQL 8.0 and MariaDB 10.5 INFORMATION_SCHEMA.COLUMNS table contain slightly different fields.
The MySQL binary log includes the thread_id, while MariaDB's binary log does not. (MDEV-7850 )
Also see Incompatibilities between MariaDB 10.4 and MySQL 8.0 and Incompatibilities between MariaDB 10.3
and MySQL 5.7.

2.1.14.1.8 Incompatibilities and Feature


Differences Between MariaDB 10.4 and MySQL
8.0
Contents
1. Storage Engines
2. Extensions and New Features
3. Incompatibilities

MariaDB maintains high levels of compatibility with MySQL, and most applications that use MySQL will work seamlessly
with MariaDB. However, take note of the following incompatibilities and feature differences between MariaDB 10.4 and
MySQL 8.0. It is based on the stable versions MySQL 8.0.22 and MariaDB 10.4.15. Note that MySQL 8 is an
'evergreen' release, so features may be added or removed in later releases.

Storage Engines
In addition to the standard InnoDB, MyISAM, BLACKHOLE, CSV, MEMORY, ARCHIVE, and MERGE storage engines,
the following are also available with MariaDB 10.4:
MyRocks, a storage engine with great compression
Aria, MyISAM replacement with better caching.
CONNECT
SEQUENCE
Spider
SphinxSE
TokuDB
FederatedX (drop-in replacement for Federated)
OQGRAPH

Extensions and New Features


The most notable features available in MariaDB , but not in MySQL, are:
Galera is a standard part of MariaDB Server.
Temporal data tables in the form of:
System-versioned tables (allow you to query and operate on historic data).
Application-time periods (allow you to query and operate on a temporal range of data).
Bitemporal tables (which combine both system-versioning and application-time periods).
DML-only flashback, allowing instances, databases or tables to be rolled back to an old snapshot.
Oracle compatibility mode
Sequences
Invisible Columns
Table Value Constructors
Semi-sync plugin merged into the server
INTERSECT and EXCEPT
OR REPLACE syntax for CREATE statements, such as CREATE OR REPLACE TABLE, CREATE OR REPLACE
DATABASE, etc
DELETE ... RETURNING
WAIT syntax for setting the lock wait timeout.
PROXY protocol support
Number of supported decimals in DECIMAL has increased from 30 to 38
Added catchall for list partitions
1665/3812
Oracle-style EXECUTE IMMEDIATE statement
Lots of new JSON functions
Microsecond Precision in Processlist
Table Elimination
Virtual Columns
Extended User Statistics
KILL all queries for a user
Storage-engine-specific CREATE TABLE
MariaDB supports more collations than MySQL, including NO PAD collations.
FLUSH SSL command to reload SSL certificates without server restart.
IF NOT EXISTS clause added to INSTALL PLUGIN and IF EXISTS clause added to UNINSTALL PLUGIN and
UNINSTALL SONAME
Enhancements to INFORMATION SCHEMA.PLUGINS table
Group commit for the binary log. This makes replication notably faster!
The binary log in MariaDB can be compressed.
New server command, SHUTDOWN WAIT FOR ALL SLAVES, and a new mysqladmin shutdown --wait-for-all-
slaves option, are added to instruct the server to wait for the last binlog event to be sent to all connected slaves
before shutting down.
BACKUP STAGE allows one to implement very efficient backups with minimal locking.
Progress reporting for ALTER TABLE and LOAD DATA INFILE
SHOW EXPLAIN gives the EXPLAIN plan for a query running in another thread. MySQL introduced the EXPLAIN
FOR CONNECTION syntax to do the same thing.
PCRE Regular Expressions (including REGEXP_REPLACE())
HandlerSocket and faster HANDLER calls

Incompatibilities
When moving from MySQL 8.0 to MariaDB 10.4, please take note of the following incompatibilities:
For a list of function differences, see Function Differences Between MariaDB 10.4 and MySQL 8.0
For a list of system variable differences, see System Variable Differences Between MariaDB 10.4 and MySQL 8.0
MariaDB's GTID is not compatible with MySQL's. Note that MariaDB and MySQL also have different GTID system
variables, so these need to be adjusted when migrating.
The unix_socket authentication plugin is now default on Unix-like systems, which is a major change to
authentication in MariaDB. See Authentication from MariaDB 10.4 for an overview of the changes.
Not all character sets and collations are supported across both MySQL and MariaDB. As of 10.4.14, MariaDB
supports 40 character sets and 322 collations (armscii8_general_nopad_ci, armscii8_nopad_bin,
ascbig5_chinese_nopad_ci, big5_nopad_bin, iicp1250_general_nopad_ci, cp1250_nopad_bin,
cp1250_general_nopad_ci, cp1250_nopad_bin, cp1251_general_nopad_ci, cp1251_nopad_bin,
cp1256_general_nopad_ci, cp1256_nopad_bin, cp1257_general_nopad_ci, cp1257_nopad_bin,
cp850_general_nopad_ci, cp850_nopad_bin, cp852_general_nopad_ci, cp852_nopad_bin,
cp866_general_nopad_ci, cp866_nopad_bin, cp932_japanese_nopad_ci, cp932_nopad_bin, dec8_nopad_bin,
dec8_swedish_nopad_ci, eucjpms_japanese_nopad_ci, eucjpms_nopad_bin, eucjpms_japanese_nopad_ci,
eucjpms_nopad_bin, euckr_korean_nopad_ci, euckr_nopad_bin, gb2312_chinese_nopad_ci,
gb2312_nopad_bin, gbk_chinese_nopad_ci, gbk_nopad_bin, geostd8_general_nopad_ci, geostd8_nopad_bin,
greek_general_nopad_ci, greek_nopad_bin, hebrew_general_nopad_ci, hebrew_nopad_bin,
hp8_english_nopad_ci, hp8_nopad_bin, keybcs2_general_nopad_ci, keybcs2_nopad_bin,
koi8r_general_nopad_ci, koi8r_nopad_bin, koi8u_general_nopad_ci, koi8u_nopad_bin, latin1_nopad_bin,
latin1_swedish_nopad_ci, latin2_general_nopad_ci, latin2_nopad_bin, latin5_nopad_bin, latin5_turkish_ci,
latin5_turkish_nopad_ci, latin7_general_nopad_ci, latin7_nopad_bin, macce_general_nopad_ci,
macce_nopad_bin, macroman_general_nopad_ci, macroman_nopad_bin, sjis_japanese_nopad_ci,
sjis_nopad_bin, swe7_nopad_bin, tis620_thai_nopad_ci, tis620_nopad_bin, ucs2_croatian_mysql561_ci,
ucs2_general_mysql500_ci, ucs2_general_nopad_ci, ucs2_myanmar_ci, ucs2_nopad_bin, ucs2_swedish_ci,
ucs2_thai_520_w2, ucs2_unicode_ci, ucs2_unicode_nopad_ci, ujis_japanese_nopad_ci, ujis_nopad_bin,
utf16le_general_nopad_ci, utf16le_nopad_bin, utf16_croatian_mysql561_ci, utf16_general_nopad_ci,
utf16_myanmar_ci, utf16_nopad_bin, utf16_thai_520_w2, utf16_unicode_520_nopad_ci,
utf16_unicode_nopad_ci, utf32_croatian_mysql561_ci, utf32_general_nopad_ci, utf32_myanmar_ci,
utf32_nopad_bin, utf32_thai_520_w2, utf32_unicode_520_nopad_ci, utf32_unicode_nopad_ci,
utf8mb4_general_nopad_ci, utf8mb4_myanmar_ci, utf8mb4_nopad_bin, utf8mb4_thai_520_w2,
utf8mb4_unicode_520_nopad_ci, utf8mb4_unicode_nopad_ci, utf8_croatian_mysql561_ci,
utf8_general_nopad_ci, utf8_myanmar_ci, utf8_nopad_bin, utf8_thai_520_w2, utf8_unicode_520_nopad_ci,
utf8_unicode_ci and utf8_unicode_nopad_ci being the additional ones).

As of 8.0.21, MySQL supports 41 character sets (gb18030 being the additional one) and 272 collations
(gb18030_bin, gb18030_chinese_ci, gb18030_unicode_520_ci, utf8mb4_0900_ai_ci, utf8mb4_0900_as_ci,
utf8mb4_0900_as_cs, utf8mb4_0900_bin, utf8mb4_cs_0900_ai_ci, utf8mb4_cs_0900_as_cs,
utf8mb4_da_0900_ai_ci, utf8mb4_da_0900_as_cs, utf8mb4_de_pb_0900_ai_ci, utf8mb4_de_pb_0900_as_cs,
utf8mb4_eo_0900_ai_ci, utf8mb4_eo_0900_as_cs, utf8mb4_es_0900_ai_ci, utf8mb4_es_0900_as_cs,
utf8mb4_es_trad_0900_ai_ci, utf8mb4_es_trad_0900_as_cs, utf8mb4_et_0900_ai_ci, utf8mb4_et_0900_as_cs,
utf8mb4_hr_0900_ai_ci, utf8mb4_hr_0900_as_cs, utf8mb4_hu_0900_ai_ci, utf8mb4_hu_0900_as_cs,
utf8mb4_is_0900_ai_ci, utf8mb4_is_0900_as_cs, utf8mb4_ja_0900_as_cs, utf8mb4_ja_0900_as_cs_ks,
1666/3812
utf8mb4_la_0900_ai_ci, utf8mb4_la_0900_as_cs, utf8mb4_lt_0900_ai_ci, utf8mb4_lt_0900_as_cs,
utf8mb4_lv_0900_ai_ci, utf8mb4_lv_0900_as_cs, utf8mb4_pl_0900_ai_ci, utf8mb4_pl_0900_as_cs,
utf8mb4_ro_0900_ai_ci, utf8mb4_ro_0900_as_cs, utf8mb4_ru_0900_ai_ci, utf8mb4_ru_0900_as_cs,
utf8mb4_sk_0900_ai_ci, utf8mb4_sk_0900_as_cs, utf8mb4_sl_0900_ai_ci, utf8mb4_sl_0900_as_cs,
utf8mb4_sv_0900_ai_ci, utf8mb4_sv_0900_as_cs, utf8mb4_tr_0900_ai_ci, utf8mb4_vi_0900_ai_ci,
utf8mb4_vi_0900_as_cs, utf8mb4_zh_0900_as_cs being the additional ones).
To make CREATE TABLE ... SELECT work the same way in statement based and row based replication it's by
default executed as CREATE OR REPLACE TABLE on the slave. One benefit of this is that if the slave dies in
the middle of CREATE ... SELECT it will be able to continue.
One can use the slave-ddl-exec-mode variable to specify how CREATE TABLE and DROP TABLE is
replicated.
Users created with MySQL's SHA256 password algorithm cannot be used in MariaDB 10.4 - MDEV-9804 .
MariaDB stores JSON as true text, not in binary format as MySQL. MariaDB's JSON functions are much faster
than MySQL's so there is no need to store in binary format, which would add complexity when manipulating JSON
objects.
For the same reason, MariaDB's JSON data type is an alias for LONGTEXT. If you want to replicate JSON
columns from MySQL to MariaDB, you should store JSON objects in MySQL in a TEXT or LONGTEXT column or
use statement based replication. If you are using JSON columns and want to upgrade to MariaDB, you need to
either convert them to TEXT or use mysqldump to copy these tables to MariaDB.
In MySQL, JSON is compared according to json values. In MariaDB JSON strings are normal strings and
compared as strings.
MariaDB 10.4 does not support MySQL's JSON operators ( -> and ->> ) (MDEV-13594 )
MariaDB 10.4 supports the standard by producing null and a warning for JSON_SEARCH when given invalid
data, while MySQL produces an error.
Roles
MariaDB never allows authentication via roles, while MySQL permits this.
MySQL permits activating multiple roles at the same time. MariaDB can achieve the same result by creating
an intermediate aggregate role.
In the INFORMATION_SCHEMA.ENABLED_ROLES table, MySQL reports just the direct list of enabled
roles, while MariaDB reports the enabled role, plus the effective inherited roles.
MySQL extends the INFORMATION_SCHEMA.APPLICABLE_ROLES table .
MySQL includes the tables INFORMATION_SCHEMA.ROLE_TABLE_GRANTS,
INFORMATION_SCHEMA.ROLE_ROUTINE_GRANTS,
INFORMATION_SCHEMA.ROLE_COLUMN_GRANTS, and INFORMATION_SCHEMA
ADMINISTRABLE_ROLE_AUTHORIZATIONS.
MySQL has the performance schema enabled by default. For performance reasons MariaDB 10.4 has it disabled
by default. You can enable it by starting mysqld with the option --performance-schema .
MySQL features a new implementation of the performance_schema and a sys schema wrapper. These are only
supported in MariaDB 10.5.
In MariaDB 10.4, using FLUSH TABLES 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, the server will wait for
the end of any transactions that are using the tables. In MySQL, FLUSH TABLES only waits for the statements to
complete.
MariaDB binaries ( mysqld , myisamchk etc.) give a warning if one uses a unique prefix of an option (such as --
big-table instead of --big-tables ). MySQL binaries require the full option name.
MariaDB 10.4 implements InnoDB encryption in a different way to MySQL 8.0.
MySQL's implementation of aborting statements that exceed a certain time to execute can only kill SELECTs,
while MariaDB's can kill any queries (excluding stored procedures).
MariaDB 10.4 does not support MySQL's SELECT /*+ MAX_EXECUTION_TIME(n) */ ... - see Aborting
Statements that Exceed a Certain Time to Execute.
MySQL 8.0 does not support the Query Cache.
MariaDB 10.4 does not support the MySQL Memcached plugin (which has been deprecated in MySQL 8.0).
However, data stored using memcached can be retrieved because the data is stored as InnoDB tables. MariaDB
is able to start successfully with an error message of not being able to find libmemcached.so library.
MariaDB 10.4 does not support MySQL 8.0's ALTER TABLE...RENAME INDEX statements (supported in
MariaDB 10.5).
In MySQL, X'HHHH' , the standard SQL syntax for binary string literals, erroneously works in the same way as
0xHHHH , which could work as a number or string depending on the context. In MariaDB, this has been fixed to
behave as a string in all contexts (and never as a number). See CAST and Hexadecimal Literals for more details
and examples.
In MariaDB 10.4, SHOW CREATE TABLE does not quote the DEFAULT value of an integer. MariaDB 10.2 and
earlier, and MySQL, do. Since MariaDB can support defaults for BLOB and TEXT fields, while MySQL does not,
SHOW CREATE TABLE will also append DEFAULT NULL where no default is explicitly provided to nullable BLOB
or TEXT fields in MariaDB.
Since MariaDB supports INTERSECT and EXCEPT, these are both reserved words and can't be used as an
identifier without being quoted.
As a result of implementing Table Value Constructors, the VALUES function has been renamed to VALUE().
MariaDB's NOWAIT supports SELECT statements, LOCK TABLES and various DDL statements, while MySQL's
NOWAIT only supports SELECT.
MariaDB's NOWAIT cannot be added on views and stored procedures while MySQL's can - MDEV-25247

1667/3812
MariaDB returns an ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction when
unable to lock within the time, while MySQL returns ERROR 3572 (HY000): Statement aborted because lock(s)
could not be acquired immediately and NOWAIT is set
MariaDB 10.4 does not support Lateral Derived Tables - MDEV-19078 .
MariaDB does not support the optional init_vector argument for AES_ENCRYPT and AES_DECRYPT or the
block_encryption_mode variable - MDEV-9069
MySQL supports SKIP LOCKED , while MariaDB doesn't.
MariaDB does not support the --initialize option. Use mysql_install_db instead. - MDEV-19010
MariaDB 10.4 does not support the ngram and MeCab full-text parser plugins - MDEV-10267 , MDEV-10268 .
MariaDB 10.4 does not support the MySQL X plugin .
MariaDB 10.4 does not support MySQL 8's “native” InnoDB partitioning handler.
MariaDB 10.4 does not support CREATE TABLESPACE for InnoDB.
The MySQL 8.0 and MariaDB 10.4 INFORMATION_SCHEMA.COLUMNS table contain slightly different fields.
The MySQL binary log includes the thread_id, while MariaDB's binary log does not. (MDEV-7850 )
Also see Incompatibilities between MariaDB 10.3 and MySQL 5.7 and Incompatibilities between MariaDB 10.2
and MySQL 5.7 .

2.1.14.1.9 Incompatibilities and Feature


Differences Between MariaDB 10.3 and MySQL
5.7
Contents
1. Storage Engines
2. Speed Improvements
3. Extensions and New Features
4. Incompatibilities

MariaDB maintains high levels of compatibility with MySQL, and most applications that use MySQL will work seamlessly
with MariaDB. However, take note of the following incompatibilities and feature differences between MariaDB 10.3 and
MySQL 5.7

Storage Engines
In addition to the standard InnoDB, MyISAM, BLACKHOLE, CSV, MEMORY, ARCHIVE, and MERGE storage engines,
the following are also available with MariaDB 10.3:
MyRocks, a storage engine with great compression
Aria, MyISAM replacement with better caching.
TokuDB
CONNECT
SEQUENCE
SphinxSE
Spider
FederatedX (drop-in replacement for Federated)
OQGRAPH

Speed Improvements
Many optimizer enhancements. Subqueries are more usable. The complete list and a comparison with MySQL is
here .
Instant ADD COLUMN
DDL Fast Fail - WAIT/NOWAIT
Faster and safer replication: Group commit for the binary log. This makes many setups that use replication and
lots of updates more than 2x times faster .
Improvements for Innodb asynchronous IO subsystem on Windows.
Segmented Key Cache for MyISAM. Can speed up MyISAM tables with up to 4x
Adjustable hash size for MyISAM and Aria. This can greatly improve shutdown time (from hours to minutes) if you
are using a lot of MyISAM/Aria tables with delayed keys.
CHECKSUM TABLE is faster.
We improved the performance of character set conversions (and removed conversions when they were not really
needed). Overall speed improvement is 1-5 % (according to sql-bench) but can be higher for big result sets with
all characters between 0x00-0x7f.
MariaDB Thread pool allows MariaDB to run with 200,000+ connections and with a notable speed improvement
when using many connections.
Lots of speed improvements when a client connects to MariaDB.
There are some improvements to the DBUG code to make its execution faster when debug is compiled in but not
used.
1668/3812
Our use of the Aria storage engine enables faster complex queries (queries which normally use disk-based
temporary tables). The Aria storage engine is used for internal temporary tables, which should give a speedup
when doing complex selects. Aria is usually faster for temporary tables when compared to MyISAM because Aria
caches row data in memory and normally doesn't have to write the temporary rows to disk.
The test suite has been extended and faster than before, even though it tests more things.

Extensions and New Features


We've added a lot of new features to MariaDB . If a patch or feature is useful, safe, and stable — we make every effort
to include it in MariaDB. The most notable features are:
Galera is a standard part of MariaDB Server.
System-versioned tables (also known as AS OF)
DML-only flashback, allowing instances, databases or tables to be rolled back to an old snapshot.
Oracle compatibility mode
Sequences
Invisible Columns
Table Value Constructors
Semi-sync plugin merged into the server
INTERSECT and EXCEPT.
PROXY protocol support
Window functions
Number of supported decimals in DECIMAL has increased from 30 to 38
Recursive Common Table Expressions
New WITH statement. WITH is a common table expression that allows you to refer to a subquery expression
many times in a query.
CHECK CONSTRAINT
DEFAULT expression, including DEFAULT for BLOB and TEXT
Added catchall for list partitions
Oracle-style EXECUTE IMMEDIATE statement
Lots of new JSON functions
Microsecond Precision in Processlist
Table Elimination
Virtual Columns
Extended User Statistics
KILL all queries for a user
KILL QUERY ID - terminates the query by query_id, leaving the connection intact
Pluggable Authentication
Storage-engine-specific CREATE TABLE
Enhancements to INFORMATION SCHEMA.PLUGINS table
Group commit for the binary log. This makes replication notably faster!
The binary log in MariaDB can be compressed.
Progress reporting for ALTER TABLE and LOAD DATA INFILE
Faster joins and subqueries
HandlerSocket and faster HANDLER calls
Dynamic Columns support
SHOW EXPLAIN gives the EXPLAIN plan for a query running in another thread. MySQL introduced the EXPLAIN
FOR CONNECTION syntax to do the same thing.
Roles
PCRE Regular Expressions (including REGEXP_REPLACE())
OR REPLACE syntax for CREATE statements, such as CREATE OR REPLACE TABLE, CREATE OR REPLACE
DATABASE, etc.
DELETE ... RETURNING
MariaDB supports expressions in the DEFAULT clause, while MySQL does not.
MariaDB supports more collations than MySQL, including NO PAD collations.

Incompatibilities
When upgrading from MySQL 5.7 to MariaDB 10.3, please take note of the following incompatibilities:
For a list of function differences, see Function Differences Between MariaDB 10.3 and MySQL 5.7
For a list of system variable differences, see System Variable Differences Between MariaDB 10.3 and MySQL 5.7
MariaDB binaries ( mysqld , myisamchk etc.) give a warning if one uses a unique prefix of an option (such as --
big-table instead of --big-tables ). MySQL binaries require the full option name.
MariaDB's GTID is not compatible with MySQL's. This means that one can't have MySQL 5.7 as a slave for
MariaDB 10.3. However MariaDB 10.3 can be a slave of MySQL 5.7 or any earlier MySQL/MariaDB version.
Note that MariaDB and MySQL also have different GTID system variables, so these need to be adjusted when
migrating.
To make CREATE TABLE ... SELECT work the same way in statement based and row based replication it's by
default executed as CREATE OR REPLACE TABLE on the slave. One benefit of this is that if the slave dies in
the middle of CREATE ... SELECT it will be able to continue.
1669/3812
One can use the slave-ddl-exec-mode variable to specify how CREATE TABLE and DROP TABLE is
replicated.
MySQL has the performance schema enabled by default. For performance reasons MariaDB 10.3 has it disabled
by default. You can enable it by starting mysqld with the option --performance-schema .
MySQL 5.7 features a new implementation of the performance_schema and a sys schema wrapper. These are
not yet supported in MariaDB.
MariaDB 10.3 implements InnoDB encryption in a different way to MySQL 5.7.
MariaDB 10.3 does not support CREATE TABLESPACE for InnoDB.
The OVER, ROWS and RECURSIVE keywords are reserved words in MariaDB 10.3, but not in MySQL 5.7. Note
that in MySQL 8.0 these are also reserved words.
MariaDB stores JSON as true text, not in binary format as MySQL. MariaDB's JSON functions are much faster
than MySQL's so there is no need to store in binary format, which would add complexity when manipulating JSON
objects.
For the same reason, MariaDB's JSON data type is an alias for LONGTEXT. If you want to replicate JSON
columns from MySQL to MariaDB, you should store JSON objects in MySQL in a TEXT or LONGTEXT column or
use statement based replication. If you are using JSON columns and want to upgrade to MariaDB, you need to
either convert them to TEXT or use mysqldump to copy these tables to MariaDB.
In MySQL, JSON is compared according to json values. In MariaDB JSON strings are normal strings and
compared as strings.
MariaDB 10.3 does not support MySQL's JSON operators ( -> and ->> ) (MDEV-13594 )
MariaDB 10.3 supports the standard by producing null and a warning for JSON_SEARCH when given invalid
data, while MySQL produces an error.
MariaDB 10.3 does not support the ngram and MeCab full-text parser plugins - MDEV-10267 , MDEV-10268 .
MariaDB 10.3 does not support the MySQL X plugin .
MariaDB 10.3 does not support MySQL 5.7's “native” InnoDB partitioning handler.
MariaDB 10.3 does not support MySQL 5.7's ALTER TABLE...RENAME INDEX statements.
MySQL's implementation of aborting statements that exceed a certain time to execute can only kill SELECTs,
while MariaDB's can kill any queries (excluding stored procedures).
MariaDB 10.3 does not support MySQL's SELECT MAX_STATEMENT_TIME = N ... for MySQL older than 5.7.8 or
SELECT /*+ MAX_EXECUTION_TIME(n) */ ... for MySQL 5.7.8 and higher - see Aborting Statements that Exceed
a Certain Time to Execute.
The MySQL version of max_statement_time is defined in millseconds, not seconds.
MariaDB 10.3 does not support the MySQL Memcached plugin. However, data stored using memcached can be
retrieved because the data is stored as InnoDB tables. MariaDB is able to start successfully with an error
message of not being able to find libmemcached.so library.
Users created with MySQL's SHA256 password algorithm cannot be used in MariaDB 10.3 - MDEV-9804 .
MariaDB 10.3 doesn't support user ACCOUNT LOCKs or PASSWORD EXPIRE (MariaDB 10.4 does)
In MySQL, X'HHHH' , the standard SQL syntax for binary string literals, erroneously works in the same way as
0xHHHH , which could work as a number or string depending on the context. In MariaDB, this has been fixed to
behave as a string in all contexts (and never as a number). See CAST and Hexadecimal Literals for more details
and examples.
In MariaDB 10.3, SHOW CREATE TABLE does not quote the DEFAULT value of an integer. Older versions of
MariaDB, and MySQL, do. Since MariaDB 10.3 can support defaults for BLOB and TEXT fields, while MySQL
does not, SHOW CREATE TABLE will also append DEFAULT NULL where no default is explicitly provided to
nullable BLOB or TEXT fields in MariaDB.
Since MariaDB supports expressions in the DEFAULT clause, in MariaDB, the
INFORMATION_SCHEMA.COLUMNS table contains extra fields, and also quotes the DEFAULT value of a string
in the COLUMN_DEFAULT field in order to distinguish it from an expression.
Since MariaDB supports INTERSECT and EXCEPT, these are both reserved words and can't be used as an
identifier without being quoted.
As a result of implementing Table Value Constructors, the VALUES function has been renamed to VALUE().
MariaDB does not support the optional init_vector argument for AES_ENCRYPT and AES_DECRYPT or the
block_encryption_mode variable - MDEV-9069
MariaDB does not support the --initialize option. Use mysql_install_db instead. - MDEV-19010
Not all character sets and collations are supported across both MySQL and MariaDB. As of 10.3.24, MariaDB
supports 40 character sets and 322 collations. As of 5.7.29, MySQL supports 41 character sets ( gb18030 being
the additional one) and 222 collations.
The MySQL binary log includes the thread_id, while MariaDB's binary log does not. (MDEV-7850 )
Also see Incompatibilities between MariaDB 10.2 and MySQL 5.7 and Incompatibilities between MariaDB 10.1
and MySQL 5.7.

2.1.14.1.10 Function Differences Between


MariaDB and MySQL
Functions in MariaDB that are not present in MySQL, or vice-versa.
Function Differences Between MariaDB 10.10 and MySQL 8.0
Functions present in MariaDB 10.10 and not present in MySQL 8.0 and vice-versa.

1670/3812
Function Differences Between MariaDB 10.9 and MySQL 8.0
Functions present in MariaDB 10.9 and not present in MySQL 8.0 and vice-versa.

Function Differences Between MariaDB 10.8 and MySQL 8.0


Functions present in MariaDB 10.8 and not present in MySQL 8.0 and vice-versa.

Function Differences Between MariaDB 10.7 and MySQL 8.0


Functions present in MariaDB 10.7 and not present in MySQL 8.0 and vice-versa.

Function Differences Between MariaDB 10.6 and MySQL 8.0


Functions present in MariaDB 10.6 and not present in MySQL 8.0 and vice-versa.

Function Differences Between MariaDB 10.5 and MySQL 8.0


Functions present in MariaDB 10.5 and not present in MySQL 8.0 and vice-versa.

Function Differences Between MariaDB 10.4 and MySQL 8.0


Functions present in MariaDB 10.4 and not present in MySQL 8.0 and vice-versa.

Function Differences Between MariaDB 10.3 and MySQL 8.0


Functions present in MariaDB 10.3 and not present in MySQL 8.0 and vice-versa.

Function Differences Between MariaDB 10.3 and MySQL 5.7


Functions present in MariaDB 10.3 and not present in MySQL 5.7 and vice-versa.

Function Differences Between MariaDB 10.2 and MySQL 5.7


Functions present in MariaDB 10.2 and not present in MySQL 5.7 and vice-versa.

Function Differences Between MariaDB 10.2 and MySQL 5.6


Functions present in MariaDB 10.2 and not present in MySQL 5.6 and vice-versa.

2.1.14.1.10.1 Function Differences Between


MariaDB 10.8 and MySQL 8.0
Contents
1. Present in MariaDB Only
1. Dynamic Columns
2. Galera
3. General
4. Geographic
5. JSON
6. Sequences
7. Window Functions
8. Miscellaneous
2. Present in MySQL Only
1. GTID
2. Geographic
3. JSON
4. Regular Expressions
5. UUID
6. Miscellaneous
3. See Also

The following is a list of all function differences between MariaDB 10.8 and MySQL 8.0. It is based on functions
available in the MySQL 8.0.23 and the MariaDB 10.8.3 releases. For a more complete list of differences, see
Incompatibilities and Feature Differences Between MariaDB 10.8 and MySQL 8.0

Present in MariaDB Only


Dynamic Columns
COLUMN_ADD
COLUMN_CHECK
COLUMN_CREATE
COLUMN_DELETE
COLUMN_EXISTS
COLUMN_GET
1671/3812
COLUMN_JSON
COLUMN_LIST

Galera
WSREP_LAST_SEEN_GTID
WSREP_LAST_WRITTEN_GTID
WSREP_SYNC_WAIT_UPTO_GTID

General
ADD_MONTHS
CHR
DECODE_ORACLE
LENGTHB
NVL (Synonym for IFNULL)
NVL2
SYS_GUID
TO_CHAR
TRIM_ORACLE
VALUE - the VALUES() function was renamed after MariaDB introduced Table Value Constructors.

Geographic
MySQL has removed the following functions in MySQL 8.0.
AREA
AsBinary
AsText
AsWKB
AsWKT
Buffer
Centroid
Contains
ConvexHull
Crosses
Dimension
Disjoint
EndPoint
Envelope
Equals
ExteriorRing
GeomCollFromText
GeomCollFromWKB
GeomFromText
GeomFromWKB
GeometryCollectionFromText
GeometryCollectionFromWKB
GeometryFromText
GeometryFromWKB
GeometryN
GeometryType
GLENGTH
InteriorRingN
Intersects
IsClosed
IsEmpty
IsSimple
LineFromText
LineFromWKB
LineStringFromText
LineStringFromWKB
MLineFromText
MLineFromWKB
MPointFromText
MPointFromWKB
MPolyFromText
MPolyFromWKB
MultiLineStringFromText
MultiLineStringFromWKB
MultiPointFromText
1672/3812
MultiPointFromWKB
MultiPolygonFromText
MultiPolygonFromWKB
NumGeometries
NumInteriorRings
NumPoints
Overlaps
PointFromText
PointFromWKB
PointN
PolyFromText
PolyFromWKB
PolygonFromText
PolygonFromWKB
SRID
StartPoint
Touches
Within
X
Y

JSON
JSON_COMPACT
JSON_DETAILED
JSON_EQUALS
JSON_EXISTS
JSON_LOOSE
JSON_NORMALIZE
JSON_QUERY

Sequences
LASTVAL
NEXTVAL
SETVAL

Window Functions
MEDIAN
PERCENTILE_CONT
PERCENTILE_DISC

Miscellaneous
NATURAL_SORT_KEY
SFORMAT

Present in MySQL Only


GTID
MariaDB and MySQL have differing GTID implementations.
GTID_SUBSET
GTID_SUBTRACT
WAIT_FOR_EXECUTED_GTID_SET
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS

Geographic
MBRCOVEREDBY
ST_BUFFER_STRATEGY
ST_FrechetDistance
ST_GeoHash
ST_HausdorffDistance
ST_IsValid
ST_LatFromGeoHash
ST_LongFromGeoHash
1673/3812
ST_PointFromGeoHash
ST_SIMPLIFY
ST_VALIDATE (MDEV-17398 )

JSON
JSON_OVERLAPS (MDEV-27677 )
JSON_PRETTY
JSON_STORAGE_FREE
JSON_STORAGE_SIZE (MDEV-17397 )

Regular Expressions
REGEXP_LIKE (MDEV-16599 )

UUID
BIN_TO_UUID
IS_UUID
UUID_TO_BIN (MDEV-15854 )

Miscellaneous
ANY_VALUE (MDEV-10426 )
ASYNCHRONOUS_CONNECTION_FAILOVER_ADD_SOURCE
ASYNCHRONOUS_CONNECTION_FAILOVER_DELETE_SOURCE
GROUPING
RANDOM_BYTES (MDEV-25704 )
VALIDATE_PASSWORD_STRENGTH (MDEV-25703 )

See Also
Incompatibilities and Feature Differences Between MariaDB 10.7 and MySQL 8.0
Function Differences Between MariaDB 10.7 and MySQL 8.0
Function Differences Between MariaDB 10.6 and MySQL 8.0
System Variable Differences Between MariaDB 10.8 and MySQL 8.0
MariaDB versus MySQL - Compatibility
MariaDB versus MySQL - Features

2.1.14.1.10.2 Function Differences Between


MariaDB 10.7 and MySQL 8.0
Contents
1. Present in MariaDB Only
1. Dynamic Columns
2. Galera
3. General
4. Geographic
5. JSON
6. Sequences
7. Window Functions
8. Miscellaneous
2. Present in MySQL Only
1. GTID
2. Geographic
3. JSON
4. Regular Expressions
5. UUID
6. Miscellaneous
3. See Also

The following is a list of all function differences between MariaDB 10.7 and MySQL 8.0. It is based on functions
available in the MySQL 8.0.23 and the MariaDB 10.7.0 releases. For a more complete list of differences, see
Incompatibilities and Feature Differences Between MariaDB 10.7 and MySQL 8.0

Present in MariaDB Only


1674/3812
Dynamic Columns
COLUMN_ADD
COLUMN_CHECK
COLUMN_CREATE
COLUMN_DELETE
COLUMN_EXISTS
COLUMN_GET
COLUMN_JSON
COLUMN_LIST

Galera
WSREP_LAST_SEEN_GTID
WSREP_LAST_WRITTEN_GTID
WSREP_SYNC_WAIT_UPTO_GTID

General
ADD_MONTHS
CHR
DECODE_ORACLE
LENGTHB
NVL (Synonym for IFNULL)
NVL2
SYS_GUID
TO_CHAR
TRIM_ORACLE
VALUE - the VALUES() function was renamed after MariaDB introduced Table Value Constructors.

Geographic
MySQL has removed the following functions in MySQL 8.0.
AREA
AsBinary
AsText
AsWKB
AsWKT
Buffer
Centroid
Contains
ConvexHull
Crosses
Dimension
Disjoint
EndPoint
Envelope
Equals
ExteriorRing
GeomCollFromText
GeomCollFromWKB
GeomFromText
GeomFromWKB
GeometryCollectionFromText
GeometryCollectionFromWKB
GeometryFromText
GeometryFromWKB
GeometryN
GeometryType
GLENGTH
InteriorRingN
Intersects
IsClosed
IsEmpty
IsSimple
LineFromText
LineFromWKB
LineStringFromText
LineStringFromWKB
MLineFromText
1675/3812
MLineFromWKB
MPointFromText
MPointFromWKB
MPolyFromText
MPolyFromWKB
MultiLineStringFromText
MultiLineStringFromWKB
MultiPointFromText
MultiPointFromWKB
MultiPolygonFromText
MultiPolygonFromWKB
NumGeometries
NumInteriorRings
NumPoints
Overlaps
PointFromText
PointFromWKB
PointN
PolyFromText
PolyFromWKB
PolygonFromText
PolygonFromWKB
SRID
StartPoint
Touches
Within
X
Y

JSON
JSON_COMPACT
JSON_DETAILED
JSON_EQUALS
JSON_EXISTS
JSON_LOOSE
JSON_NORMALIZE
JSON_QUERY

Sequences
LASTVAL
NEXTVAL
SETVAL

Window Functions
MEDIAN
PERCENTILE_CONT
PERCENTILE_DISC

Miscellaneous
NATURAL_SORT_KEY
SFORMAT

Present in MySQL Only


GTID
MariaDB and MySQL have differing GTID implementations.
GTID_SUBSET
GTID_SUBTRACT
WAIT_FOR_EXECUTED_GTID_SET
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS

Geographic
1676/3812
MBRCOVEREDBY
ST_BUFFER_STRATEGY
ST_FrechetDistance
ST_GeoHash
ST_HausdorffDistance
ST_IsValid
ST_LatFromGeoHash
ST_LongFromGeoHash
ST_PointFromGeoHash
ST_SIMPLIFY
ST_VALIDATE (MDEV-17398 )

JSON
JSON_OVERLAPS (MDEV-27677 )
JSON_PRETTY
JSON_STORAGE_FREE
JSON_STORAGE_SIZE (MDEV-17397 )

Regular Expressions
REGEXP_LIKE (MDEV-16599 )

UUID
BIN_TO_UUID
IS_UUID
UUID_TO_BIN (MDEV-15854 )

Miscellaneous
ANY_VALUE (MDEV-10426 )
ASYNCHRONOUS_CONNECTION_FAILOVER_ADD_SOURCE
ASYNCHRONOUS_CONNECTION_FAILOVER_DELETE_SOURCE
GROUPING
RANDOM_BYTES (MDEV-25704 )
VALIDATE_PASSWORD_STRENGTH (MDEV-25703 )

See Also
Incompatibilities and Feature Differences Between MariaDB 10.7 and MySQL 8.0
Function Differences Between MariaDB 10.6 and MySQL 8.0
Function Differences Between MariaDB 10.5 and MySQL 8.0
System Variable Differences Between MariaDB 10.7 and MySQL 8.0
MariaDB versus MySQL - Compatibility
MariaDB versus MySQL - Features

2.1.14.1.10.3 Function Differences Between


MariaDB 10.6 and MySQL 8.0

1677/3812
Contents
1. Present in MariaDB Only
1. Dynamic Columns
2. Galera
3. General
4. Geographic
5. JSON
6. Sequences
7. Window Functions
2. Present in MySQL Only
1. GTID
2. Geographic
3. JSON
4. Regular Expressions
5. UUID
6. Miscellaneous
3. See Also

The following is a list of all function differences between MariaDB 10.6 and MySQL 8.0. It is based on functions
available in the MySQL 8.0.23 and the MariaDB 10.6.1 releases. For a more complete list of differences, see
Incompatibilities and Feature Differences Between MariaDB 10.6 and MySQL 8.0

Present in MariaDB Only


Dynamic Columns
COLUMN_ADD
COLUMN_CHECK
COLUMN_CREATE
COLUMN_DELETE
COLUMN_EXISTS
COLUMN_GET
COLUMN_JSON
COLUMN_LIST

Galera
WSREP_LAST_SEEN_GTID
WSREP_LAST_WRITTEN_GTID
WSREP_SYNC_WAIT_UPTO_GTID

General
ADD_MONTHS
CHR
DECODE_ORACLE
LENGTHB
NVL (Synonym for IFNULL)
NVL2
SYS_GUID
TO_CHAR
TRIM_ORACLE
VALUE - the VALUES() function was renamed after MariaDB introduced Table Value Constructors.

Geographic
MySQL has removed the following functions in MySQL 8.0.
AREA
AsBinary
AsText
AsWKB
AsWKT
Buffer
Centroid
Contains
ConvexHull
Crosses
Dimension
1678/3812
Disjoint
EndPoint
Envelope
Equals
ExteriorRing
GeomCollFromText
GeomCollFromWKB
GeomFromText
GeomFromWKB
GeometryCollectionFromText
GeometryCollectionFromWKB
GeometryFromText
GeometryFromWKB
GeometryN
GeometryType
GLENGTH
InteriorRingN
Intersects
IsClosed
IsEmpty
IsSimple
LineFromText
LineFromWKB
LineStringFromText
LineStringFromWKB
MLineFromText
MLineFromWKB
MPointFromText
MPointFromWKB
MPolyFromText
MPolyFromWKB
MultiLineStringFromText
MultiLineStringFromWKB
MultiPointFromText
MultiPointFromWKB
MultiPolygonFromText
MultiPolygonFromWKB
NumGeometries
NumInteriorRings
NumPoints
Overlaps
PointFromText
PointFromWKB
PointN
PolyFromText
PolyFromWKB
PolygonFromText
PolygonFromWKB
SRID
StartPoint
Touches
Within
X
Y

JSON
JSON_COMPACT
JSON_DETAILED
JSON_EXISTS
JSON_LOOSE
JSON_QUERY
JSON_VALUE

Sequences
LASTVAL
NEXTVAL
SETVAL

1679/3812
Window Functions
MEDIAN
PERCENTILE_CONT
PERCENTILE_DISC

Present in MySQL Only


GTID
MariaDB and MySQL have differing GTID implementations.
GTID_SUBSET
GTID_SUBTRACT
WAIT_FOR_EXECUTED_GTID_SET
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS

Geographic
MBRCOVEREDBY
ST_BUFFER_STRATEGY
ST_FrechetDistance
ST_GeoHash
ST_HausdorffDistance
ST_IsValid
ST_LatFromGeoHash
ST_LongFromGeoHash
ST_PointFromGeoHash
ST_SIMPLIFY
ST_VALIDATE (MDEV-17398 )

JSON
JSON_OVERLAPS (MDEV-27677 )
JSON_PRETTY
JSON_STORAGE_FREE
JSON_STORAGE_SIZE (MDEV-17397 )

Regular Expressions
REGEXP_LIKE (MDEV-16599 )

UUID
BIN_TO_UUID
IS_UUID
UUID_TO_BIN (MDEV-15854 )

Miscellaneous
ANY_VALUE (MDEV-10426 )
ASYNCHRONOUS_CONNECTION_FAILOVER_ADD_SOURCE
ASYNCHRONOUS_CONNECTION_FAILOVER_DELETE_SOURCE
GROUPING
RANDOM_BYTES (MDEV-25704 )
VALIDATE_PASSWORD_STRENGTH (MDEV-25703 )

See Also
Incompatibilities and Feature Differences Between MariaDB 10.6 and MySQL 8.0
Function Differences Between MariaDB 10.5 and MySQL 8.0
Function Differences Between MariaDB 10.4 and MySQL 8.0
System Variable Differences Between MariaDB 10.6 and MySQL 8.0
MariaDB versus MySQL - Compatibility
MariaDB versus MySQL - Features

1680/3812
2.1.14.1.10.4 Function Differences Between
MariaDB 10.5 and MySQL 8.0
Contents
1. Present in MariaDB Only
1. Dynamic Columns
2. Galera
3. General
4. Geographical
5. JSON
6. Sequences
7. Window Functions
2. Present in MySQL Only
1. GTID
2. Geographic
3. JSON
4. Regular Expressions
5. UUID
6. Miscellaneous
3. See Also

The following is a list of all function differences between MariaDB 10.5 and MySQL 8.0. It is based on functions
available in the MySQL 8.0.17 and the MariaDB 10.5.10 releases. For a more complete list of differences, see
Incompatibilities and Feature Differences Between MariaDB 10.5 and MySQL 8.0

Present in MariaDB Only


Dynamic Columns
COLUMN_ADD
COLUMN_CHECK
COLUMN_CREATE
COLUMN_DELETE
COLUMN_EXISTS
COLUMN_GET
COLUMN_JSON
COLUMN_LIST

Galera
WSREP_LAST_SEEN_GTID
WSREP_LAST_WRITTEN_GTID
WSREP_SYNC_WAIT_UPTO_GTID

General
CHR
DECODE_ORACLE
LENGTHB
NVL (Synonym for IFNULL)
NVL2
TRIM_ORACLE
VALUE - the VALUES() function was renamed after MariaDB introduced Table Value Constructors.

Geographical
MySQL has removed the following functions in MySQL 8.0.
AREA
AsBinary
AsText
AsWKB
AsWKT
Buffer
Centroid
Contains
ConvexHull

1681/3812
Crosses
Dimension
Disjoint
EndPoint
Envelope
Equals
ExteriorRing
GeomCollFromText
GeomCollFromWKB
GeomFromText
GeomFromWKB
GeometryCollectionFromText
GeometryCollectionFromWKB
GeometryFromText
GeometryFromWKB
GeometryN
GeometryType
GLENGTH
InteriorRingN
Intersects
IsClosed
IsEmpty
IsSimple
LineFromText
LineFromWKB
LineStringFromText
LineStringFromWKB
MLineFromText
MLineFromWKB
MPointFromText
MPointFromWKB
MPolyFromText
MPolyFromWKB
MultiLineStringFromText
MultiLineStringFromWKB
MultiPointFromText
MultiPointFromWKB
MultiPolygonFromText
MultiPolygonFromWKB
NumGeometries
NumInteriorRings
NumPoints
Overlaps
PointFromText
PointFromWKB
PointN
PolyFromText
PolyFromWKB
PolygonFromText
PolygonFromWKB
SRID
StartPoint
Touches
Within
X
Y

JSON
JSON_COMPACT
JSON_DETAILED
JSON_EXISTS
JSON_LOOSE
JSON_QUERY
JSON_VALUE

Sequences
LASTVAL
NEXTVAL
SETVAL
1682/3812
Window Functions
MEDIAN
PERCENTILE_CONT
PERCENTILE_DISC

Present in MySQL Only


GTID
MariaDB and MySQL have differing GTID implementations.
GTID_SUBSET
GTID_SUBTRACT
WAIT_FOR_EXECUTED_GTID_SET
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()

Geographic
MBRCOVEREDBY
ST_BUFFER_STRATEGY
ST_GeoHash
ST_IsValid
ST_LatFromGeoHash
ST_LongFromGeoHash
ST_PointFromGeoHash
ST_SIMPLIFY
ST_VALIDATE

JSON
JSON_OVERLAPS
JSON_PRETTY
JSON_STORAGE_FREE
JSON_STORAGE_SIZE
JSON_TABLE

Regular Expressions
REGEXP_LIKE (MDEV-16599 )

UUID
BIN_TO_UUID
IS_UUID
UUID_TO_BIN

Miscellaneous
ANY_VALUE
GROUPING
RANDOM_BYTES
VALIDATE_PASSWORD_STRENGTH

See Also
Incompatibilities and Feature Differences Between MariaDB 10.5 and MySQL 8.0
Function Differences Between MariaDB 10.4 and MySQL 8.0
Function Differences Between MariaDB 10.3 and MySQL 8.0
System Variable Differences Between MariaDB 10.5 and MySQL 8.0
MariaDB versus MySQL - Compatibility
MariaDB versus MySQL - Features

2.1.14.1.10.5 Function Differences Between


MariaDB 10.4 and MySQL 8.0
1683/3812
Contents
1. Present in MariaDB Only
1. Dynamic Columns
2. Galera
3. General
4. Geographical
5. JSON
6. Sequences
7. Window Functions
2. Present in MySQL Only
1. GTID
2. Geographic
3. JSON
4. Regular Expressions
5. UUID
6. Miscellaneous
3. See Also

The following is a list of all function differences between MariaDB 10.4 and MySQL 8.0. It is based on functions
available in the stable MySQL 8.0.17 and MariaDB 10.4.19 releases. For a more complete list of differences, see
Incompatibilities and Feature Differences Between MariaDB 10.4 and MySQL 8.0.

Present in MariaDB Only


Dynamic Columns
COLUMN_ADD
COLUMN_CHECK
COLUMN_CREATE
COLUMN_DELETE
COLUMN_EXISTS
COLUMN_GET
COLUMN_JSON
COLUMN_LIST

Galera
WSREP_LAST_SEEN_GTID
WSREP_LAST_WRITTEN_GTID
WSREP_SYNC_WAIT_UPTO_GTID

General
CHR
DECODE_ORACLE
LENGTHB
NVL (Synonym for IFNULL)
NVL2
TRIM_ORACLE
VALUE - the VALUES() function was renamed after MariaDB introduced Table Value Constructors.

Geographical
MySQL has removed the following functions in MySQL 8.0.
AREA
AsBinary
AsText
AsWKB
AsWKT
Buffer
Centroid
Contains
ConvexHull
Crosses
Dimension
Disjoint
EndPoint
Envelope
1684/3812
Equals
ExteriorRing
GeomCollFromText
GeomCollFromWKB
GeomFromText
GeomFromWKB
GeometryCollectionFromText
GeometryCollectionFromWKB
GeometryFromText
GeometryFromWKB
GeometryN
GeometryType
GLENGTH
InteriorRingN
Intersects
IsClosed
IsEmpty
IsSimple
LineFromText
LineFromWKB
LineStringFromText
LineStringFromWKB
MLineFromText
MLineFromWKB
MPointFromText
MPointFromWKB
MPolyFromText
MPolyFromWKB
MultiLineStringFromText
MultiLineStringFromWKB
MultiPointFromText
MultiPointFromWKB
MultiPolygonFromText
MultiPolygonFromWKB
NumGeometries
NumInteriorRings
NumPoints
Overlaps
PointFromText
PointFromWKB
PointN
PolyFromText
PolyFromWKB
PolygonFromText
PolygonFromWKB
SRID
StartPoint
Touches
Within
X
Y

JSON
JSON_COMPACT
JSON_DETAILED
JSON_EXISTS
JSON_LOOSE
JSON_QUERY
JSON_VALUE

Sequences
LASTVAL
NEXTVAL
SETVAL

Window Functions
MEDIAN
1685/3812
PERCENTILE_CONT
PERCENTILE_DISC

Present in MySQL Only


GTID
MariaDB and MySQL have differing GTID implementations.
GTID_SUBSET
GTID_SUBTRACT
WAIT_FOR_EXECUTED_GTID_SET
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()

Geographic
MBRCOVEREDBY
ST_BUFFER_STRATEGY
ST_GeoHash
ST_IsValid
ST_LatFromGeoHash
ST_LongFromGeoHash
ST_PointFromGeoHash
ST_SIMPLIFY
ST_VALIDATE

JSON
JSON_ARRAYAGG
JSON_OBJECTAGG
JSON_OVERLAPS
JSON_PRETTY
JSON_STORAGE_FREE
JSON_STORAGE_SIZE
JSON_TABLE

Regular Expressions
REGEXP_LIKE (MDEV-16599 )

UUID
BIN_TO_UUID
IS_UUID
UUID_TO_BIN

Miscellaneous
ANY_VALUE
GROUPING
RANDOM_BYTES
RELEASE_ALL_LOCKS
VALIDATE_PASSWORD_STRENGTH

See Also
Incompatibilities and Feature Differences Between MariaDB 10.4 and MySQL 8.0
Function Differences Between MariaDB 10.3 and MySQL 8.0
Function Differences Between MariaDB 10.3 and MySQL 5.7
System Variable Differences Between MariaDB 10.4 and MySQL 8.0
MariaDB versus MySQL - Compatibility
MariaDB versus MySQL - Features

2.1.14.1.10.6 Function Differences Between


MariaDB 10.3 and MySQL 8.0
1686/3812
Contents
1. Present in MariaDB Only
1. Dynamic Columns
2. General
3. Geographical
4. JSON
5. Sequences
6. Window Functions
2. Present in MySQL Only
1. GTID
2. Geographic
3. JSON
4. Regular Expressions
5. UUID
6. Miscellaneous
3. See Also

The following is a list of all function differences between MariaDB 10.3 and MySQL 8.0. It is based on functions
available in the stable versions MySQL 8.0.11 and MariaDB 10.3.20.

Present in MariaDB Only


Dynamic Columns
COLUMN_ADD
COLUMN_CHECK
COLUMN_CREATE
COLUMN_DELETE
COLUMN_EXISTS
COLUMN_GET
COLUMN_JSON
COLUMN_LIST

General
CHR
DECODE_ORACLE
LENGTHB
NVL (Synonym for IFNULL)
NVL2
TRIM_ORACLE
VALUE - the VALUES() function was renamed after MariaDB introduced Table Value Constructors.

Geographical
MySQL has removed the following functions in MySQL 8.0.
AREA
AsBinary
AsText
AsWKB
AsWKT
Buffer
Centroid
Contains
ConvexHull
Crosses
Dimension
Disjoint
EndPoint
Envelope
Equals
ExteriorRing
GeomCollFromText
GeomCollFromWKB
GeomFromText
GeomFromWKB
GeometryCollectionFromText
GeometryCollectionFromWKB
1687/3812
GeometryFromText
GeometryFromWKB
GeometryN
GeometryType
GLENGTH
InteriorRingN
Intersects
IsClosed
IsEmpty
IsSimple
LineFromText
LineFromWKB
LineStringFromText
LineStringFromWKB
MLineFromText
MLineFromWKB
MPointFromText
MPointFromWKB
MPolyFromText
MPolyFromWKB
MultiLineStringFromText
MultiLineStringFromWKB
MultiPointFromText
MultiPointFromWKB
MultiPolygonFromText
MultiPolygonFromWKB
NumGeometries
NumInteriorRings
NumPoints
Overlaps
PointFromText
PointFromWKB
PointN
PolyFromText
PolyFromWKB
PolygonFromText
PolygonFromWKB
SRID
StartPoint
Touches
Within
X
Y

JSON
JSON_COMPACT
JSON_DETAILED
JSON_EXISTS
JSON_LOOSE
JSON_QUERY
JSON_VALUE

Sequences
LASTVAL
NEXTVAL
SETVAL

Window Functions
MEDIAN
PERCENTILE_CONT
PERCENTILE_DISC

Present in MySQL Only


GTID
1688/3812
MariaDB and MySQL have differing GTID implementations.
GTID_SUBSET
GTID_SUBTRACT
WAIT_FOR_EXECUTED_GTID_SET
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()

Geographic
MBRCOVEREDBY
ST_BUFFER_STRATEGY
ST_GeoHash
ST_IsValid
ST_LatFromGeoHash
ST_LongFromGeoHash
ST_PointFromGeoHash
ST_SIMPLIFY
ST_VALIDATE

JSON
JSON_ARRAYAGG
JSON_OBJECTAGG
JSON_PRETTY
JSON_STORAGE_FREE
JSON_STORAGE_SIZE
JSON_TABLE

Regular Expressions
REGEXP_LIKE (MDEV-16599 )

UUID
BIN_TO_UUID
IS_UUID
UUID_TO_BIN

Miscellaneous
ANY_VALUE
GROUPING
RANDOM_BYTES
RELEASE_ALL_LOCKS
VALIDATE_PASSWORD_STRENGTH

See Also
Function Differences Between MariaDB 10.3 and MySQL 5.7
System Variable Differences Between MariaDB 10.3 and MySQL 8.0
MariaDB versus MySQL - Compatibility
MariaDB versus MySQL - Features

2.1.14.1.10.7 Function Differences Between


MariaDB 10.3 and MySQL 5.7

1689/3812
Contents
1. Present in MariaDB Only
1. Dynamic Columns
2. General
3. JSON
4. Regular Expressions
5. Sequences
6. Window Functions
2. Present in MySQL Only
1. GTID
2. Geographic
3. Miscellaneous
3. See Also

The following is a list of all function differences between MariaDB 10.3 and MySQL 5.7. It is based on functions
available in the stable versions MySQL 5.7.18 and MariaDB 10.3.29.
For a description of all differences, see Incompatibilities and Feature Differences Between MariaDB 10.3 and MySQL
5.7.

Present in MariaDB Only


Dynamic Columns
COLUMN_ADD
COLUMN_CHECK
COLUMN_CREATE
COLUMN_DELETE
COLUMN_EXISTS
COLUMN_GET
COLUMN_JSON
COLUMN_LIST

General
CHR
DECODE_ORACLE
LENGTHB
NVL (Synonym for IFNULL)
NVL2
TRIM_ORACLE
VALUE - the VALUES() function was renamed after MariaDB introduced Table Value Constructors.

JSON
JSON_COMPACT
JSON_DETAILED
JSON_EXISTS
JSON_LOOSE
JSON_MERGE_PATCH
JSON_MERGE_PRESERVE
JSON_QUERY
JSON_VALUE

Regular Expressions
REGEXP_INSTR
REGEXP_REPLACE
REGEXP_SUBSTR

Sequences
LASTVAL
NEXTVAL
SETVAL

Window Functions
1690/3812
CUME_DIST
DENSE_RANK
LAG
LAST_VALUE
LEAD
MEDIAN
NTH_VALUE
NTILE
PERCENT_RANK
PERCENTILE_CONT
PERCENTILE_DISC
RANK
ROW_NUMBER

Present in MySQL Only


GTID
MariaDB and MySQL have differing GTID implementations.
GTID_SUBSET
GTID_SUBTRACT
WAIT_FOR_EXECUTED_GTID_SET
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()

Geographic
DISTANCE
MBRCOVEREDBY
ST_BUFFER_STRATEGY
ST_GeoHash
ST_IsValid
ST_LatFromGeoHash
ST_LongFromGeoHash
ST_PointFromGeoHash
ST_SIMPLIFY
ST_VALIDATE

Miscellaneous
ANY_VALUE
RANDOM_BYTES
RELEASE_ALL_LOCKS
VALIDATE_PASSWORD_STRENGTH

See Also
Incompatibilities and Feature Differences Between MariaDB 10.3 and MySQL 5.7
System Variable Differences Between MariaDB 10.3 and MySQL 5.7
Function Differences Between MariaDB 10.2 and MySQL 5.7

2.1.14.1.11 System Variable Differences


between MariaDB and MySQL
The following articles list the differences between the system variables available in MariaDB and in MySQL for each of
the major releases.
System Variable Differences Between MariaDB 10.9 and MySQL 8.0
Comparison of MariaDB 10.9 and MySQL 8.0 system variables.

System Variable Differences Between MariaDB 10.8 and MySQL 8.0


Comparison of MariaDB 10.8 and MySQL 8.0 system variables.

System Variable Differences Between MariaDB 10.7 and MySQL 8.0


Comparison of MariaDB 10.7 and MySQL 8.0 system variables.

1691/3812
System Variable Differences Between MariaDB 10.6 and MySQL 8.0
Comparison of MariaDB 10.6 and MySQL 8.0 system variables.

System Variable Differences Between MariaDB 10.5 and MySQL 8.0


Comparison of MariaDB 10.5 and MySQL 8.0 system variables.

System Variable Differences Between MariaDB 10.4 and MySQL 8.0


Comparison of MariaDB 10.4 and MySQL 8.0 system variables.

System Variable Differences Between MariaDB 10.3 and MySQL 8.0


Comparison of MariaDB 10.3 and MySQL 8.0 system variables.

System Variable Differences Between MariaDB 10.3 and MySQL 5.7


Comparison of MariaDB 10.3 and MySQL 5.7 system variables.

System Variable Differences Between MariaDB and MySQL - Unsupported


Releases
Comparison of variable differences between major versions of MariaDB and MySQL.

2.1.14.1.11.1 System Variable Differences


Between MariaDB 10.9 and MySQL 8.0
Contents
1. Comparison Table
2. See Also

The following is a comparison of variables that either appear only in MariaDB 10.9 or MySQL 8.0, or have different
default settings in MariaDB 10.9, and MySQL 8.0. The releases MariaDB 10.9.1 and MySQL 8.0.11, with only default
plugins enabled, were used for the comparison. Note that MySQL 8 is an 'evergreen' release, so features may be added
or removed in later releases.

Comparison Table
Variable MariaDB 10.9 Default MySQL 8.0 Default Notes
Determines whether to automatically
activate_all_roles_on_login - OFF
activate roles on login.
MariaDB 10.3 introduced new
ALTER TABLE ALGORITHM
clauses to avoid slow copies in
alter_algorithm DEFAULT -
certain instances. This variable
allows setting this if no ALGORITHM
clause is specified.
Percentage of rows from the table
analyze_sample_percentage 100.0000 - ANALYZE TABLE will sample to
collect table statistics.
The Aria storage engine is only
aria_* * -
available in MariaDB.
Whether to automatically generate
auto_generate_certs - ON
SSL key and certificate files.
Determines whether ALTER TABLE
avoid_temporal_upgrade - OFF implicitly upgrades temporal
columns.
MariaDB and MySQL have different
back_log Autosized Autosized
autosizing algorithms.
Introduced in MariaDB 5.3 for
binlog-annotate-row-events ON - replicating between MariaDB 5.3 and
MySQL/MariaDB 5.1.
For use in MariaDB's parallel
binlog_commit_wait_count 0 -
replication.
For use in MariaDB's parallel
binlog_commit_wait_usec 100000 -
replication.
MySQL-only variable for controlling
binlog_error_action ABORT_SERVER what happens when the server
cannot write to the binary log.
Sets the binary log expiration period
binlog_expire_logs_seconds 0 2592000 in seconds

For setting the size of the file cache


binlog_file_cache_size 16184 -
for the binary log.
MariaDB and MySQL have differing
binlog_format MIXED ROW
binary log formats.

1692/3812
MySQL-only variable for controlling
binlog_group_commit_sync_delay 0 the wait time before synchronizing
the binary log file to disk.
MySQL-only variable for setting the
maximum number of transactions to
binlog_group_commit_sync_no_delay_count 0 wait for before aborting the current
binlog_group_commit_sync_delay
delay.
MySQL-only GTID variable.
binlog_gtid_simple_recovery - ON MariaDB's GTID implementation is
different.
Specifies a timeout for reading
transactions from the flush queue
binlog_max_flush_queue_time - 0
before continuing with group commit
and syncing log to disk.
For optimized kernel thread
binlog_optimize_thread_scheduling ON -
scheduling.
Determines whether transactions
binlog_order_commits - ON
may be committed in parallel.
Determines the amount of table
binlog_row_metadata NO_LOG MINIMAL metadata added to the binary log
with row-based logging.
Permits an alternative binlog format
binlog_row_value_options - (empty)
for JSON document updates.
MySQL-only variable for logging
binlog_rows_query_log_events - OFF extra information in row-based
logging.
Maximum number of row hashes
binlog_transaction_dependency_history_size - 25000 kept for looking up transactions that
last modified a given row.
For determining how to best use the
binlog_transaction_dependency_tracking - COMMIT_ORDER
slave's multithreaded applier.
MySQL-only variable for controlling
block_encryption_mode - aes-128-ecb the block encryption mode for block-
based algorithms.
For use with MySQL's SHA-256
caching_sha2_password* - *
authentication with caching.
MySQL 8.0 defaults to the utf8mb4
character_set_* latin1 or utf8 utf8mb4
character set.
Permits disabling constraint checks,
for example when loading a table
check_constraint_checks ON -
that violates some constraints that
you plan to fix later.
MySQL-only variable for controlling
whether the server performs proxy
check_proxy_users OFF
user mapping for authentication
plugins.
MySQL 8.0 defaults to the utf8mb4
collation_* latin1_swedish_ci or utf8_general_ci utf8mb4_0900_ai_ci
character set.
MariaDB supports Storage-engine
column_compression_threshold 100 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_level 6 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_strategy DEFAULT_STRATEGY -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_wrap OFF -
Independent Column Compression.
When MySQL 8.0 introduced
common table expressions they
cte_max_recursion_depth - 1000 used a different name. MariaDB's
variable is called
max_recursive_iterations.
Unused variable removed in MySQL
date_format %Y-%m-%d -
8.0
Unused variable removed in MySQL
datetime_format %Y-%m-%d -
8.0
The Aria storage engine is only
deadlock_search_depth_long 15 -
available in MariaDB.
The Aria storage engine is only
deadlock_search_depth_short 4 -
available in MariaDB.
The Aria storage engine is only
deadlock_timeout_long 50000000 -
available in MariaDB.
The Aria storage engine is only
deadlock_timeout_short 10000 -
available in MariaDB.
Disable system thread alarm calls,
debug_no_thread_alarm OFF -
for debugging or testing.
MySQL 8 introduced a new
default_authentication_plugin - caching_sha2_password
authentication plugin.
For internal use in MySQL 8
default_collation_for_utf8mb4 - utf8mb4_0900_ai_ci
replication.

1693/3812
For use with MariaDB's multi-source
default_master_connection empty -
replication.
MariaDB defaults to password
default_password_lifetime 0 360
expiration off.
For handling incompatibilities
default_regex_flags empty - between MariaDB's PCRE and the
old regex library.
Default storage engine used for
default_tmp_storage_engine empty InnoDB tables created with CREATE
TEMPORARY TABLE.
MySQL-only variable for disabling
disabled_storage_engines empty
specific storage engines.
MariaDB password expiration is off
by default, and by default does not
disconnect_on_expired_password OFF ON
disconnect a client when a password
has expired.
MariaDB enables table and
encrypt_binlog OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_files OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_disk_tables OFF -
tablespace encryption.
MySQL-only variable for adding end
end_markers_in_json - OFF
markers to JSON output.
MariaDB and MySQL have different
enforce_gtid_consistency - OFF
GTID implementations.
Forces the use of a particular
enforce_storage_engine none
storage engine for new tables.
Variable for tuning when the
optimizer should switch from using
eq_range_index_dive_limit 0 200
index dives to index statistics for
qualifying rows estimation.
MySQL enables the event scheduler
event_scheduler OFF ON
by default.
Used for determining expensive
expensive_subquery_limit 100 -
queries for optimization.
MySQL 8 disables the old
explicit_defaults_for_timestamp OFF ON
timestamp behavior.
Introduced in the MariaDB 5.1
extra_max_connections 1 -
threadpool.
Introduced in the MariaDB 5.1
extra_port 0 -
threadpool.
MariaDB increases the maximum
group_concat_max_len 1048576 1024 length for a GROUP_CONCAT()
result from 1K to 1M.
MariaDB and MySQL have different
gtid_binlog_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_binlog_state empty -
GTID implementations.
MariaDB and MySQL have different
gtid_cleanup_batch_size 64 -
GTID implementations.
MariaDB and MySQL have different
gtid_current_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_domain_id 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_executed - empty
GTID implementations.
MariaDB and MySQL have different
gtid_executed_compression_period - 1000
GTID implementations.
MariaDB and MySQL have different
gtid_ignore_duplicates OFF - GTID implementations.

MariaDB and MySQL have different


gtid_mode - OFF
GTID implementations.
MariaDB and MySQL have different
gtid_next - AUTOMATIC
GTID implementations.
MariaDB and MySQL have different
gtid_owned - empty
GTID implementations.
MariaDB and MySQL have different
gtid_pos_auto_engines empty -
GTID implementations.
MariaDB and MySQL have different
gtid_purged - empty
GTID implementations.
MariaDB and MySQL have different
gtid_seq_no 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_slave_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_strict_mode OFF -
GTID implementations.

1694/3812
MySQL has removed the ENCRYPT
have_crypt YES -
function.
MariaDB's version indicates whether
YaSSL or openssl was used.
have_openssl
MySQL's is a synonym for
have_ssl .

MySQL has removed the query


have_query_cache YES -
cache.
Whether MySQL's statement
have_statement_timeout - execution timeout feature is
available.
MySQL has removed symlink
have_symlink YES DISABLED
support.
Added when MySQL 8 introduced
histogram_generation_max_mem_size - 20000000 Histogram-based Statistics.
MariaDB uses histogram_size
MariaDB introduced Histogram-
histogram_size 0 -
based Statistics.
MariaDB introduced Histogram-
histogram_type SINGLE_PREC_HB -
based Statistics.
Time in seconds that the server
idle_readonly_transaction_timeout 0 -
waits for idle read-only transactions.
Time in seconds that the server
idle_transaction_timeout 0 -
waits for idle transactions.
Time in seconds that the server
idle_write_transaction_timeout 0 -
waits for idle write transactions.
ignore_builtin_innodb OFF - Ignored and removed in MySQL 8.
Controls the Conversion of Big IN
in_predicate_conversion_threshold 1000 - Predicates Into Subqueries
optimization.
Set to 1 if you are in a transaction,
in_transaction 0 -
and 0 if not.
Time until MySQL Information
information_schema_stats_expiry - 86400
Schema cached statistics expire.
Adaptive flushing is enabled when
this this low water mark percentage
innodb_adaptive_flushing_lwm 10.000000 10 of the redo log capacity is reached.
MariaDB's variable is a double,
MySQL's an integer.
Defaulting to OFF is a performance
improvement especially for DROP
innodb_adaptive_hash_index OFF ON
TABLE, TRUNCATE TABLE, ALTER
TABLE, or DROP INDEX operations
Deprecated and ignored in MariaDB
innodb_adaptive_max_sleep_delay - 150000
10.5 and removed in MariaDB 10.6.
Specific to MySQL's memcached,
innodb_api_* - *
removed in MariaDB 10.2.
MariaDB has an extra mode, 3 , for
skipping the rollback of connected
innodb_autoinc_lock_mode 1 2 transactions. MySQL defaults to
row-based replication, so can safely
use 2 .
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_buffer_pool_instances - 1
since the original reasons for
introducing no longer apply.
fullcrc32 permits encryption to be
innodb_checksum_algorithm full_crc32 crc32 supported over a SPATIAL INDEX,
which crc32 does not support.
Deprecated option removed in
innodb_checksums ON -
MySQL.
Deprecated and ignored in MariaDB
innodb_commit_concurrency - 0
10.5 and removed in MariaDB 10.6.
Introduced with MariaDB's InnoDB
innodb_compression_* * -
compression.
Deprecated and ignored in MariaDB
innodb_concurrency_tickets - 5000
10.5 and removed in MariaDB 10.6.
innodb_deadlock_report Full - How to report deadlocks.
MySQL option that automatically
configures various settings if the
innodb_dedicated_server - OFF
server is a dedicated InnoDB
database server.
Default encryption key id used for
innodb_default_encryption_key_id 1 - table encryption. See Data at Rest
Encryption.
MariaDB can defragment InnoDB
innodb_defragment * -
tablespaces.
Used to search for tablespace files
innodb_directories - (empty) when moving or restoring a new
location.

1695/3812
Tell InnoDB to stop any writes to
innodb_disallow_writes OFF -
disk.
See MariaDB's Data at Rest
innodb_encrypt_* 1 -
Encryption.
MariaDB's fatal semaphore timeout
innodb_fatal_semaphore_wait_threshold 600 -
is configurable.
MariaDB InnoDB flushing method by
default on Unix systems bypasses
innodb_flush_method O_DIRECT fsync
the file system cache for improved
performance in most cases.
MySQL 8 by default now assumes
innodb_flush_neighbors 1 0
the use of an SSD device.
If set to 1 in MariaDB (0 is default)
CREATE TABLEs without a primary
innodb_force_primary_key OFF - or unique key where all keyparts are
NOT NULL will not be accepted, and
will return an error.
Up to what percentage of dirty pages
in MariaDB should be flushed when
innodb_idle_flush_pct 100 -
InnoDB finds it has spare resources
to do so.
MariaDB has support for data
innodb_immediate_scrub_data_uncompressed OFF -
scrubbing.
See Instant ADD COLUMN for
innodb_instant_alter_column_allowed add_drop_reorder -
InnoDB.
Deprecated option in MariaDB for
disabling gap locking for searches
innodb_locks_unsafe_for_binlog OFF - and index scans. Deprecated in
MariaDB, use READ COMMITTED
transaction isolation instead.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6,
innodb_log_checksums - ON as there is no reason to allow
checksums to be disabled on the
redo log.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_log_compressed_pages - ON
as part of the InnoDB redo log
performance improvements.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_log_files_in_group - 2
as part of the InnoDB redo log
performance improvements.
MySQL variables for constraining
innodb_log_spin_* - * CPU usage while waiting for flushed
redo.
MySQL variable for constraining
innodb_log_wait_for_flush_spin_hwm - * CPU usage while waiting for flushed
redo.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct 75 90
90.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct_lwm 0 10
10.
MariaDB 10.2 reduced the limit for
innodb_max_undo_log_size 10485760 1073741824 when an undo tablespace is marked
for truncation.
In most systems, autosized based
on the table_open_cache setting,
innodb_open_files Autosized (2000) Autosized (4000)
which differs between MariaDB and
MySQL.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_page_cleaners - 1 as the original reasons for for
splitting the buffer pool have mostly
gone away.
MariaDB includes the Facebook
innodb_prefix_index_cluster_optimization OFF -
prefix index queries optimization.
MySQL option for writing DDL logs
innodb_print_ddl_logs - OFF
to stderr.
Whether to set
innodb_read_only_compressed ON - ROW_FORMAT=COMPRESSED
tables to read-only.
MySQL 8 has also now introduced
redo log encryption, but used a
innodb_redo_log_encrypt - OFF
different name. The equivalent option
in MariaDB is innodb_encrypt_log.
Deprecated and ignored in MariaDB
innodb_replication_delay - 0
10.5 and removed in MariaDB 10.6.
MariaDB changed the default from 6
innodb_spin_wait_delay 4 6 to 4 based on extensive
benchmarking.
MariaDB option to control the
innodb_stats_modified_counter 0 -
calculation of new statistics.
1696/3812
Deprecated MariaDB option for
innodb_stats_sample_pages 8 - control over index distribution
statistics.
Enabling gives a larger sample of
pages for larger tables for the
innodb_stats_traditional ON -
purposes of index statistics
calculation.
Deprecated and ignored in MariaDB
innodb_sync_array_size - 1
10.5 and removed in MariaDB 10.6.
Deprecated and ignored in MariaDB
innodb_thread_concurrency - 0
10.5 and removed in MariaDB 10.6.
Deprecated and ignored in MariaDB
innodb_thread_sleep_delay - 10000
10.5 and removed in MariaDB 10.6.
MySQL option for encrypting undo
innodb_undo_log_encrypt - OFF logs residing in separate undo
tablespaces.
MySQL 8 changes the default to
innodb_undo_log_truncate OFF ON ON, marking larger undo logs for
truncation.
Number of tablespace files used for
dividing up the undo logs. MySQL 8
innodb_undo_tablespaces 0 2 has deprecated this setting, and
increased the default (and minimum)
to 2.
Atomic writes are a faster alternative
to innodb_doublewrite and MariaDB
innodb_use_atomic_writes ON -
automatically detects when
supporting SSD cards are used.
MySQL uses this variable to set the
internal_tmp_disk_storage_engine - INNODB storage engine for on-disk internal
temporary tables.
MySQL and MariaDB use different
formats for temporary tables. In
internal_tmp_mem_storage_engine - TEMPTABLE MariaDB, the
aria_used_for_temp_tables performs
a similar function.
Maximum size in bytes of the query
join_buffer_space_limit 2097152 - buffer. See block-based join
algorithms.
For determining the join algorithms.
join_cache_level 2 -
See block-based join algorithms
Size of the buffer for the index
key_buffer_size 134217728 8388608 blocks used by MyISAM tables and
shared for all threads.
Number of hash buckets for open
key_cache_file_hash_size 512 -
and changed files.
The number of segments in a key
key_cache_segments 0 -
cache. See Segmented Key Cache.
Whether MySQL 8's keyring
keyring_operations - ON
operations are enabled.
MariaDB and MySQL have different
last_gtid - empty
GTID implementations.
MySQL no longer supports LOAD
local_infile ON OFF
DATA LOCAL by default.
MariaDB has reduced the timeout for
lock_wait_timeout 86400 31536000
acquiring metadata locks.
MySQL 8 enables the binary log by
log_bin OFF ON
default.
MariaDB setting for whether or not
log_bin_compress OFF -
the binary log can be compressed.
Minimum length of sql statement (in
statement mode) or record (in row
log_bin_compress_min_len 256 - mode) that can be compressed. See
Compressing Events to Reduce Size
of the Binary Log.
MySQL-only variable showing
log_bin_use_v1_row_events - OFF whether or not MySQL's version 2
binary logging format is being used.
Disable logging of certain
log_disabled_statements sp -
statements to the general log.
Components to enable for MySQL
log_error_services - log_filter_internal; log_sink_internal
error logging.
MySQL variable for setting verbosity
log_error_verbosity - 3 of error, warning, and note
messages in the error log.
MySQL 8 has by default enabled
log_slave_updates OFF ON binary logging of updates a slave
receives from a master.
MariaDB logs slow admin
log_slow_admin_statements ON OFF statements to the slow query log by
default.

1697/3812
Disable logging of certain
log_slow_disabled_statements admin,call,slave,sp -
statements to the slow query log.
admin, filesort, filesort_on_disk,
full_join, full_scan, query_cache,
log_slow_filter - For slow query log filtering.
query_cache_miss, tmp_table,
tmp_table_on_disk
Limits the number of queries logged
log_slow_rate_limit 1 -
to the slow query log.
MariaDB logs slow slave statements
log_slow_slave_statements ON OFF
to the slow query log by default.
Controls information to be added to
log_slow_verbosity empty - the slow query log. See also Slow
Query Log Extended Statistics.
MySQL setting for controlling
log_statements_unsafe_for_binlog - ON whether binlog warnings are written
to the error log.
MySQL variables with settings for
log_syslog* platform-dependent -
writing to syslog.
Size in bytes of the transaction
log_tc_size 24576 - coordinator log, defined in multiples
of 4096.
MySQL-only variable for limiting the
number of statements without
log_throttle_queries_not_using_indexes - 0
indexes written to the slow query
log.
MySQL-only variable controlling the
log_timestamps - UTC timezone for certain logging
conditions.

MySQL 8 has replaced with


log_warnings 2 -
log_error_verbosity .

MySQL variable for assigning roles


mandatory_roles - (empty)
to all users.
Whether slave logs master status
master_info_repository - TABLE and connection info to a table or a
file.
max_allowed_packet 16M 64M
Specifies the maximum number of
messages stored for display by
max_error_count 64 1024
SHOW ERRORS and SHOW
WARNINGS statements.
MySQL renamed the
max_execution_time - 0
max_statement_time variable.
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
max_length_for_sort_data 64 1024
these are added to the sort key. This
can speed up the sort as there's no
need 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.
Maximum size for parameter values
sent with
max_long_data_size 16777216 -
mysql_stmt_send_long_data().
Removed in MySQL 5.6.
Maximum number of failed
max_password_errors 4294967295 - connections attempts before no
more are permitted.
Maximum points_per_circle for
max_points_in_geometry - 65536 MySQL's ST_Buffer_Strategy()
function.
Maximum number of iterations when
max_recursive_iterations 4294967295 -
executing recursive queries.
max_relay_log_size 1073741824 0 Can be set by session in MariaDB.
The most key seeks required when
searching with an index, regardless
4294967295 (32-bit) or of the actual index cardinality. If this
max_seeks_for_key 4294967295
18446744073709547520 (64-bit) value is set lower than its default and
maximum, indexes will tend to be
preferred over table scans.
Amount of memory a single user
max_session_mem_used 9223372036854775807 -
session is allowed to allocate.
Maximum time in seconds that a
query can execute before being
max_statement_time 0 - aborted. MySQL used to have a
variable of this name before
renaming it max_execution_time .
max_tmp_tables 32 - Unused variable removed in MySQL.

1698/3812
Read lock requests will be permitted
4294967295 (32-bit) or
max_write_lock_count 4294967295 for processing after this many write
18446744073709547520 (64-bit)
locks.
Size of buffer to use when using
mrr_buffer_size 262144 - multi-range read with range access.
See Multi Range Read optimization.
Block size used for MyISAM index
myisam_block_size 1024 -
pages.
myisam_recover_options BACKUP,QUICK OFF MyISAM recovery mode.
Size in bytes of the buffer allocated
myisam_sort_buffer_size 134216704 8388608 when creating or sorting indexes on
a MyISAM table.
Whether MySQL's authentication
mysql_native_password_proxy_users - OFF
plugin supports proxy users. I
Causes MariaDB to use the MySQL-
5.6 low level formats for TIME,
mysql56_temporal_format ON
DATETIME and TIMESTAMP
instead of the MariaDB 5.3+ version.
Used for backward-compatibility with
new - OFF
MySQL 4.1, not present in MariaDB.
mysqlx+* - * MySQL's X plugin related variables.
Sets the n-gram token size for
ngram_token_size - 2
MySQL's n-gram full-text parser.
MySQL settting for specifying
offline_mode - OFF whether the server should run in
offline mode.
old_alter_table DEFAULT OFF An alias for alter_algorithm.
Used for getting MariaDB to emulate
behavior from an old version of
old_mode Empty string -
MySQL or MariaDB. See OLD
Mode.
MySQL 8 is no longer compatible
old_passwords OFF - with the old pre-MySQL 4.1 form of
password hashing.
Controls number of record samples
optimizer_selectivity_sampling_limit 100 -
to check condition selectivity.
A series of flags for controlling the
optimizer_switch See details query optimizer. MariaDB has
introduced a number of new settings.
MySQL has more settings for
optimizer_trace_* - *
optimizer tracing.
Controls which statistics can be
optimizer_use_condition_selectivity 4 - used by the optimizer when looking
for the best query execution plan.
Used by MySQL 8 for delaying
original_commit_timestamp - *
replication.
4294967295 (32-bit) or MySQL variable for limiting memory
parser_max_mem_size -
18446744073709547520 (64-bit) available to the parser.
Controls reuse of previous
password_* - *
passwords in MySQL.
The Performance Schema is off by
performance_schema OFF ON
default in MariaDB.
Many performance schema variables
are autoset in MySQL, and MySQL
performance_schema_*
has a different version, with
additional variables.
plugin_maturity One less than the server maturity - Minimum acceptable plugin maturity.
Time in seconds between sending
progress_report_time 5 - progress reports to the client for
time-consuming statements.
Enable proxy protocol for these
proxy_protocol_networks (empty) -
source networks.
Size in bytes of the extra blocks
allocated during query parsing and
query_alloc_block_size 16384 8192
execution (after query_prealloc_size
is used up).
MySQL has removed the query
query_cache_* * -
cache.
Size in bytes of the persistent buffer
for query parsing and execution,
query_prealloc_size 24576 8192
allocated on connect and freed on
disconnect.
MySQL-only variable setting a limit
range_optimizer_max_mem_size - 8388608 on the range optimizer's memory
usage.
MySQL-only variable for determining
rbr_exec_mode - STRICT
the handling of certain key errors.
Permits restricting the speed at
read_binlog_speed_limit 0 - which the slave reads the binlog from
the master.
1699/3812
Memory and time limits for regular
regexp_* - *
expression matching operations.
MySQL-only variable determining
relay_log_info_repository - TABLE whether the slave's position in the
relay logs is written to a file or table.
Tells the slave to reproduce
replicate_annotate_row_events ON - annotate_rows_events received from
the master in its own binary log.
replicate_do_db empty string - See Dynamic Replication Variables.

replicate_do_table empty string - See Dynamic Replication Variables.


See Selectively skipping replication
replicate_events_marked_for_skip replicate -
of binlog events.
replicate_ignore_db empty string - See Dynamic Replication Variables.
replicate_ignore_table empty string - See Dynamic Replication Variables.
replicate_wild_do_table empty string - See Dynamic Replication Variables.
replicate_wild_ignore_table empty string - See Dynamic Replication Variables.
Determine whether the server returns
result_metadata - FULL result set metadata for connections
where this is optional.
See Non-semi-join subquery
rowid_merge_buff_size 8388608 -
optimizations.
Minimum data in bytes read from the
rpl_read_size - 8192
binary and relay log files.
MariaDB includes semisynchronous
rpl_semi_sync_* - - replication without the need to install
a plugin.
Controls the time that STOP SLAVE
rpl_stop_slave_timeout - 31536000
waits before timing out.
The S3 storage engine is only
s3_* * -
available in MariaDB.
Limits the number of schema
schema_definition_cache - 256 definition objects kept in the
dictionary object cache.
secure_auth ON - Removed in MySQL.
MariaDB-only option permitting the
secure_timestamp NO - restricting of direct setting of a
session timestamp..
MySQL-only variable for use in
server_id_bits - server_id
MySQL Cluster.
MySQL-only variable containing the
server_uuid - UUID
UUID.
MySQL-only variables for tracking
gtid changes. MariaDB and
session_track_gtids - OFF
MySQL's gtid implementation is
different.
MySQL-only variable determining
sha256_password_proxy_users - OFF whether the sha256_password plugin
supports proxy users.
Option to cause SHOW CREATE
show_create_table_verbosity - OFF TABLE to display ROW_FORMAT in
all cases.
MySQL-only variable for determining
whether SHOW CREATE TABLE
show_old_temporals - OFF
output should include comments for
old format temporal columns.
skip_parallel_replication OFF - See parallel replication.
See Selectively skipping replication
skip_replication OFF -
of binlog events.
slave_allow_batching - OFF MySQL-only replication variable.
slave_checkpoint_group - 512 MySQL-only replication variable.
slave_checkpoint_period - 300 MySQL-only replication variable.
Modes for how replication of DDL
slave_ddl_exec_mode IDEMPOTENT -
events should be executed.
slave_domain_parallel_threads 0 - For configuring parallel replication.
slave_net_timeout 3600 60 MySQL reduced the timeout to 60s.
slave_parallel_max_queued 131072 - For configuring parallel replication.
Controls what transactions are
slave_parallel_mode optimistic - applied in parallel when using
parallel_replication.
slave_parallel_threads 0 - For configuring parallel replication.
slave_parallel_type - DATABASE MySQL-only replication variable.
slave_pending_jobs_size_max - 16777216 MySQL-only replication variable.
slave_preserve_commit_order - OFF MySQL-only replication variable.
slave_rows_search_algorithms - INDEX_SCAN, HASH_SCAN MySQL-only replication variable.

1700/3812
See Running triggers on the slave for
slave_run_triggers_for_rbr NO Row-based events for a description
and use-case for this setting.
When an error occurs during a
transaction on the slave, replication
usually halts. By default,
transactions that caused a deadlock
or elapsed lock wait timeout will be
slave_transaction_retry_errors 1213,1205 -
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 to
this variable.
Interval in seconds for the slave SQL
thread to retry a failed transaction
slave_transaction_retry_interval 0 - due to a deadlock, elapsed lock wait
timeout or an error listed in
slave_transaction_retry_errors.
The default sort buffer allocated has
sort_buffer_size 2097152 262144
been reduced in MySQL.
Adds an implicit IF EXISTS to
ALTER, RENAME and DROP of
sql_if_exists OFF -
TABLES, VIEWS, FUNCTIONS and
PACKAGES
ONLY_FULL_GROUP_BY,
STRICT_TRANS_TABLES, STRICT_TRANS_TABLES,
ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_IN_DATE,
sql_mode See SQL Mode.
NO_AUTO_CREATE_USER, NO_ZERO_DATE,
NO_ENGINE_SUBSTITUTION ERROR_FOR_DIVISION_BY_ZERO,
NO_ENGINE_SUBSTITUTION
Whether FIPS mode is enabled on
ssl_fips_mode - OFF
the server side.
standard_compliant_cte ON - See Common Table Expressions.
Alias for default_storage_engine,
storage_engine InnoDB -
removed in MySQL.
In MariaDB, when password
validation plugins are enabled, reject
strict_password_validation ON -
passwords that cannot be validated
(passwords specified as a hash).
Limits the number of stored program
stored_program_definition_cache - 256 definition objects kept in the
dictionary object cache.
MySQL variable for prohibiting client
super_read_only - OFF updates from users with the SUPER
privilege.
MySQL synchronizes all actions to
sync_binlog 0 1 the binary log before they are
committed.
.frm files have been removed in
sync_frm 1 -
MySQL.
MariaDB has System-Versioned
system_versioning_alter_history ERROR -
Tables
MariaDB has System-Versioned
system_versioning_asof DEFAULT -
Tables
Number of table definitions that can
table_definition_cache 400 -1 (autosized)
be cached.
Maximum number of table cache
table_open_cache_instances 8 16
instances.
Limits the number of tablespace
tablespace_definition_cache - 256 definition objects kept in the
dictionary object cache.
Interval, in seconds, between when
successive keep-alive packets are
tcp_keepalive_interval 0 -
sent if no acknowledgement is
received.
Number of unacknowledged probes
to send before considering the
tcp_keepalive_probes 0 -
connection dead and notifying the
application layer.
Set the TCP_NODELAY option
tcp_keepalive_time 0 - (disable Nagle's algorithm) on
socket.
Timeout, in milliseconds, with no
tcp_nodelay 1 - activity until the first TCP keep-alive
packet is sent.
Limits the RAM used by MySQL's
temptable_max_ram - 1GB
TempTable storage engine.
MariaDB uses an improved thread
thread_cache_size Autosized -1 (autosized)
pool .
thread_concurrency 10 - Removed in MySQL 5.7.
Better precision for the data in the
thread_pool_dedicated_listener 0 - Information Schema
THREADPOOL_QUEUES Table.
1701/3812
Better precision for the data in the
thread_pool_exact_stats 0 - Information Schema
THREADPOOL_QUEUES Table.
thread_pool_idle_timeout 60 - See Using the Thread Pool .
thread_pool_max_threads 65536 - See Using the Thread Pool .
Windows-only. See Using the
thread_pool_min_threads 1 -
Thread Pool .
thread_pool_oversubscribe 3 - See Using the Thread Pool .
thread_pool_prio_kickup auto - See Using the Thread Pool .
thread_pool_priority auto - See Using the Thread Pool .
See Using the Thread Pool . *Only
thread_pool_size Number of processors 16* available in MySQL with a
commercial plugin.
See Using the Thread Pool . *Only
thread_pool_stall_limit 500 6* available in MySQL with a
commercial plugin.
thread_stack 299008 Varies See Using the Thread Pool .
time_format %H:%i:%s - Removed in MySQL.
timed_mutexes OFF - Removed in MySQL.
Max size for data for an internal
tmp_disk_table_size 18446744073709551615 - temporary on-disk MyISAM or Aria
table.
tmp_memory_table_size 16777216 - Alias for tmp_table_size.
Variable for enabling batching of
transaction_allow_batching - OFF statements within the same
transaction in MySQL Cluster.
The MariaDB equivalent is
transaction_isolation - REPEATABLE-READ
tx_isolation.
The MariaDB equivalent is
transaction_read_only - OFF
tx_read_only.
transaction_write_set_extraction - OFF Unused MySQL-only variable.
The MySQL equivalent is
tx_isolation REPEATABLE-READ -
transaction_isolation.
The MySQL equivalent is
tx_read_only OFF -
transaction_read_only.
Controls the use of engine-
use_stat_tables preferably_for_queries -
independent table statistics.
Whether to activate MariaDB's User
userstat OFF - Statistics implementation, not
available in MySQL.
Version of the zlib library compiled
version_compile_zlib - *
in.
version_malloc_library * - Version of the used malloc library.
Permits seeing exactly which
version_source_revision Varies - version of the source was used for a
build.
version_ssl_library * - Version of the used TLS library.
MySQL option allowing safety to be
windowing_high_use_precision - * sacrificed for speed in window
function calculations.
Galera cluster is only available in
wsrep_* * -
MariaDB.
Variable MariaDB 10.8 MySQL 8.0 Notes

See Also
System Variable Differences Between MariaDB 10.8 and MySQL 8.0

2.1.14.1.11.2 System Variable Differences


Between MariaDB 10.8 and MySQL 8.0
Contents
1. Comparison Table
2. See Also

The following is a comparison of variables that either appear only in MariaDB 10.8 or MySQL 8.0, or have different
default settings in MariaDB 10.8, and MySQL 8.0. The releases MariaDB 10.8.3 and MySQL 8.0.11, with only default
plugins enabled, were used for the comparison. Note that MySQL 8 is an 'evergreen' release, so features may be added
or removed in later releases.

1702/3812
Comparison Table
Variable MariaDB 10.8 Default MySQL 8.0 Default Notes
Determines whether to automatically
activate_all_roles_on_login - OFF
activate roles on login.
MariaDB 10.3 introduced new
ALTER TABLE ALGORITHM
clauses to avoid slow copies in
alter_algorithm DEFAULT -
certain instances. This variable
allows setting this if no ALGORITHM
clause is specified.
Percentage of rows from the table
analyze_sample_percentage 100.0000 - ANALYZE TABLE will sample to
collect table statistics.
The Aria storage engine is only
aria_* * -
available in MariaDB.
Whether to automatically generate
auto_generate_certs - ON
SSL key and certificate files.
Determines whether ALTER TABLE
avoid_temporal_upgrade - OFF implicitly upgrades temporal
columns.
MariaDB and MySQL have different
back_log Autosized Autosized
autosizing algorithms.
Introduced in MariaDB 5.3 for
binlog-annotate-row-events ON - replicating between MariaDB 5.3 and
MySQL/MariaDB 5.1.
For use in MariaDB's parallel
binlog_commit_wait_count 0 -
replication.
For use in MariaDB's parallel
binlog_commit_wait_usec 100000 -
replication.
MySQL-only variable for controlling
binlog_error_action ABORT_SERVER what happens when the server
cannot write to the binary log.
Sets the binary log expiration period
binlog_expire_logs_seconds 0 2592000
in seconds
For setting the size of the file cache
binlog_file_cache_size 16184 -
for the binary log.
MariaDB and MySQL have differing
binlog_format MIXED ROW
binary log formats.
MySQL-only variable for controlling
binlog_group_commit_sync_delay 0 the wait time before synchronizing
the binary log file to disk.
MySQL-only variable for setting the
maximum number of transactions to
binlog_group_commit_sync_no_delay_count 0 wait for before aborting the current
binlog_group_commit_sync_delay
delay.
MySQL-only GTID variable.
binlog_gtid_simple_recovery - ON MariaDB's GTID implementation is
different.
Specifies a timeout for reading
transactions from the flush queue
binlog_max_flush_queue_time - 0
before continuing with group commit
and syncing log to disk.
For optimized kernel thread
binlog_optimize_thread_scheduling ON -
scheduling.
Determines whether transactions
binlog_order_commits - ON
may be committed in parallel.
Determines the amount of table
binlog_row_metadata NO_LOG MINIMAL metadata added to the binary log
with row-based logging.
Permits an alternative binlog format
binlog_row_value_options - (empty)
for JSON document updates.
MySQL-only variable for logging
binlog_rows_query_log_events - OFF extra information in row-based
logging.
Maximum number of row hashes
binlog_transaction_dependency_history_size - 25000 kept for looking up transactions that
last modified a given row.
For determining how to best use the
binlog_transaction_dependency_tracking - COMMIT_ORDER
slave's multithreaded applier.
MySQL-only variable for controlling
block_encryption_mode - aes-128-ecb the block encryption mode for block-
based algorithms.
For use with MySQL's SHA-256
caching_sha2_password* - *
authentication with caching.
MySQL 8.0 defaults to the utf8mb4
character_set_* latin1 or utf8 utf8mb4
character set.

1703/3812
Permits disabling constraint checks,
for example when loading a table
check_constraint_checks ON -
that violates some constraints that
you plan to fix later.
MySQL-only variable for controlling
whether the server performs proxy
check_proxy_users OFF
user mapping for authentication
plugins.
MySQL 8.0 defaults to the utf8mb4
collation_* latin1_swedish_ci or utf8_general_ci utf8mb4_0900_ai_ci
character set.
MariaDB supports Storage-engine
column_compression_threshold 100 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_level 6 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_strategy DEFAULT_STRATEGY -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_wrap OFF -
Independent Column Compression.
When MySQL 8.0 introduced
common table expressions they
cte_max_recursion_depth - 1000 used a different name. MariaDB's
variable is called
max_recursive_iterations.
Unused variable removed in MySQL
date_format %Y-%m-%d -
8.0
Unused variable removed in MySQL
datetime_format %Y-%m-%d -
8.0
The Aria storage engine is only
deadlock_search_depth_long 15 -
available in MariaDB.
The Aria storage engine is only
deadlock_search_depth_short 4 -
available in MariaDB.
The Aria storage engine is only
deadlock_timeout_long 50000000 -
available in MariaDB.
The Aria storage engine is only
deadlock_timeout_short 10000 -
available in MariaDB.
Disable system thread alarm calls,
debug_no_thread_alarm OFF -
for debugging or testing.
MySQL 8 introduced a new
default_authentication_plugin - caching_sha2_password
authentication plugin.
For internal use in MySQL 8
default_collation_for_utf8mb4 - utf8mb4_0900_ai_ci
replication.
For use with MariaDB's multi-source
default_master_connection empty -
replication.
MariaDB defaults to password
default_password_lifetime 0 360
expiration off.
For handling incompatibilities
default_regex_flags empty - between MariaDB's PCRE and the
old regex library.
Default storage engine used for
default_tmp_storage_engine empty InnoDB tables created with CREATE
TEMPORARY TABLE.
MySQL-only variable for disabling
disabled_storage_engines empty
specific storage engines.
MariaDB password expiration is off
by default, and by default does not
disconnect_on_expired_password OFF ON
disconnect a client when a password
has expired.
MariaDB enables table and
encrypt_binlog OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_files OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_disk_tables OFF -
tablespace encryption.
MySQL-only variable for adding end
end_markers_in_json - OFF
markers to JSON output.
MariaDB and MySQL have different
enforce_gtid_consistency - OFF
GTID implementations.
Forces the use of a particular
enforce_storage_engine none
storage engine for new tables.
Variable for tuning when the
optimizer should switch from using
eq_range_index_dive_limit 0 200
index dives to index statistics for
qualifying rows estimation.
MySQL enables the event scheduler
event_scheduler OFF ON
by default.
Used for determining expensive
expensive_subquery_limit 100 -
queries for optimization.
MySQL 8 disables the old
explicit_defaults_for_timestamp OFF ON
timestamp behavior.

1704/3812
Introduced in the MariaDB 5.1
extra_max_connections 1 -
threadpool.
Introduced in the MariaDB 5.1
extra_port 0 -
threadpool.
MariaDB increases the maximum
group_concat_max_len 1048576 1024 length for a GROUP_CONCAT()
result from 1K to 1M.
MariaDB and MySQL have different
gtid_binlog_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_binlog_state empty -
GTID implementations.
MariaDB and MySQL have different
gtid_cleanup_batch_size 64 -
GTID implementations.
MariaDB and MySQL have different
gtid_current_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_domain_id 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_executed - empty
GTID implementations.
MariaDB and MySQL have different
gtid_executed_compression_period - 1000
GTID implementations.
MariaDB and MySQL have different
gtid_ignore_duplicates OFF -
GTID implementations.
MariaDB and MySQL have different
gtid_mode - OFF
GTID implementations.
MariaDB and MySQL have different
gtid_next - AUTOMATIC
GTID implementations.
MariaDB and MySQL have different
gtid_owned - empty
GTID implementations.
MariaDB and MySQL have different
gtid_pos_auto_engines empty -
GTID implementations.
MariaDB and MySQL have different
gtid_purged - empty
GTID implementations.
MariaDB and MySQL have different
gtid_seq_no 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_slave_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_strict_mode OFF -
GTID implementations.
MySQL has removed the ENCRYPT
have_crypt YES -
function.
MariaDB's version indicates whether
YaSSL or openssl was used.
have_openssl
MySQL's is a synonym for
have_ssl .

MySQL has removed the query


have_query_cache YES -
cache.
Whether MySQL's statement
have_statement_timeout - execution timeout feature is
available.
MySQL has removed symlink
have_symlink YES DISABLED
support.
Added when MySQL 8 introduced
histogram_generation_max_mem_size - 20000000 Histogram-based Statistics.
MariaDB uses histogram_size
MariaDB introduced Histogram-
histogram_size 0 -
based Statistics.
MariaDB introduced Histogram-
histogram_type SINGLE_PREC_HB -
based Statistics.
Time in seconds that the server
idle_readonly_transaction_timeout 0 -
waits for idle read-only transactions.
Time in seconds that the server
idle_transaction_timeout 0 -
waits for idle transactions.
Time in seconds that the server
idle_write_transaction_timeout 0 -
waits for idle write transactions.
ignore_builtin_innodb OFF - Ignored and removed in MySQL 8.
Controls the Conversion of Big IN
in_predicate_conversion_threshold 1000 - Predicates Into Subqueries
optimization.
Set to 1 if you are in a transaction,
in_transaction 0 -
and 0 if not.
Time until MySQL Information
information_schema_stats_expiry - 86400
Schema cached statistics expire.
Adaptive flushing is enabled when
this this low water mark percentage
innodb_adaptive_flushing_lwm 10.000000 10 of the redo log capacity is reached.
MariaDB's variable is a double,
MySQL's an integer.
1705/3812
Defaulting to OFF is a performance
improvement especially for DROP
innodb_adaptive_hash_index OFF ON
TABLE, TRUNCATE TABLE, ALTER
TABLE, or DROP INDEX operations
Deprecated and ignored in MariaDB
innodb_adaptive_max_sleep_delay - 150000
10.5 and removed in MariaDB 10.6.
Specific to MySQL's memcached,
innodb_api_* - *
removed in MariaDB 10.2.
MariaDB has an extra mode, 3 , for
skipping the rollback of connected
innodb_autoinc_lock_mode 1 2 transactions. MySQL defaults to
row-based replication, so can safely
use 2 .
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_buffer_pool_instances - 1
since the original reasons for
introducing no longer apply.
fullcrc32 permits encryption to be
innodb_checksum_algorithm full_crc32 crc32 supported over a SPATIAL INDEX,
which crc32 does not support.
Deprecated option removed in
innodb_checksums ON -
MySQL.
Deprecated and ignored in MariaDB
innodb_commit_concurrency - 0
10.5 and removed in MariaDB 10.6.
Introduced with MariaDB's InnoDB
innodb_compression_* * -
compression.
Deprecated and ignored in MariaDB
innodb_concurrency_tickets - 5000
10.5 and removed in MariaDB 10.6.
innodb_deadlock_report Full - How to report deadlocks.
MySQL option that automatically
configures various settings if the
innodb_dedicated_server - OFF
server is a dedicated InnoDB
database server.
Default encryption key id used for
innodb_default_encryption_key_id 1 - table encryption. See Data at Rest
Encryption.
MariaDB can defragment InnoDB
innodb_defragment * -
tablespaces.
Used to search for tablespace files
innodb_directories - (empty) when moving or restoring a new
location.
Tell InnoDB to stop any writes to
innodb_disallow_writes OFF -
disk.
See MariaDB's Data at Rest
innodb_encrypt_* 1 -
Encryption.
MariaDB's fatal semaphore timeout
innodb_fatal_semaphore_wait_threshold 600 -
is configurable.
MariaDB InnoDB flushing method by
default on Unix systems bypasses
innodb_flush_method O_DIRECT fsync
the file system cache for improved
performance in most cases.
MySQL 8 by default now assumes
innodb_flush_neighbors 1 0
the use of an SSD device.
If set to 1 in MariaDB (0 is default)
CREATE TABLEs without a primary
innodb_force_primary_key OFF - or unique key where all keyparts are
NOT NULL will not be accepted, and
will return an error.
Up to what percentage of dirty pages
in MariaDB should be flushed when
innodb_idle_flush_pct 100 -
InnoDB finds it has spare resources
to do so.
MariaDB has support for data
innodb_immediate_scrub_data_uncompressed OFF -
scrubbing.
See Instant ADD COLUMN for
innodb_instant_alter_column_allowed add_drop_reorder -
InnoDB.
Deprecated option in MariaDB for
disabling gap locking for searches
innodb_locks_unsafe_for_binlog OFF - and index scans. Deprecated in
MariaDB, use READ COMMITTED
transaction isolation instead.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6,
innodb_log_checksums - ON as there is no reason to allow
checksums to be disabled on the
redo log.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_log_compressed_pages - ON
as part of the InnoDB redo log
performance improvements.

1706/3812
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_log_files_in_group - 2
as part of the InnoDB redo log
performance improvements.
MySQL variables for constraining
innodb_log_spin_* - * CPU usage while waiting for flushed
redo.
MySQL variable for constraining
innodb_log_wait_for_flush_spin_hwm - * CPU usage while waiting for flushed
redo.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct 75 90
90.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct_lwm 0 10
10.
MariaDB 10.2 reduced the limit for
innodb_max_undo_log_size 10485760 1073741824 when an undo tablespace is marked
for truncation.
In most systems, autosized based
on the table_open_cache setting,
innodb_open_files Autosized (2000) Autosized (4000)
which differs between MariaDB and
MySQL.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_page_cleaners - 1 as the original reasons for for
splitting the buffer pool have mostly
gone away.
MariaDB includes the Facebook
innodb_prefix_index_cluster_optimization OFF -
prefix index queries optimization.
MySQL option for writing DDL logs
innodb_print_ddl_logs - OFF
to stderr.
Whether to set
innodb_read_only_compressed ON - ROW_FORMAT=COMPRESSED
tables to read-only.
MySQL 8 has also now introduced
redo log encryption, but used a
innodb_redo_log_encrypt - OFF
different name. The equivalent option
in MariaDB is innodb_encrypt_log.
Deprecated and ignored in MariaDB
innodb_replication_delay - 0
10.5 and removed in MariaDB 10.6.
MariaDB changed the default from 6
innodb_spin_wait_delay 4 6 to 4 based on extensive
benchmarking.
MariaDB option to control the
innodb_stats_modified_counter 0 -
calculation of new statistics.
Deprecated MariaDB option for
innodb_stats_sample_pages 8 - control over index distribution
statistics.
Enabling gives a larger sample of
pages for larger tables for the
innodb_stats_traditional ON - purposes of index statistics
calculation.

Deprecated and ignored in MariaDB


innodb_sync_array_size - 1
10.5 and removed in MariaDB 10.6.
Deprecated and ignored in MariaDB
innodb_thread_concurrency - 0
10.5 and removed in MariaDB 10.6.
Deprecated and ignored in MariaDB
innodb_thread_sleep_delay - 10000
10.5 and removed in MariaDB 10.6.
MySQL option for encrypting undo
innodb_undo_log_encrypt - OFF logs residing in separate undo
tablespaces.
MySQL 8 changes the default to
innodb_undo_log_truncate OFF ON ON, marking larger undo logs for
truncation.
Number of tablespace files used for
dividing up the undo logs. MySQL 8
innodb_undo_tablespaces 0 2 has deprecated this setting, and
increased the default (and minimum)
to 2.
Atomic writes are a faster alternative
to innodb_doublewrite and MariaDB
innodb_use_atomic_writes ON -
automatically detects when
supporting SSD cards are used.
MySQL uses this variable to set the
internal_tmp_disk_storage_engine - INNODB storage engine for on-disk internal
temporary tables.
MySQL and MariaDB use different
formats for temporary tables. In
internal_tmp_mem_storage_engine - TEMPTABLE MariaDB, the
aria_used_for_temp_tables performs
a similar function.

1707/3812
Maximum size in bytes of the query
join_buffer_space_limit 2097152 - buffer. See block-based join
algorithms.
For determining the join algorithms.
join_cache_level 2 -
See block-based join algorithms
Size of the buffer for the index
key_buffer_size 134217728 8388608 blocks used by MyISAM tables and
shared for all threads.
Number of hash buckets for open
key_cache_file_hash_size 512 -
and changed files.
The number of segments in a key
key_cache_segments 0 -
cache. See Segmented Key Cache.
Whether MySQL 8's keyring
keyring_operations - ON
operations are enabled.
MariaDB and MySQL have different
last_gtid - empty
GTID implementations.
MySQL no longer supports LOAD
local_infile ON OFF
DATA LOCAL by default.
MariaDB has reduced the timeout for
lock_wait_timeout 86400 31536000
acquiring metadata locks.
MySQL 8 enables the binary log by
log_bin OFF ON
default.
MariaDB setting for whether or not
log_bin_compress OFF -
the binary log can be compressed.
Minimum length of sql statement (in
statement mode) or record (in row
log_bin_compress_min_len 256 - mode) that can be compressed. See
Compressing Events to Reduce Size
of the Binary Log.
MySQL-only variable showing
log_bin_use_v1_row_events - OFF whether or not MySQL's version 2
binary logging format is being used.
Disable logging of certain
log_disabled_statements sp -
statements to the general log.
Components to enable for MySQL
log_error_services - log_filter_internal; log_sink_internal
error logging.
MySQL variable for setting verbosity
log_error_verbosity - 3 of error, warning, and note
messages in the error log.
MySQL 8 has by default enabled
log_slave_updates OFF ON binary logging of updates a slave
receives from a master.

MariaDB logs slow admin


log_slow_admin_statements ON OFF statements to the slow query log by
default.
Disable logging of certain
log_slow_disabled_statements admin,call,slave,sp -
statements to the slow query log.
admin, filesort, filesort_on_disk,
full_join, full_scan, query_cache,
log_slow_filter - For slow query log filtering.
query_cache_miss, tmp_table,
tmp_table_on_disk
Limits the number of queries logged
log_slow_rate_limit 1 -
to the slow query log.
MariaDB logs slow slave statements
log_slow_slave_statements ON OFF
to the slow query log by default.
Controls information to be added to
log_slow_verbosity empty - the slow query log. See also Slow
Query Log Extended Statistics.
MySQL setting for controlling
log_statements_unsafe_for_binlog - ON whether binlog warnings are written
to the error log.
MySQL variables with settings for
log_syslog* platform-dependent -
writing to syslog.
Size in bytes of the transaction
log_tc_size 24576 - coordinator log, defined in multiples
of 4096.
MySQL-only variable for limiting the
number of statements without
log_throttle_queries_not_using_indexes - 0
indexes written to the slow query
log.
MySQL-only variable controlling the
log_timestamps - UTC timezone for certain logging
conditions.
MySQL 8 has replaced with
log_warnings 2 -
log_error_verbosity .

MySQL variable for assigning roles


mandatory_roles - (empty)
to all users.
Whether slave logs master status
master_info_repository - TABLE and connection info to a table or a
file.

1708/3812
max_allowed_packet 16M 64M
Specifies the maximum number of
messages stored for display by
max_error_count 64 1024
SHOW ERRORS and SHOW
WARNINGS statements.
MySQL renamed the
max_execution_time - 0
max_statement_time variable.
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
max_length_for_sort_data 64 1024
these are added to the sort key. This
can speed up the sort as there's no
need 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.
Maximum size for parameter values
sent with
max_long_data_size 16777216 -
mysql_stmt_send_long_data().
Removed in MySQL 5.6.
Maximum number of failed
max_password_errors 4294967295 - connections attempts before no
more are permitted.
Maximum points_per_circle for
max_points_in_geometry - 65536 MySQL's ST_Buffer_Strategy()
function.
Maximum number of iterations when
max_recursive_iterations 4294967295 -
executing recursive queries.
max_relay_log_size 1073741824 0 Can be set by session in MariaDB.
The most key seeks required when
searching with an index, regardless
4294967295 (32-bit) or of the actual index cardinality. If this
max_seeks_for_key 4294967295
18446744073709547520 (64-bit) value is set lower than its default and
maximum, indexes will tend to be
preferred over table scans.
Amount of memory a single user
max_session_mem_used 9223372036854775807 - session is allowed to allocate.

Maximum time in seconds that a


query can execute before being
max_statement_time 0 - aborted. MySQL used to have a
variable of this name before
renaming it max_execution_time .
max_tmp_tables 32 - Unused variable removed in MySQL.
Read lock requests will be permitted
4294967295 (32-bit) or
max_write_lock_count 4294967295 for processing after this many write
18446744073709547520 (64-bit)
locks.
Size of buffer to use when using
mrr_buffer_size 262144 - multi-range read with range access.
See Multi Range Read optimization.
Block size used for MyISAM index
myisam_block_size 1024 -
pages.
myisam_recover_options BACKUP,QUICK OFF MyISAM recovery mode.
Size in bytes of the buffer allocated
myisam_sort_buffer_size 134216704 8388608 when creating or sorting indexes on
a MyISAM table.
Whether MySQL's authentication
mysql_native_password_proxy_users - OFF
plugin supports proxy users. I
Causes MariaDB to use the MySQL-
5.6 low level formats for TIME,
mysql56_temporal_format ON
DATETIME and TIMESTAMP
instead of the MariaDB 5.3+ version.
Used for backward-compatibility with
new - OFF
MySQL 4.1, not present in MariaDB.
mysqlx+* - * MySQL's X plugin related variables.
Sets the n-gram token size for
ngram_token_size - 2
MySQL's n-gram full-text parser.
MySQL settting for specifying
offline_mode - OFF whether the server should run in
offline mode.
old_alter_table DEFAULT OFF An alias for alter_algorithm.
Used for getting MariaDB to emulate
behavior from an old version of
old_mode Empty string -
MySQL or MariaDB. See OLD
Mode.
MySQL 8 is no longer compatible
old_passwords OFF - with the old pre-MySQL 4.1 form of
password hashing.
Controls number of record samples
optimizer_selectivity_sampling_limit 100 -
to check condition selectivity.
1709/3812
A series of flags for controlling the
optimizer_switch See details query optimizer. MariaDB has
introduced a number of new settings.
MySQL has more settings for
optimizer_trace_* - *
optimizer tracing.
Controls which statistics can be
optimizer_use_condition_selectivity 4 - used by the optimizer when looking
for the best query execution plan.
Used by MySQL 8 for delaying
original_commit_timestamp - *
replication.
4294967295 (32-bit) or MySQL variable for limiting memory
parser_max_mem_size -
18446744073709547520 (64-bit) available to the parser.
Controls reuse of previous
password_* - *
passwords in MySQL.
The Performance Schema is off by
performance_schema OFF ON
default in MariaDB.
Many performance schema variables
are autoset in MySQL, and MySQL
performance_schema_*
has a different version, with
additional variables.
plugin_maturity One less than the server maturity - Minimum acceptable plugin maturity.
Time in seconds between sending
progress_report_time 5 - progress reports to the client for
time-consuming statements.

Enable proxy protocol for these


proxy_protocol_networks (empty) -
source networks.
Size in bytes of the extra blocks
allocated during query parsing and
query_alloc_block_size 16384 8192
execution (after query_prealloc_size
is used up).
MySQL has removed the query
query_cache_* * -
cache.
Size in bytes of the persistent buffer
for query parsing and execution,
query_prealloc_size 24576 8192
allocated on connect and freed on
disconnect.
MySQL-only variable setting a limit
range_optimizer_max_mem_size - 8388608 on the range optimizer's memory
usage.
MySQL-only variable for determining
rbr_exec_mode - STRICT
the handling of certain key errors.
Permits restricting the speed at
read_binlog_speed_limit 0 - which the slave reads the binlog from
the master.
Memory and time limits for regular
regexp_* - *
expression matching operations.
MySQL-only variable determining
relay_log_info_repository - TABLE whether the slave's position in the
relay logs is written to a file or table.
Tells the slave to reproduce
replicate_annotate_row_events ON - annotate_rows_events received from
the master in its own binary log.
replicate_do_db empty string - See Dynamic Replication Variables.
replicate_do_table empty string - See Dynamic Replication Variables.
See Selectively skipping replication
replicate_events_marked_for_skip replicate -
of binlog events.
replicate_ignore_db empty string - See Dynamic Replication Variables.
replicate_ignore_table empty string - See Dynamic Replication Variables.
replicate_wild_do_table empty string - See Dynamic Replication Variables.
replicate_wild_ignore_table empty string - See Dynamic Replication Variables.
Determine whether the server returns
result_metadata - FULL result set metadata for connections
where this is optional.
See Non-semi-join subquery
rowid_merge_buff_size 8388608 -
optimizations.
Minimum data in bytes read from the
rpl_read_size - 8192
binary and relay log files.
MariaDB includes semisynchronous
rpl_semi_sync_* - - replication without the need to install
a plugin.
Controls the time that STOP SLAVE
rpl_stop_slave_timeout - 31536000
waits before timing out.
The S3 storage engine is only
s3_* * -
available in MariaDB.
Limits the number of schema
schema_definition_cache - 256 definition objects kept in the
dictionary object cache.

1710/3812
secure_auth ON - Removed in MySQL.
MariaDB-only option permitting the
secure_timestamp NO - restricting of direct setting of a
session timestamp..
MySQL-only variable for use in
server_id_bits - server_id
MySQL Cluster.
MySQL-only variable containing the
server_uuid - UUID
UUID.
MySQL-only variables for tracking
gtid changes. MariaDB and
session_track_gtids - OFF
MySQL's gtid implementation is
different.
MySQL-only variable determining
sha256_password_proxy_users - OFF whether the sha256_password plugin
supports proxy users.
Option to cause SHOW CREATE
show_create_table_verbosity - OFF TABLE to display ROW_FORMAT in
all cases.
MySQL-only variable for determining
whether SHOW CREATE TABLE
show_old_temporals - OFF
output should include comments for
old format temporal columns.
skip_parallel_replication OFF - See parallel replication.
See Selectively skipping replication
skip_replication OFF -
of binlog events.
slave_allow_batching - OFF MySQL-only replication variable.
slave_checkpoint_group - 512 MySQL-only replication variable.
slave_checkpoint_period - 300 MySQL-only replication variable.
Modes for how replication of DDL
slave_ddl_exec_mode IDEMPOTENT -
events should be executed.
slave_domain_parallel_threads 0 - For configuring parallel replication.
slave_net_timeout 3600 60 MySQL reduced the timeout to 60s.
slave_parallel_max_queued 131072 - For configuring parallel replication.
Controls what transactions are
slave_parallel_mode optimistic - applied in parallel when using
parallel_replication.
slave_parallel_threads 0 - For configuring parallel replication.
slave_parallel_type - DATABASE MySQL-only replication variable.
slave_pending_jobs_size_max - 16777216 MySQL-only replication variable.
slave_preserve_commit_order - OFF MySQL-only replication variable.
slave_rows_search_algorithms - INDEX_SCAN, HASH_SCAN MySQL-only replication variable.
See Running triggers on the slave for
slave_run_triggers_for_rbr NO Row-based events for a description
and use-case for this setting.
When an error occurs during a
transaction on the slave, replication
usually halts. By default,
transactions that caused a deadlock
or elapsed lock wait timeout will be
slave_transaction_retry_errors 1213,1205 -
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 to
this variable.
Interval in seconds for the slave SQL
thread to retry a failed transaction
slave_transaction_retry_interval 0 - due to a deadlock, elapsed lock wait
timeout or an error listed in
slave_transaction_retry_errors.
The default sort buffer allocated has
sort_buffer_size 2097152 262144
been reduced in MySQL.
Adds an implicit IF EXISTS to
ALTER, RENAME and DROP of
sql_if_exists OFF -
TABLES, VIEWS, FUNCTIONS and
PACKAGES
ONLY_FULL_GROUP_BY,
STRICT_TRANS_TABLES, STRICT_TRANS_TABLES,
ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_IN_DATE,
sql_mode See SQL Mode.
NO_AUTO_CREATE_USER, NO_ZERO_DATE,
NO_ENGINE_SUBSTITUTION ERROR_FOR_DIVISION_BY_ZERO,
NO_ENGINE_SUBSTITUTION
Whether FIPS mode is enabled on
ssl_fips_mode - OFF
the server side.
standard_compliant_cte ON - See Common Table Expressions.
Alias for default_storage_engine,
storage_engine InnoDB -
removed in MySQL.

1711/3812
In MariaDB, when password
validation plugins are enabled, reject
strict_password_validation ON -
passwords that cannot be validated
(passwords specified as a hash).
Limits the number of stored program
stored_program_definition_cache - 256 definition objects kept in the
dictionary object cache.
MySQL variable for prohibiting client
super_read_only - OFF updates from users with the SUPER
privilege.
MySQL synchronizes all actions to
sync_binlog 0 1 the binary log before they are
committed.
.frm files have been removed in
sync_frm 1 -
MySQL.
MariaDB has System-Versioned
system_versioning_alter_history ERROR -
Tables
MariaDB has System-Versioned
system_versioning_asof DEFAULT -
Tables
Number of table definitions that can
table_definition_cache 400 -1 (autosized)
be cached.
Maximum number of table cache
table_open_cache_instances 8 16
instances.
Limits the number of tablespace
tablespace_definition_cache - 256 definition objects kept in the
dictionary object cache.
Interval, in seconds, between when
successive keep-alive packets are
tcp_keepalive_interval 0 -
sent if no acknowledgement is
received.
Number of unacknowledged probes
to send before considering the
tcp_keepalive_probes 0 -
connection dead and notifying the
application layer.
Set the TCP_NODELAY option
tcp_keepalive_time 0 - (disable Nagle's algorithm) on
socket.
Timeout, in milliseconds, with no
tcp_nodelay 1 - activity until the first TCP keep-alive
packet is sent.
Limits the RAM used by MySQL's
temptable_max_ram - 1GB
TempTable storage engine.
MariaDB uses an improved thread
thread_cache_size Autosized -1 (autosized)
pool .
thread_concurrency 10 - Removed in MySQL 5.7.
Better precision for the data in the
thread_pool_dedicated_listener 0 - Information Schema
THREADPOOL_QUEUES Table.
Better precision for the data in the
thread_pool_exact_stats 0 - Information Schema
THREADPOOL_QUEUES Table.
thread_pool_idle_timeout 60 - See Using the Thread Pool .
thread_pool_max_threads 65536 - See Using the Thread Pool .
Windows-only. See Using the
thread_pool_min_threads 1 -
Thread Pool .
thread_pool_oversubscribe 3 - See Using the Thread Pool .
thread_pool_prio_kickup auto - See Using the Thread Pool .
thread_pool_priority auto - See Using the Thread Pool .
See Using the Thread Pool . *Only
thread_pool_size Number of processors 16* available in MySQL with a
commercial plugin.
See Using the Thread Pool . *Only
thread_pool_stall_limit 500 6* available in MySQL with a
commercial plugin.
thread_stack 299008 Varies See Using the Thread Pool .
time_format %H:%i:%s - Removed in MySQL.
timed_mutexes OFF - Removed in MySQL.
Max size for data for an internal
tmp_disk_table_size 18446744073709551615 - temporary on-disk MyISAM or Aria
table.
tmp_memory_table_size 16777216 - Alias for tmp_table_size.
Variable for enabling batching of
transaction_allow_batching - OFF statements within the same
transaction in MySQL Cluster.
The MariaDB equivalent is
transaction_isolation - REPEATABLE-READ
tx_isolation.
The MariaDB equivalent is
transaction_read_only - OFF
tx_read_only.
1712/3812
transaction_write_set_extraction - OFF Unused MySQL-only variable.

tx_isolation REPEATABLE-READ - The MySQL equivalent is


transaction_isolation.
The MySQL equivalent is
tx_read_only OFF -
transaction_read_only.
Controls the use of engine-
use_stat_tables preferably_for_queries -
independent table statistics.
Whether to activate MariaDB's User
userstat OFF - Statistics implementation, not
available in MySQL.
Version of the zlib library compiled
version_compile_zlib - *
in.
version_malloc_library * - Version of the used malloc library.
Permits seeing exactly which
version_source_revision Varies - version of the source was used for a
build.
version_ssl_library * - Version of the used TLS library.
MySQL option allowing safety to be
windowing_high_use_precision - * sacrificed for speed in window
function calculations.
Galera cluster is only available in
wsrep_* * -
MariaDB.
Variable MariaDB 10.8 MySQL 8.0 Notes

See Also
System Variable Differences Between MariaDB 10.7 and MySQL 8.0

2.1.14.1.11.3 System Variable Differences


Between MariaDB 10.7 and MySQL 8.0
Contents
1. Comparison Table
2. See Also

The following is a comparison of variables that either appear only in MariaDB 10.7 or MySQL 8.0, or have different
default settings in MariaDB 10.7, and MySQL 8.0. The releases MariaDB 10.7.0 and MySQL 8.0.11, with only default
plugins enabled, were used for the comparison. Note that MySQL 8 is an 'evergreen' release, so features may be added
or removed in later releases.

Comparison Table
Variable MariaDB 10.7 Default MySQL 8.0 Default Notes
Determines whether to automatically
activate_all_roles_on_login - OFF
activate roles on login.
MariaDB 10.3 introduced new
ALTER TABLE ALGORITHM
clauses to avoid slow copies in
alter_algorithm DEFAULT -
certain instances. This variable
allows setting this if no ALGORITHM
clause is specified.
Percentage of rows from the table
analyze_sample_percentage 100.0000 - ANALYZE TABLE will sample to
collect table statistics.
The Aria storage engine is only
aria_* * -
available in MariaDB.
Whether to automatically generate
auto_generate_certs - ON
SSL key and certificate files.
Determines whether ALTER TABLE
avoid_temporal_upgrade - OFF implicitly upgrades temporal
columns.
MariaDB and MySQL have different
back_log Autosized Autosized
autosizing algorithms.
Introduced in MariaDB 5.3 for
binlog-annotate-row-events ON - replicating between MariaDB 5.3 and
MySQL/MariaDB 5.1.
For use in MariaDB's parallel
binlog_commit_wait_count 0 -
replication.
For use in MariaDB's parallel
binlog_commit_wait_usec 100000 -
replication.

1713/3812
MySQL-only variable for controlling
binlog_error_action ABORT_SERVER what happens when the server
cannot write to the binary log.

Sets the binary log expiration period


binlog_expire_logs_seconds 0 2592000
in seconds
For setting the size of the file cache
binlog_file_cache_size 16184 -
for the binary log.
MariaDB and MySQL have differing
binlog_format MIXED ROW
binary log formats.
MySQL-only variable for controlling
binlog_group_commit_sync_delay 0 the wait time before synchronizing
the binary log file to disk.
MySQL-only variable for setting the
maximum number of transactions to
binlog_group_commit_sync_no_delay_count 0 wait for before aborting the current
binlog_group_commit_sync_delay
delay.
MySQL-only GTID variable.
binlog_gtid_simple_recovery - ON MariaDB's GTID implementation is
different.
Specifies a timeout for reading
transactions from the flush queue
binlog_max_flush_queue_time - 0
before continuing with group commit
and syncing log to disk.
For optimized kernel thread
binlog_optimize_thread_scheduling ON -
scheduling.
Determines whether transactions
binlog_order_commits - ON
may be committed in parallel.
Determines the amount of table
binlog_row_metadata NO_LOG MINIMAL metadata added to the binary log
with row-based logging.
Permits an alternative binlog format
binlog_row_value_options - (empty)
for JSON document updates.
MySQL-only variable for logging
binlog_rows_query_log_events - OFF extra information in row-based
logging.
Maximum number of row hashes
binlog_transaction_dependency_history_size - 25000 kept for looking up transactions that
last modified a given row.
For determining how to best use the
binlog_transaction_dependency_tracking - COMMIT_ORDER
slave's multithreaded applier.
MySQL-only variable for controlling
block_encryption_mode - aes-128-ecb the block encryption mode for block-
based algorithms.
For use with MySQL's SHA-256
caching_sha2_password* - *
authentication with caching.
MySQL 8.0 defaults to the utf8mb4
character_set_* latin1 or utf8 utf8mb4
character set.
Permits disabling constraint checks,
for example when loading a table
check_constraint_checks ON -
that violates some constraints that
you plan to fix later.
MySQL-only variable for controlling
whether the server performs proxy
check_proxy_users OFF
user mapping for authentication
plugins.
MySQL 8.0 defaults to the utf8mb4
collation_* latin1_swedish_ci or utf8_general_ci utf8mb4_0900_ai_ci
character set.
MariaDB supports Storage-engine
column_compression_threshold 100 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_level 6 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_strategy DEFAULT_STRATEGY -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_wrap OFF -
Independent Column Compression.
When MySQL 8.0 introduced
common table expressions they
cte_max_recursion_depth - 1000 used a different name. MariaDB's
variable is called
max_recursive_iterations.
Unused variable removed in MySQL
date_format %Y-%m-%d -
8.0
Unused variable removed in MySQL
datetime_format %Y-%m-%d -
8.0
The Aria storage engine is only
deadlock_search_depth_long 15 -
available in MariaDB.
The Aria storage engine is only
deadlock_search_depth_short 4 -
available in MariaDB.

1714/3812
The Aria storage engine is only
deadlock_timeout_long 50000000 -
available in MariaDB.
The Aria storage engine is only
deadlock_timeout_short 10000 -
available in MariaDB.
Disable system thread alarm calls,
debug_no_thread_alarm OFF -
for debugging or testing.
MySQL 8 introduced a new
default_authentication_plugin - caching_sha2_password
authentication plugin.
For internal use in MySQL 8
default_collation_for_utf8mb4 - utf8mb4_0900_ai_ci
replication.
For use with MariaDB's multi-source
default_master_connection empty -
replication.
MariaDB defaults to password
default_password_lifetime 0 360
expiration off.
For handling incompatibilities
default_regex_flags empty - between MariaDB's PCRE and the
old regex library.
Default storage engine used for
default_tmp_storage_engine empty InnoDB tables created with CREATE
TEMPORARY TABLE.
MySQL-only variable for disabling
disabled_storage_engines empty
specific storage engines.
MariaDB password expiration is off
by default, and by default does not
disconnect_on_expired_password OFF ON
disconnect a client when a password
has expired.
MariaDB enables table and
encrypt_binlog OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_files OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_disk_tables OFF -
tablespace encryption.
MySQL-only variable for adding end
end_markers_in_json - OFF
markers to JSON output.
MariaDB and MySQL have different
enforce_gtid_consistency - OFF
GTID implementations.
Forces the use of a particular
enforce_storage_engine none
storage engine for new tables.
Variable for tuning when the
optimizer should switch from using
eq_range_index_dive_limit 0 200
index dives to index statistics for
qualifying rows estimation.
MySQL enables the event scheduler
event_scheduler OFF ON
by default.
Used for determining expensive
expensive_subquery_limit 100 -
queries for optimization.
MySQL 8 disables the old
explicit_defaults_for_timestamp OFF ON
timestamp behavior.
Introduced in the MariaDB 5.1
extra_max_connections 1 -
threadpool.
Introduced in the MariaDB 5.1
extra_port 0 -
threadpool.
MariaDB increases the maximum
group_concat_max_len 1048576 1024 length for a GROUP_CONCAT()
result from 1K to 1M.
MariaDB and MySQL have different
gtid_binlog_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_binlog_state empty -
GTID implementations.
MariaDB and MySQL have different
gtid_cleanup_batch_size 64 -
GTID implementations.
MariaDB and MySQL have different
gtid_current_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_domain_id 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_executed - empty
GTID implementations.
MariaDB and MySQL have different
gtid_executed_compression_period - 1000
GTID implementations.
MariaDB and MySQL have different
gtid_ignore_duplicates OFF -
GTID implementations.
MariaDB and MySQL have different
gtid_mode - OFF
GTID implementations.
MariaDB and MySQL have different
gtid_next - AUTOMATIC
GTID implementations.
MariaDB and MySQL have different
gtid_owned - empty
GTID implementations.

1715/3812
MariaDB and MySQL have different
gtid_pos_auto_engines empty -
GTID implementations.
MariaDB and MySQL have different
gtid_purged - empty
GTID implementations.
MariaDB and MySQL have different
gtid_seq_no 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_slave_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_strict_mode OFF -
GTID implementations.
MySQL has removed the ENCRYPT
have_crypt YES -
function.
MariaDB's version indicates whether
YaSSL or openssl was used.
have_openssl
MySQL's is a synonym for
have_ssl .

MySQL has removed the query


have_query_cache YES -
cache.
Whether MySQL's statement
have_statement_timeout - execution timeout feature is
available.
MySQL has removed symlink
have_symlink YES DISABLED
support.
Added when MySQL 8 introduced
histogram_generation_max_mem_size - 20000000 Histogram-based Statistics.
MariaDB uses histogram_size
MariaDB introduced Histogram-
histogram_size 0 -
based Statistics.
MariaDB introduced Histogram-
histogram_type SINGLE_PREC_HB -
based Statistics.
Time in seconds that the server
idle_readonly_transaction_timeout 0 -
waits for idle read-only transactions.
Time in seconds that the server
idle_transaction_timeout 0 -
waits for idle transactions.
Time in seconds that the server
idle_write_transaction_timeout 0 -
waits for idle write transactions.
ignore_builtin_innodb OFF - Ignored and removed in MySQL 8.
Controls the Conversion of Big IN
in_predicate_conversion_threshold 1000 - Predicates Into Subqueries
optimization.
Set to 1 if you are in a transaction,
in_transaction 0 -
and 0 if not.
Time until MySQL Information
information_schema_stats_expiry - 86400
Schema cached statistics expire.
Adaptive flushing is enabled when
this this low water mark percentage
innodb_adaptive_flushing_lwm 10.000000 10 of the redo log capacity is reached.
MariaDB's variable is a double,
MySQL's an integer.
Defaulting to OFF is a performance
improvement especially for DROP
innodb_adaptive_hash_index OFF ON
TABLE, TRUNCATE TABLE, ALTER
TABLE, or DROP INDEX operations
Deprecated and ignored in MariaDB
innodb_adaptive_max_sleep_delay - 150000
10.5 and removed in MariaDB 10.6.
Specific to MySQL's memcached,
innodb_api_* - *
removed in MariaDB 10.2.
MariaDB has an extra mode, 3 , for
skipping the rollback of connected
innodb_autoinc_lock_mode 1 2 transactions. MySQL defaults to
row-based replication, so can safely
use 2 .
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_buffer_pool_instances - 1
since the original reasons for
introducing no longer apply.
fullcrc32 permits encryption to be
innodb_checksum_algorithm full_crc32 crc32 supported over a SPATIAL INDEX,
which crc32 does not support.
Deprecated option removed in
innodb_checksums ON -
MySQL.
Deprecated and ignored in MariaDB
innodb_commit_concurrency - 0
10.5 and removed in MariaDB 10.6.
Introduced with MariaDB's InnoDB
innodb_compression_* * -
compression.
Deprecated and ignored in MariaDB
innodb_concurrency_tickets - 5000
10.5 and removed in MariaDB 10.6.
innodb_deadlock_report Full - How to report deadlocks.

1716/3812
MySQL option that automatically
configures various settings if the
innodb_dedicated_server - OFF
server is a dedicated InnoDB
database server.
Default encryption key id used for
innodb_default_encryption_key_id 1 - table encryption. See Data at Rest
Encryption.
MariaDB can defragment InnoDB
innodb_defragment * -
tablespaces.
Used to search for tablespace files
innodb_directories - (empty) when moving or restoring a new
location.
Tell InnoDB to stop any writes to
innodb_disallow_writes OFF -
disk.
See MariaDB's Data at Rest
innodb_encrypt_* 1 -
Encryption.
MariaDB's fatal semaphore timeout
innodb_fatal_semaphore_wait_threshold 600 -
is configurable.
MariaDB InnoDB flushing method by
default on Unix systems bypasses
innodb_flush_method O_DIRECT fsync
the file system cache for improved
performance in most cases.
MySQL 8 by default now assumes
innodb_flush_neighbors 1 0
the use of an SSD device.
If set to 1 in MariaDB (0 is default)
CREATE TABLEs without a primary
innodb_force_primary_key OFF - or unique key where all keyparts are
NOT NULL will not be accepted, and
will return an error.
Up to what percentage of dirty pages
in MariaDB should be flushed when
innodb_idle_flush_pct 100 -
InnoDB finds it has spare resources
to do so.
MariaDB has support for data
innodb_immediate_scrub_data_uncompressed OFF -
scrubbing.
See Instant ADD COLUMN for
innodb_instant_alter_column_allowed add_drop_reorder -
InnoDB.
Deprecated option in MariaDB for
disabling gap locking for searches
innodb_locks_unsafe_for_binlog OFF - and index scans. Deprecated in
MariaDB, use READ COMMITTED
transaction isolation instead.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6,
innodb_log_checksums - ON as there is no reason to allow
checksums to be disabled on the
redo log.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_log_compressed_pages - ON
as part of the InnoDB redo log
performance improvements.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_log_files_in_group - 2
as part of the InnoDB redo log
performance improvements.
MySQL variables for constraining
innodb_log_spin_* - * CPU usage while waiting for flushed
redo.
MySQL variable for constraining
innodb_log_wait_for_flush_spin_hwm - * CPU usage while waiting for flushed
redo.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct 75 90
90.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct_lwm 0 10
10.
MariaDB 10.2 reduced the limit for
innodb_max_undo_log_size 10485760 1073741824 when an undo tablespace is marked
for truncation.
In most systems, autosized based
on the table_open_cache setting,
innodb_open_files Autosized (2000) Autosized (4000)
which differs between MariaDB and
MySQL.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_page_cleaners - 1 as the original reasons for for
splitting the buffer pool have mostly
gone away.
MariaDB includes the Facebook
innodb_prefix_index_cluster_optimization OFF -
prefix index queries optimization.
MySQL option for writing DDL logs
innodb_print_ddl_logs - OFF
to stderr.

1717/3812
Whether to set
innodb_read_only_compressed ON - ROW_FORMAT=COMPRESSED
tables to read-only.
MySQL 8 has also now introduced
redo log encryption, but used a
innodb_redo_log_encrypt - OFF
different name. The equivalent option
in MariaDB is innodb_encrypt_log.
Deprecated and ignored in MariaDB
innodb_replication_delay - 0
10.5 and removed in MariaDB 10.6.
MariaDB changed the default from 6
innodb_spin_wait_delay 4 6 to 4 based on extensive
benchmarking.
MariaDB option to control the
innodb_stats_modified_counter 0 -
calculation of new statistics.
Deprecated MariaDB option for
innodb_stats_sample_pages 8 - control over index distribution
statistics.
Enabling gives a larger sample of
pages for larger tables for the
innodb_stats_traditional ON -
purposes of index statistics
calculation.
Deprecated and ignored in MariaDB
innodb_sync_array_size - 1
10.5 and removed in MariaDB 10.6.
Deprecated and ignored in MariaDB
innodb_thread_concurrency - 0
10.5 and removed in MariaDB 10.6.
Deprecated and ignored in MariaDB
innodb_thread_sleep_delay - 10000
10.5 and removed in MariaDB 10.6.
MySQL option for encrypting undo
innodb_undo_log_encrypt - OFF logs residing in separate undo
tablespaces.
MySQL 8 changes the default to
innodb_undo_log_truncate OFF ON ON, marking larger undo logs for
truncation.
Number of tablespace files used for
dividing up the undo logs. MySQL 8
innodb_undo_tablespaces 0 2 has deprecated this setting, and
increased the default (and minimum)
to 2.
Atomic writes are a faster alternative
to innodb_doublewrite and MariaDB
innodb_use_atomic_writes ON -
automatically detects when
supporting SSD cards are used.
MySQL uses this variable to set the
internal_tmp_disk_storage_engine - INNODB storage engine for on-disk internal
temporary tables.
MySQL and MariaDB use different
formats for temporary tables. In
internal_tmp_mem_storage_engine - TEMPTABLE MariaDB, the
aria_used_for_temp_tables performs
a similar function.

Maximum size in bytes of the query


join_buffer_space_limit 2097152 - buffer. See block-based join
algorithms.
For determining the join algorithms.
join_cache_level 2 -
See block-based join algorithms
Size of the buffer for the index
key_buffer_size 134217728 8388608 blocks used by MyISAM tables and
shared for all threads.
Number of hash buckets for open
key_cache_file_hash_size 512 -
and changed files.
The number of segments in a key
key_cache_segments 0 -
cache. See Segmented Key Cache.
Whether MySQL 8's keyring
keyring_operations - ON
operations are enabled.
MariaDB and MySQL have different
last_gtid - empty
GTID implementations.
MySQL no longer supports LOAD
local_infile ON OFF
DATA LOCAL by default.
MariaDB has reduced the timeout for
lock_wait_timeout 86400 31536000
acquiring metadata locks.
MySQL 8 enables the binary log by
log_bin OFF ON
default.
MariaDB setting for whether or not
log_bin_compress OFF -
the binary log can be compressed.
Minimum length of sql statement (in
statement mode) or record (in row
log_bin_compress_min_len 256 - mode) that can be compressed. See
Compressing Events to Reduce Size
of the Binary Log.

1718/3812
MySQL-only variable showing
log_bin_use_v1_row_events - OFF whether or not MySQL's version 2
binary logging format is being used.
Disable logging of certain
log_disabled_statements sp -
statements to the general log.
Components to enable for MySQL
log_error_services - log_filter_internal; log_sink_internal
error logging.
MySQL variable for setting verbosity
log_error_verbosity - 3 of error, warning, and note
messages in the error log.
MySQL 8 has by default enabled
log_slave_updates OFF ON binary logging of updates a slave
receives from a master.
MariaDB logs slow admin
log_slow_admin_statements ON OFF statements to the slow query log by
default.
Disable logging of certain
log_slow_disabled_statements admin,call,slave,sp -
statements to the slow query log.
admin, filesort, filesort_on_disk,
full_join, full_scan, query_cache,
log_slow_filter - For slow query log filtering.
query_cache_miss, tmp_table,
tmp_table_on_disk
Limits the number of queries logged
log_slow_rate_limit 1 -
to the slow query log.
MariaDB logs slow slave statements
log_slow_slave_statements ON OFF
to the slow query log by default.
Controls information to be added to
log_slow_verbosity empty - the slow query log. See also Slow
Query Log Extended Statistics.
MySQL setting for controlling
log_statements_unsafe_for_binlog - ON whether binlog warnings are written
to the error log.
MySQL variables with settings for
log_syslog* platform-dependent -
writing to syslog.
Size in bytes of the transaction
log_tc_size 24576 - coordinator log, defined in multiples
of 4096.
MySQL-only variable for limiting the
number of statements without
log_throttle_queries_not_using_indexes - 0
indexes written to the slow query
log.
MySQL-only variable controlling the
log_timestamps - UTC timezone for certain logging
conditions.
MySQL 8 has replaced with
log_warnings 2 -
log_error_verbosity .

MySQL variable for assigning roles


mandatory_roles - (empty)
to all users.
Whether slave logs master status
master_info_repository - TABLE and connection info to a table or a
file.
max_allowed_packet 16M 64M
Specifies the maximum number of
messages stored for display by
max_error_count 64 1024
SHOW ERRORS and SHOW
WARNINGS statements.
MySQL renamed the
max_execution_time - 0
max_statement_time variable.
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
max_length_for_sort_data 64 1024
these are added to the sort key. This
can speed up the sort as there's no
need 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.
Maximum size for parameter values
sent with
max_long_data_size 16777216 -
mysql_stmt_send_long_data().
Removed in MySQL 5.6.
Maximum number of failed
max_password_errors 4294967295 - connections attempts before no
more are permitted.
Maximum points_per_circle for
max_points_in_geometry - 65536 MySQL's ST_Buffer_Strategy()
function.
Maximum number of iterations when
max_recursive_iterations 4294967295 -
executing recursive queries.

1719/3812
max_relay_log_size 1073741824 0 Can be set by session in MariaDB.
The most key seeks required when
searching with an index, regardless
4294967295 (32-bit) or of the actual index cardinality. If this
max_seeks_for_key 4294967295
18446744073709547520 (64-bit) value is set lower than its default and
maximum, indexes will tend to be
preferred over table scans.
Amount of memory a single user
max_session_mem_used 9223372036854775807 -
session is allowed to allocate.
Maximum time in seconds that a
query can execute before being
max_statement_time 0 - aborted. MySQL used to have a
variable of this name before
renaming it max_execution_time .
max_tmp_tables 32 - Unused variable removed in MySQL.
Read lock requests will be permitted
4294967295 (32-bit) or
max_write_lock_count 4294967295 for processing after this many write
18446744073709547520 (64-bit)
locks.
Size of buffer to use when using
mrr_buffer_size 262144 - multi-range read with range access.
See Multi Range Read optimization.
Block size used for MyISAM index
myisam_block_size 1024 -
pages.
myisam_recover_options BACKUP,QUICK OFF MyISAM recovery mode.
Size in bytes of the buffer allocated
myisam_sort_buffer_size 134216704 8388608 when creating or sorting indexes on
a MyISAM table.
Whether MySQL's authentication
mysql_native_password_proxy_users - OFF
plugin supports proxy users. I
Causes MariaDB to use the MySQL-
5.6 low level formats for TIME,
mysql56_temporal_format ON
DATETIME and TIMESTAMP
instead of the MariaDB 5.3+ version.
Used for backward-compatibility with
new - OFF
MySQL 4.1, not present in MariaDB.
mysqlx+* - * MySQL's X plugin related variables.
Sets the n-gram token size for
ngram_token_size - 2
MySQL's n-gram full-text parser.
MySQL settting for specifying
offline_mode - OFF whether the server should run in
offline mode.
old_alter_table DEFAULT OFF An alias for alter_algorithm.
Used for getting MariaDB to emulate
behavior from an old version of
old_mode Empty string -
MySQL or MariaDB. See OLD
Mode.
MySQL 8 is no longer compatible
old_passwords OFF - with the old pre-MySQL 4.1 form of
password hashing.
Controls number of record samples
optimizer_selectivity_sampling_limit 100 -
to check condition selectivity.
A series of flags for controlling the
optimizer_switch See details query optimizer. MariaDB has
introduced a number of new settings.
MySQL has more settings for
optimizer_trace_* - *
optimizer tracing.
Controls which statistics can be
optimizer_use_condition_selectivity 4 - used by the optimizer when looking
for the best query execution plan.
Used by MySQL 8 for delaying
original_commit_timestamp - *
replication.
4294967295 (32-bit) or MySQL variable for limiting memory
parser_max_mem_size -
18446744073709547520 (64-bit) available to the parser.
Controls reuse of previous
password_* - *
passwords in MySQL.
The Performance Schema is off by
performance_schema OFF ON
default in MariaDB.
Many performance schema variables
are autoset in MySQL, and MySQL
performance_schema_*
has a different version, with
additional variables.
plugin_maturity One less than the server maturity - Minimum acceptable plugin maturity.
Time in seconds between sending
progress_report_time 5 - progress reports to the client for
time-consuming statements.
Enable proxy protocol for these
proxy_protocol_networks (empty) -
source networks.

1720/3812
Size in bytes of the extra blocks
allocated during query parsing and
query_alloc_block_size 16384 8192
execution (after query_prealloc_size
is used up).
MySQL has removed the query
query_cache_* * -
cache.
Size in bytes of the persistent buffer
for query parsing and execution,
query_prealloc_size 24576 8192
allocated on connect and freed on
disconnect.
MySQL-only variable setting a limit
range_optimizer_max_mem_size - 8388608 on the range optimizer's memory
usage.
MySQL-only variable for determining
rbr_exec_mode - STRICT
the handling of certain key errors.
Permits restricting the speed at
read_binlog_speed_limit 0 - which the slave reads the binlog from
the master.
Memory and time limits for regular
regexp_* - *
expression matching operations.
MySQL-only variable determining
relay_log_info_repository - TABLE whether the slave's position in the
relay logs is written to a file or table.
Tells the slave to reproduce
replicate_annotate_row_events ON - annotate_rows_events received from
the master in its own binary log.
replicate_do_db empty string - See Dynamic Replication Variables.
replicate_do_table empty string - See Dynamic Replication Variables.
See Selectively skipping replication
replicate_events_marked_for_skip replicate -
of binlog events.
replicate_ignore_db empty string - See Dynamic Replication Variables.
replicate_ignore_table empty string - See Dynamic Replication Variables.
replicate_wild_do_table empty string - See Dynamic Replication Variables.
replicate_wild_ignore_table empty string - See Dynamic Replication Variables.
Determine whether the server returns
result_metadata - FULL result set metadata for connections
where this is optional.
See Non-semi-join subquery
rowid_merge_buff_size 8388608 -
optimizations.
Minimum data in bytes read from the
rpl_read_size - 8192
binary and relay log files.
MariaDB includes semisynchronous
rpl_semi_sync_* - - replication without the need to install
a plugin.
Controls the time that STOP SLAVE
rpl_stop_slave_timeout - 31536000
waits before timing out.
The S3 storage engine is only
s3_* * -
available in MariaDB.
Limits the number of schema
schema_definition_cache - 256 definition objects kept in the
dictionary object cache.
secure_auth ON - Removed in MySQL.
MariaDB-only option permitting the
secure_timestamp NO - restricting of direct setting of a
session timestamp..
MySQL-only variable for use in
server_id_bits - server_id
MySQL Cluster.
MySQL-only variable containing the
server_uuid - UUID
UUID.
MySQL-only variables for tracking
gtid changes. MariaDB and
session_track_gtids - OFF
MySQL's gtid implementation is
different.
MySQL-only variable determining
sha256_password_proxy_users - OFF whether the sha256_password plugin
supports proxy users.
Option to cause SHOW CREATE
show_create_table_verbosity - OFF TABLE to display ROW_FORMAT in
all cases.
MySQL-only variable for determining
whether SHOW CREATE TABLE
show_old_temporals - OFF
output should include comments for
old format temporal columns.
skip_parallel_replication OFF - See parallel replication.
See Selectively skipping replication
skip_replication OFF -
of binlog events.
slave_allow_batching - OFF MySQL-only replication variable.
slave_checkpoint_group - 512 MySQL-only replication variable.
1721/3812
slave_checkpoint_period - 300 MySQL-only replication variable.
Modes for how replication of DDL
slave_ddl_exec_mode IDEMPOTENT -
events should be executed.
slave_domain_parallel_threads 0 - For configuring parallel replication.
slave_net_timeout 3600 60 MySQL reduced the timeout to 60s.
slave_parallel_max_queued 131072 - For configuring parallel replication.
Controls what transactions are
slave_parallel_mode optimistic - applied in parallel when using
parallel_replication.

slave_parallel_threads 0 - For configuring parallel replication.


slave_parallel_type - DATABASE MySQL-only replication variable.
slave_pending_jobs_size_max - 16777216 MySQL-only replication variable.
slave_preserve_commit_order - OFF MySQL-only replication variable.
slave_rows_search_algorithms - INDEX_SCAN, HASH_SCAN MySQL-only replication variable.
See Running triggers on the slave for
slave_run_triggers_for_rbr NO Row-based events for a description
and use-case for this setting.
When an error occurs during a
transaction on the slave, replication
usually halts. By default,
transactions that caused a deadlock
or elapsed lock wait timeout will be
slave_transaction_retry_errors 1213,1205 -
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 to
this variable.
Interval in seconds for the slave SQL
thread to retry a failed transaction
slave_transaction_retry_interval 0 - due to a deadlock, elapsed lock wait
timeout or an error listed in
slave_transaction_retry_errors.
The default sort buffer allocated has
sort_buffer_size 2097152 262144
been reduced in MySQL.
Adds an implicit IF EXISTS to
ALTER, RENAME and DROP of
sql_if_exists OFF -
TABLES, VIEWS, FUNCTIONS and
PACKAGES
ONLY_FULL_GROUP_BY,
STRICT_TRANS_TABLES, STRICT_TRANS_TABLES,
ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_IN_DATE,
sql_mode See SQL Mode.
NO_AUTO_CREATE_USER, NO_ZERO_DATE,
NO_ENGINE_SUBSTITUTION ERROR_FOR_DIVISION_BY_ZERO,
NO_ENGINE_SUBSTITUTION
Whether FIPS mode is enabled on
ssl_fips_mode - OFF
the server side.
standard_compliant_cte ON - See Common Table Expressions.
Alias for default_storage_engine,
storage_engine InnoDB -
removed in MySQL.
In MariaDB, when password
validation plugins are enabled, reject
strict_password_validation ON -
passwords that cannot be validated
(passwords specified as a hash).
Limits the number of stored program
stored_program_definition_cache - 256 definition objects kept in the
dictionary object cache.
MySQL variable for prohibiting client
super_read_only - OFF updates from users with the SUPER
privilege.
MySQL synchronizes all actions to
sync_binlog 0 1 the binary log before they are
committed.
.frm files have been removed in
sync_frm 1 -
MySQL.
MariaDB has System-Versioned
system_versioning_alter_history ERROR -
Tables
MariaDB has System-Versioned
system_versioning_asof DEFAULT -
Tables
Number of table definitions that can
table_definition_cache 400 -1 (autosized)
be cached.
Maximum number of table cache
table_open_cache_instances 8 16
instances.
Limits the number of tablespace
tablespace_definition_cache - 256 definition objects kept in the
dictionary object cache.
Interval, in seconds, between when
successive keep-alive packets are
tcp_keepalive_interval 0 -
sent if no acknowledgement is
received.

1722/3812
Number of unacknowledged probes
to send before considering the
tcp_keepalive_probes 0 -
connection dead and notifying the
application layer.
Set the TCP_NODELAY option
tcp_keepalive_time 0 - (disable Nagle's algorithm) on
socket.

Timeout, in milliseconds, with no


tcp_nodelay 1 - activity until the first TCP keep-alive
packet is sent.
Limits the RAM used by MySQL's
temptable_max_ram - 1GB
TempTable storage engine.
MariaDB uses an improved thread
thread_cache_size Autosized -1 (autosized)
pool .
thread_concurrency 10 - Removed in MySQL 5.7.
Better precision for the data in the
thread_pool_dedicated_listener 0 - Information Schema
THREADPOOL_QUEUES Table.
Better precision for the data in the
thread_pool_exact_stats 0 - Information Schema
THREADPOOL_QUEUES Table.
thread_pool_idle_timeout 60 - See Using the Thread Pool .
thread_pool_max_threads 65536 - See Using the Thread Pool .
Windows-only. See Using the
thread_pool_min_threads 1 -
Thread Pool .
thread_pool_oversubscribe 3 - See Using the Thread Pool .
thread_pool_prio_kickup auto - See Using the Thread Pool .
thread_pool_priority auto - See Using the Thread Pool .
See Using the Thread Pool . *Only
thread_pool_size Number of processors 16* available in MySQL with a
commercial plugin.
See Using the Thread Pool . *Only
thread_pool_stall_limit 500 6* available in MySQL with a
commercial plugin.
thread_stack 299008 Varies See Using the Thread Pool .
time_format %H:%i:%s - Removed in MySQL.
timed_mutexes OFF - Removed in MySQL.
Max size for data for an internal
tmp_disk_table_size 18446744073709551615 - temporary on-disk MyISAM or Aria
table.
tmp_memory_table_size 16777216 - Alias for tmp_table_size.
Variable for enabling batching of
transaction_allow_batching - OFF statements within the same
transaction in MySQL Cluster.
The MariaDB equivalent is
transaction_isolation - REPEATABLE-READ
tx_isolation.
The MariaDB equivalent is
transaction_read_only - OFF
tx_read_only.
transaction_write_set_extraction - OFF Unused MySQL-only variable.
The MySQL equivalent is
tx_isolation REPEATABLE-READ -
transaction_isolation.
The MySQL equivalent is
tx_read_only OFF -
transaction_read_only.
Controls the use of engine-
use_stat_tables preferably_for_queries -
independent table statistics.
Whether to activate MariaDB's User
userstat OFF - Statistics implementation, not
available in MySQL.
Version of the zlib library compiled
version_compile_zlib - *
in.
version_malloc_library * - Version of the used malloc library.
Permits seeing exactly which
version_source_revision Varies - version of the source was used for a
build.
version_ssl_library * - Version of the used TLS library.
MySQL option allowing safety to be
windowing_high_use_precision - * sacrificed for speed in window
function calculations.
Galera cluster is only available in
wsrep_* * -
MariaDB.
Variable MariaDB 10.7 MySQL 8.0 Notes

See Also
1723/3812
System Variable Differences Between MariaDB 10.6 and MySQL 8.0

2.1.14.1.11.4 System Variable Differences


Between MariaDB 10.6 and MySQL 8.0
Contents
1. Comparison Table
2. See Also

The following is a comparison of variables that either appear only in MariaDB 10.6 or MySQL 8.0, or have different
default settings in MariaDB 10.6, and MySQL 8.0. The stable releases MariaDB 10.6.4 and MySQL 8.0.11, with only
default plugins enabled, were used for the comparison. Note that MySQL 8 is an 'evergreen' release, so features may
be added or removed in later releases.
The most notable differences are that MariaDB includes, by default, the Aria storage engine (resulting in extra memory
allocation), Galera Cluster, and has a different thread pool implementation . For this reason, a default implementation
of MariaDB 10.6 will use more memory than MySQL 8.0. MariaDB 10.6 and MySQL 8.0 also have different GTID
implementations.
MariaDB's extra memory usage can be handled with the following rules of thumb:
If you are not using MyISAM and don't plan to use Aria:
Set key_buffer_size to something very low (16K) as it's not used.
Set aria_pagecache_buffer_size to what you think you need for handling internal tmp tables that didn't fit in
memory.
Normally this is what before you had set for key_buffer_size (at least 1M).
If you are using MyISAM and not planning to use Aria:
Set aria_pagecache_buffer_size to what you think you need for handling internal tmp tables that didn't fit in
memory.
If you are planning to use Aria, you should set aria_pagecache_buffer_size to something that fits a big part of
your normal data + overflow temporary tables.

Comparison Table
Variable MariaDB 10.6 Default MySQL 8.0 Default Notes
Determines whether to automatically
activate_all_roles_on_login - OFF
activate roles on login.
MariaDB 10.3 introduced new
ALTER TABLE ALGORITHM
clauses to avoid slow copies in
alter_algorithm DEFAULT -
certain instances. This variable
allows setting this if no ALGORITHM
clause is specified.
Percentage of rows from the table
analyze_sample_percentage 100.0000 - ANALYZE TABLE will sample to
collect table statistics.
The Aria storage engine is only
aria_* * -
available in MariaDB.
Whether to automatically generate
auto_generate_certs - ON
SSL key and certificate files.
Determines whether ALTER TABLE
avoid_temporal_upgrade - OFF implicitly upgrades temporal
columns.
MariaDB and MySQL have different
back_log Autosized Autosized
autosizing algorithms.
Introduced in MariaDB 5.3 for
binlog-annotate-row-events ON - replicating between MariaDB 5.3 and
MySQL/MariaDB 5.1.
For use in MariaDB's parallel
binlog_commit_wait_count 0 -
replication.
For use in MariaDB's parallel
binlog_commit_wait_usec 100000 -
replication.
MySQL-only variable for controlling
binlog_error_action ABORT_SERVER what happens when the server
cannot write to the binary log.
Sets the binary log expiration period
binlog_expire_logs_seconds 0 2592000
in seconds
For setting the size of the file cache
binlog_file_cache_size 16184 -
for the binary log.
MariaDB and MySQL have differing
binlog_format MIXED ROW
binary log formats.
MySQL-only variable for controlling
binlog_group_commit_sync_delay 0 the wait time before synchronizing
the binary log file to disk.

1724/3812
MySQL-only variable for setting the
maximum number of transactions to
binlog_group_commit_sync_no_delay_count 0 wait for before aborting the current
binlog_group_commit_sync_delay
delay.
MySQL-only GTID variable.
binlog_gtid_simple_recovery - ON MariaDB's GTID implementation is
different.
Specifies a timeout for reading
transactions from the flush queue
binlog_max_flush_queue_time - 0
before continuing with group commit
and syncing log to disk.
For optimized kernel thread
binlog_optimize_thread_scheduling ON -
scheduling.
Determines whether transactions
binlog_order_commits - ON
may be committed in parallel.
Determines the amount of table
binlog_row_metadata NO_LOG MINIMAL metadata added to the binary log
with row-based logging.
Permits an alternative binlog format
binlog_row_value_options - (empty)
for JSON document updates.
MySQL-only variable for logging
binlog_rows_query_log_events - OFF extra information in row-based
logging.
Maximum number of row hashes
binlog_transaction_dependency_history_size - 25000 kept for looking up transactions that
last modified a given row.
For determining how to best use the
binlog_transaction_dependency_tracking - COMMIT_ORDER
slave's multithreaded applier.
MySQL-only variable for controlling
block_encryption_mode - aes-128-ecb the block encryption mode for block-
based algorithms.
For use with MySQL's SHA-256
caching_sha2_password* - *
authentication with caching.
MySQL 8.0 defaults to the utf8mb4
character_set_* latin1 or utf8 utf8mb4
character set.
Permits disabling constraint checks,
for example when loading a table
check_constraint_checks ON -
that violates some constraints that
you plan to fix later.
MySQL-only variable for controlling
whether the server performs proxy
check_proxy_users OFF
user mapping for authentication
plugins.
MySQL 8.0 defaults to the utf8mb4
collation_* latin1_swedish_ci or utf8_general_ci utf8mb4_0900_ai_ci
character set.
MariaDB supports Storage-engine
column_compression_threshold 100 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_level 6 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_strategy DEFAULT_STRATEGY -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_wrap OFF -
Independent Column Compression.
When MySQL 8.0 introduced
common table expressions they
cte_max_recursion_depth - 1000 used a different name. MariaDB's
variable is called
max_recursive_iterations.
Unused variable removed in MySQL
date_format %Y-%m-%d -
8.0
Unused variable removed in MySQL
datetime_format %Y-%m-%d -
8.0
The Aria storage engine is only
deadlock_search_depth_long 15 -
available in MariaDB.
The Aria storage engine is only
deadlock_search_depth_short 4 -
available in MariaDB.
The Aria storage engine is only
deadlock_timeout_long 50000000 - available in MariaDB.

The Aria storage engine is only


deadlock_timeout_short 10000 -
available in MariaDB.
Disable system thread alarm calls,
debug_no_thread_alarm OFF -
for debugging or testing.
MySQL 8 introduced a new
default_authentication_plugin - caching_sha2_password
authentication plugin.
For internal use in MySQL 8
default_collation_for_utf8mb4 - utf8mb4_0900_ai_ci
replication.
For use with MariaDB's multi-source
default_master_connection empty -
replication.

1725/3812
MariaDB defaults to password
default_password_lifetime 0 360
expiration off.
For handling incompatibilities
default_regex_flags empty - between MariaDB's PCRE and the
old regex library.
Default storage engine used for
default_tmp_storage_engine empty InnoDB tables created with CREATE
TEMPORARY TABLE.
MySQL-only variable for disabling
disabled_storage_engines empty
specific storage engines.
MariaDB password expiration is off
by default, and by default does not
disconnect_on_expired_password OFF ON
disconnect a client when a password
has expired.
MariaDB enables table and
encrypt_binlog OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_files OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_disk_tables OFF -
tablespace encryption.
MySQL-only variable for adding end
end_markers_in_json - OFF
markers to JSON output.
MariaDB and MySQL have different
enforce_gtid_consistency - OFF
GTID implementations.
Forces the use of a particular
enforce_storage_engine none
storage engine for new tables.
Variable for tuning when the
optimizer should switch from using
eq_range_index_dive_limit 0 200
index dives to index statistics for
qualifying rows estimation.
MySQL enables the event scheduler
event_scheduler OFF ON
by default.
Used for determining expensive
expensive_subquery_limit 100 -
queries for optimization.
MySQL 8 disables the old
explicit_defaults_for_timestamp OFF ON
timestamp behavior.
Introduced in the MariaDB 5.1
extra_max_connections 1 -
threadpool.
Introduced in the MariaDB 5.1
extra_port 0 -
threadpool.
MariaDB increases the maximum
group_concat_max_len 1048576 1024 length for a GROUP_CONCAT()
result from 1K to 1M.
MariaDB and MySQL have different
gtid_binlog_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_binlog_state empty -
GTID implementations.
MariaDB and MySQL have different
gtid_cleanup_batch_size 64 -
GTID implementations.
MariaDB and MySQL have different
gtid_current_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_domain_id 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_executed - empty
GTID implementations.
MariaDB and MySQL have different
gtid_executed_compression_period - 1000
GTID implementations.
MariaDB and MySQL have different
gtid_ignore_duplicates OFF -
GTID implementations.
MariaDB and MySQL have different
gtid_mode - OFF
GTID implementations.
MariaDB and MySQL have different
gtid_next - AUTOMATIC
GTID implementations.
MariaDB and MySQL have different
gtid_owned - empty
GTID implementations.
MariaDB and MySQL have different
gtid_pos_auto_engines empty -
GTID implementations.
MariaDB and MySQL have different
gtid_purged - empty
GTID implementations.
MariaDB and MySQL have different
gtid_seq_no 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_slave_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_strict_mode OFF -
GTID implementations.
MySQL has removed the ENCRYPT
have_crypt YES -
function.

1726/3812
MariaDB's version indicates whether
YaSSL or openssl was used.
have_openssl
MySQL's is a synonym for
have_ssl .

MySQL has removed the query


have_query_cache YES -
cache.
Whether MySQL's statement
have_statement_timeout - execution timeout feature is
available.
MySQL has removed symlink
have_symlink YES DISABLED
support.
Added when MySQL 8 introduced
histogram_generation_max_mem_size - 20000000 Histogram-based Statistics.
MariaDB uses histogram_size
MariaDB introduced Histogram-
histogram_size 0 -
based Statistics.
MariaDB introduced Histogram-
histogram_type SINGLE_PREC_HB -
based Statistics.
Time in seconds that the server
idle_readonly_transaction_timeout 0 -
waits for idle read-only transactions.
Time in seconds that the server
idle_transaction_timeout 0 -
waits for idle transactions.
Time in seconds that the server
idle_write_transaction_timeout 0 -
waits for idle write transactions.
ignore_builtin_innodb OFF - Ignored and removed in MySQL 8.
Controls the Conversion of Big IN
in_predicate_conversion_threshold 1000 - Predicates Into Subqueries
optimization.
Set to 1 if you are in a transaction,
in_transaction 0 -
and 0 if not.
Time until MySQL Information
information_schema_stats_expiry - 86400
Schema cached statistics expire.
Adaptive flushing is enabled when
this this low water mark percentage
innodb_adaptive_flushing_lwm 10.000000 10 of the redo log capacity is reached.
MariaDB's variable is a double,
MySQL's an integer.
Defaulting to OFF is a performance
improvement especially for DROP
innodb_adaptive_hash_index OFF ON
TABLE, TRUNCATE TABLE, ALTER
TABLE, or DROP INDEX operations
Deprecated and ignored in MariaDB
innodb_adaptive_max_sleep_delay - 150000
10.5 and removed in MariaDB 10.6.
Specific to MySQL's memcached,
innodb_api_* - *
removed in MariaDB 10.2.
MariaDB has an extra mode, 3 , for
skipping the rollback of connected
innodb_autoinc_lock_mode 1 2 transactions. MySQL defaults to
row-based replication, so can safely
use 2 .
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_buffer_pool_instances - 1
since the original reasons for
introducing no longer apply.
fullcrc32 permits encryption to be
innodb_checksum_algorithm full_crc32 crc32 supported over a SPATIAL INDEX,
which crc32 does not support.

Deprecated option removed in


innodb_checksums ON -
MySQL.
Deprecated and ignored in MariaDB
innodb_commit_concurrency - 0
10.5 and removed in MariaDB 10.6.
Introduced with MariaDB's InnoDB
innodb_compression_* * -
compression.
Deprecated and ignored in MariaDB
innodb_concurrency_tickets - 5000
10.5 and removed in MariaDB 10.6.
innodb_deadlock_report Full - How to report deadlocks.
MySQL option that automatically
configures various settings if the
innodb_dedicated_server - OFF
server is a dedicated InnoDB
database server.
Default encryption key id used for
innodb_default_encryption_key_id 1 - table encryption. See Data at Rest
Encryption.
MariaDB can defragment InnoDB
innodb_defragment * -
tablespaces.
Used to search for tablespace files
innodb_directories - (empty) when moving or restoring a new
location.
Tell InnoDB to stop any writes to
innodb_disallow_writes OFF -
disk.
1727/3812
See MariaDB's Data at Rest
innodb_encrypt_* 1 -
Encryption.
MariaDB's fatal semaphore timeout
innodb_fatal_semaphore_wait_threshold 600 -
is configurable.
MariaDB 10.6 InnoDB flushing
method by default on Unix systems
innodb_flush_method O_DIRECT fsync bypasses the file system cache for
improved performance in most
cases.
MySQL 8 by default now assumes
innodb_flush_neighbors 1 0
the use of an SSD device.
If set to 1 in MariaDB (0 is default)
CREATE TABLEs without a primary
innodb_force_primary_key OFF - or unique key where all keyparts are
NOT NULL will not be accepted, and
will return an error.
Up to what percentage of dirty pages
in MariaDB should be flushed when
innodb_idle_flush_pct 100 -
InnoDB finds it has spare resources
to do so.
MariaDB has support for data
innodb_immediate_scrub_data_uncompressed OFF -
scrubbing.
See Instant ADD COLUMN for
innodb_instant_alter_column_allowed add_drop_reorder -
InnoDB.
Deprecated option in MariaDB for
disabling gap locking for searches
innodb_locks_unsafe_for_binlog OFF - and index scans. Deprecated in
MariaDB, use READ COMMITTED
transaction isolation instead.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6,
innodb_log_checksums - ON as there is no reason to allow
checksums to be disabled on the
redo log.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_log_compressed_pages - ON
as part of the InnoDB redo log
performance improvements.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_log_files_in_group - 2
as part of the InnoDB redo log
performance improvements.
MySQL variables for constraining
innodb_log_spin_* - * CPU usage while waiting for flushed
redo.
MySQL variable for constraining
innodb_log_wait_for_flush_spin_hwm - * CPU usage while waiting for flushed
redo.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct 75 90
90.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct_lwm 0 10 10.

MariaDB 10.2 reduced the limit for


innodb_max_undo_log_size 10485760 1073741824 when an undo tablespace is marked
for truncation.
In most systems, autosized based
on the table_open_cache setting,
innodb_open_files Autosized (2000) Autosized (4000)
which differs between MariaDB and
MySQL.
Deprecated and ignored in MariaDB
10.5 and removed in MariaDB 10.6
innodb_page_cleaners - 1 as the original reasons for for
splitting the buffer pool have mostly
gone away.
MariaDB includes the Facebook
innodb_prefix_index_cluster_optimization OFF -
prefix index queries optimization.
MySQL option for writing DDL logs
innodb_print_ddl_logs - OFF
to stderr.
Whether to set
innodb_read_only_compressed ON - ROW_FORMAT=COMPRESSED
tables to read-only.
MySQL 8 has also now introduced
redo log encryption, but used a
innodb_redo_log_encrypt - OFF
different name. The equivalent option
in MariaDB is innodb_encrypt_log.
Deprecated and ignored in MariaDB
innodb_replication_delay - 0
10.5 and removed in MariaDB 10.6.
MariaDB changed the default from 6
innodb_spin_wait_delay 4 6 to 4 based on extensive
benchmarking.
MariaDB option to control the
innodb_stats_modified_counter 0 -
calculation of new statistics.

1728/3812
Deprecated MariaDB option for
innodb_stats_sample_pages 8 - control over index distribution
statistics.
Enabling gives a larger sample of
pages for larger tables for the
innodb_stats_traditional ON -
purposes of index statistics
calculation.
Deprecated and ignored in MariaDB
innodb_sync_array_size - 1
10.5 and removed in MariaDB 10.6.
Deprecated and ignored in MariaDB
innodb_thread_concurrency - 0
10.5 and removed in MariaDB 10.6.
Deprecated and ignored in MariaDB
innodb_thread_sleep_delay - 10000
10.5 and removed in MariaDB 10.6.
MySQL option for encrypting undo
innodb_undo_log_encrypt - OFF logs residing in separate undo
tablespaces.
MySQL 8 changes the default to
innodb_undo_log_truncate OFF ON ON, marking larger undo logs for
truncation.
Number of tablespace files used for
dividing up the undo logs. MySQL 8
innodb_undo_tablespaces 0 2 has deprecated this setting, and
increased the default (and minimum)
to 2.
Atomic writes are a faster alternative
to innodb_doublewrite and MariaDB
innodb_use_atomic_writes ON -
automatically detects when
supporting SSD cards are used.
MySQL uses this variable to set the
internal_tmp_disk_storage_engine - INNODB storage engine for on-disk internal
temporary tables.
MySQL and MariaDB use different
formats for temporary tables. In
internal_tmp_mem_storage_engine - TEMPTABLE MariaDB, the
aria_used_for_temp_tables performs
a similar function.
Maximum size in bytes of the query
join_buffer_space_limit 2097152 - buffer. See block-based join
algorithms.
For determining the join algorithms.
join_cache_level 2 -
See block-based join algorithms
Size of the buffer for the index
key_buffer_size 134217728 8388608 blocks used by MyISAM tables and
shared for all threads.
Number of hash buckets for open
key_cache_file_hash_size 512 -
and changed files.
The number of segments in a key
key_cache_segments 0 -
cache. See Segmented Key Cache.
Whether MySQL 8's keyring
keyring_operations - ON
operations are enabled.
MariaDB and MySQL have different
last_gtid - empty
GTID implementations.
MySQL no longer supports LOAD
local_infile ON OFF
DATA LOCAL by default.
MariaDB has reduced the timeout for
lock_wait_timeout 86400 31536000
acquiring metadata locks.
MySQL 8 enables the binary log by
log_bin OFF ON
default.
MariaDB setting for whether or not
log_bin_compress OFF -
the binary log can be compressed.
Minimum length of sql statement (in
statement mode) or record (in row
log_bin_compress_min_len 256 - mode) that can be compressed. See
Compressing Events to Reduce Size
of the Binary Log.
MySQL-only variable showing
log_bin_use_v1_row_events - OFF whether or not MySQL's version 2
binary logging format is being used.
Disable logging of certain
log_disabled_statements sp -
statements to the general log.
Components to enable for MySQL
log_error_services - log_filter_internal; log_sink_internal
error logging.
MySQL variable for setting verbosity
log_error_verbosity - 3 of error, warning, and note
messages in the error log.
MySQL 8 has by default enabled
log_slave_updates OFF ON binary logging of updates a slave
receives from a master.
MariaDB logs slow admin
log_slow_admin_statements ON OFF statements to the slow query log by
default.

1729/3812
Disable logging of certain
log_slow_disabled_statements admin,call,slave,sp -
statements to the slow query log.
admin, filesort, filesort_on_disk,
full_join, full_scan, query_cache,
log_slow_filter - For slow query log filtering.
query_cache_miss, tmp_table,
tmp_table_on_disk
Limits the number of queries logged
log_slow_rate_limit 1 -
to the slow query log.
MariaDB logs slow slave statements
log_slow_slave_statements ON OFF
to the slow query log by default.
Controls information to be added to
log_slow_verbosity empty - the slow query log. See also Slow
Query Log Extended Statistics.
MySQL setting for controlling
log_statements_unsafe_for_binlog - ON whether binlog warnings are written
to the error log.
MySQL variables with settings for
log_syslog* platform-dependent -
writing to syslog.
Size in bytes of the transaction
log_tc_size 24576 - coordinator log, defined in multiples
of 4096.
MySQL-only variable for limiting the
number of statements without
log_throttle_queries_not_using_indexes - 0
indexes written to the slow query
log.
MySQL-only variable controlling the
log_timestamps - UTC timezone for certain logging
conditions.
MySQL 8 has replaced with
log_warnings 2 -
log_error_verbosity .

MySQL variable for assigning roles


mandatory_roles - (empty)
to all users.
Whether slave logs master status
master_info_repository - TABLE and connection info to a table or a
file.
max_allowed_packet 16M 64M
Specifies the maximum number of
messages stored for display by
max_error_count 64 1024
SHOW ERRORS and SHOW
WARNINGS statements.
MySQL renamed the
max_execution_time - 0
max_statement_time variable.
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
max_length_for_sort_data 64 1024
these are added to the sort key. This
can speed up the sort as there's no
need 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.
Maximum size for parameter values
sent with
max_long_data_size 16777216 -
mysql_stmt_send_long_data().
Removed in MySQL 5.6.
Maximum number of failed
max_password_errors 4294967295 - connections attempts before no
more are permitted.
Maximum points_per_circle for
max_points_in_geometry - 65536 MySQL's ST_Buffer_Strategy()
function.
Maximum number of iterations when
max_recursive_iterations 4294967295 -
executing recursive queries.
max_relay_log_size 1073741824 0 Can be set by session in MariaDB.
The most key seeks required when
searching with an index, regardless
4294967295 (32-bit) or of the actual index cardinality. If this
max_seeks_for_key 4294967295
18446744073709547520 (64-bit) value is set lower than its default and
maximum, indexes will tend to be
preferred over table scans.
Amount of memory a single user
max_session_mem_used 9223372036854775807 -
session is allowed to allocate.
Maximum time in seconds that a
query can execute before being
max_statement_time 0 - aborted. MySQL used to have a
variable of this name before
renaming it max_execution_time .
max_tmp_tables 32 - Unused variable removed in MySQL.

1730/3812
Read lock requests will be permitted
4294967295 (32-bit) or
max_write_lock_count 4294967295 for processing after this many write
18446744073709547520 (64-bit)
locks.
Size of buffer to use when using
mrr_buffer_size 262144 - multi-range read with range access.
See Multi Range Read optimization.
Block size used for MyISAM index
myisam_block_size 1024 -
pages.
myisam_recover_options BACKUP,QUICK OFF MyISAM recovery mode.
Size in bytes of the buffer allocated
myisam_sort_buffer_size 134216704 8388608 when creating or sorting indexes on
a MyISAM table.
Whether MySQL's authentication
mysql_native_password_proxy_users - OFF
plugin supports proxy users. I
Causes MariaDB to use the MySQL-
5.6 low level formats for TIME,
mysql56_temporal_format ON
DATETIME and TIMESTAMP
instead of the MariaDB 5.3+ version.
Used for backward-compatibility with
new - OFF
MySQL 4.1, not present in MariaDB.
mysqlx+* - * MySQL's X plugin related variables.
Sets the n-gram token size for
ngram_token_size - 2
MySQL's n-gram full-text parser.
MySQL settting for specifying
offline_mode - OFF whether the server should run in
offline mode.
old_alter_table DEFAULT OFF An alias for alter_algorithm.
Used for getting MariaDB to emulate
behavior from an old version of
old_mode Empty string -
MySQL or MariaDB. See OLD
Mode.
MySQL 8 is no longer compatible
old_passwords OFF - with the old pre-MySQL 4.1 form of
password hashing.
Controls number of record samples
optimizer_selectivity_sampling_limit 100 -
to check condition selectivity.
A series of flags for controlling the
optimizer_switch See details query optimizer. MariaDB has
introduced a number of new settings.
MySQL has more settings for
optimizer_trace_* - *
optimizer tracing.
Controls which statistics can be
optimizer_use_condition_selectivity 4 - used by the optimizer when looking
for the best query execution plan.
Used by MySQL 8 for delaying
original_commit_timestamp - *
replication.
4294967295 (32-bit) or MySQL variable for limiting memory
parser_max_mem_size -
18446744073709547520 (64-bit) available to the parser.
Controls reuse of previous
password_* - *
passwords in MySQL.
The Performance Schema is off by
performance_schema OFF ON
default in MariaDB.
Many performance schema variables
are autoset in MySQL, and MySQL
performance_schema_*
has a different version, with
additional variables.
plugin_maturity One less than the server maturity - Minimum acceptable plugin maturity.
Time in seconds between sending
progress_report_time 5 - progress reports to the client for
time-consuming statements.
Enable proxy protocol for these
proxy_protocol_networks (empty) -
source networks.
Size in bytes of the extra blocks
allocated during query parsing and
query_alloc_block_size 16384 8192
execution (after query_prealloc_size
is used up).
MySQL has removed the query
query_cache_* * -
cache.
Size in bytes of the persistent buffer
for query parsing and execution,
query_prealloc_size 24576 8192
allocated on connect and freed on
disconnect.
MySQL-only variable setting a limit
range_optimizer_max_mem_size - 8388608 on the range optimizer's memory
usage.
MySQL-only variable for determining
rbr_exec_mode - STRICT
the handling of certain key errors.
Permits restricting the speed at
read_binlog_speed_limit 0 - which the slave reads the binlog from
the master.
1731/3812
Memory and time limits for regular
regexp_* - *
expression matching operations.
MySQL-only variable determining
relay_log_info_repository - TABLE whether the slave's position in the
relay logs is written to a file or table.
Tells the slave to reproduce
replicate_annotate_row_events ON - annotate_rows_events received from
the master in its own binary log.
replicate_do_db empty string - See Dynamic Replication Variables.
replicate_do_table empty string - See Dynamic Replication Variables.
See Selectively skipping replication
replicate_events_marked_for_skip replicate -
of binlog events.
replicate_ignore_db empty string - See Dynamic Replication Variables.
replicate_ignore_table empty string - See Dynamic Replication Variables.
replicate_wild_do_table empty string - See Dynamic Replication Variables.
replicate_wild_ignore_table empty string - See Dynamic Replication Variables.
Determine whether the server returns
result_metadata - FULL result set metadata for connections
where this is optional.
See Non-semi-join subquery
rowid_merge_buff_size 8388608 -
optimizations.
Minimum data in bytes read from the
rpl_read_size - 8192
binary and relay log files.
MariaDB includes semisynchronous
rpl_semi_sync_* - - replication without the need to install
a plugin.
Controls the time that STOP SLAVE
rpl_stop_slave_timeout - 31536000
waits before timing out.
The S3 storage engine is only
s3_* * -
available in MariaDB.
Limits the number of schema
schema_definition_cache - 256 definition objects kept in the
dictionary object cache.
secure_auth ON - Removed in MySQL.
MariaDB-only option permitting the
secure_timestamp NO - restricting of direct setting of a
session timestamp..
MySQL-only variable for use in
server_id_bits - server_id
MySQL Cluster.
MySQL-only variable containing the
server_uuid - UUID
UUID.
MySQL-only variables for tracking
gtid changes. MariaDB and
session_track_gtids - OFF
MySQL's gtid implementation is
different.
MySQL-only variable determining
sha256_password_proxy_users - OFF whether the sha256_password plugin
supports proxy users.
Option to cause SHOW CREATE
show_create_table_verbosity - OFF TABLE to display ROW_FORMAT in
all cases.
MySQL-only variable for determining
whether SHOW CREATE TABLE
show_old_temporals - OFF
output should include comments for
old format temporal columns.
skip_parallel_replication OFF - See parallel replication.
See Selectively skipping replication
skip_replication OFF -
of binlog events.
slave_allow_batching - OFF MySQL-only replication variable.
slave_checkpoint_group - 512 MySQL-only replication variable.
slave_checkpoint_period - 300 MySQL-only replication variable.
Modes for how replication of DDL
slave_ddl_exec_mode IDEMPOTENT -
events should be executed.
slave_domain_parallel_threads 0 - For configuring parallel replication.
slave_net_timeout 3600 60 MySQL reduced the timeout to 60s.
slave_parallel_max_queued 131072 - For configuring parallel replication.
Controls what transactions are
slave_parallel_mode optimistic - applied in parallel when using
parallel_replication.
slave_parallel_threads 0 - For configuring parallel replication.
slave_parallel_type - DATABASE MySQL-only replication variable.
slave_pending_jobs_size_max - 16777216 MySQL-only replication variable.
slave_preserve_commit_order - OFF MySQL-only replication variable.
slave_rows_search_algorithms - INDEX_SCAN, HASH_SCAN MySQL-only replication variable.

1732/3812
See Running triggers on the slave for
slave_run_triggers_for_rbr NO Row-based events for a description
and use-case for this setting.
When an error occurs during a
transaction on the slave, replication
usually halts. By default,
transactions that caused a deadlock
or elapsed lock wait timeout will be
slave_transaction_retry_errors 1213,1205 - 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 to
this variable.

Interval in seconds for the slave SQL


thread to retry a failed transaction
slave_transaction_retry_interval 0 - due to a deadlock, elapsed lock wait
timeout or an error listed in
slave_transaction_retry_errors.
The default sort buffer allocated has
sort_buffer_size 2097152 262144
been reduced in MySQL.
Adds an implicit IF EXISTS to
ALTER, RENAME and DROP of
sql_if_exists OFF -
TABLES, VIEWS, FUNCTIONS and
PACKAGES
ONLY_FULL_GROUP_BY,
STRICT_TRANS_TABLES, STRICT_TRANS_TABLES,
ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_IN_DATE,
sql_mode See SQL Mode.
NO_AUTO_CREATE_USER, NO_ZERO_DATE,
NO_ENGINE_SUBSTITUTION ERROR_FOR_DIVISION_BY_ZERO,
NO_ENGINE_SUBSTITUTION
Whether FIPS mode is enabled on
ssl_fips_mode - OFF
the server side.
standard_compliant_cte ON - See Common Table Expressions.
Alias for default_storage_engine,
storage_engine InnoDB -
removed in MySQL.
In MariaDB, when password
validation plugins are enabled, reject
strict_password_validation ON -
passwords that cannot be validated
(passwords specified as a hash).
Limits the number of stored program
stored_program_definition_cache - 256 definition objects kept in the
dictionary object cache.
MySQL variable for prohibiting client
super_read_only - OFF updates from users with the SUPER
privilege.
MySQL synchronizes all actions to
sync_binlog 0 1 the binary log before they are
committed.
.frm files have been removed in
sync_frm 1 -
MySQL.
MariaDB has System-Versioned
system_versioning_alter_history ERROR -
Tables
MariaDB has System-Versioned
system_versioning_asof DEFAULT -
Tables
Number of table definitions that can
table_definition_cache 400 -1 (autosized)
be cached.
Maximum number of table cache
table_open_cache_instances 8 16
instances.
Limits the number of tablespace
tablespace_definition_cache - 256 definition objects kept in the
dictionary object cache.
Interval, in seconds, between when
successive keep-alive packets are
tcp_keepalive_interval 0 -
sent if no acknowledgement is
received.
Number of unacknowledged probes
to send before considering the
tcp_keepalive_probes 0 -
connection dead and notifying the
application layer.
Set the TCP_NODELAY option
tcp_keepalive_time 0 - (disable Nagle's algorithm) on
socket.
Timeout, in milliseconds, with no
tcp_nodelay 1 - activity until the first TCP keep-alive
packet is sent.
Limits the RAM used by MySQL's
temptable_max_ram - 1GB
TempTable storage engine.
MariaDB uses an improved thread
thread_cache_size Autosized -1 (autosized)
pool .
thread_concurrency 10 - Removed in MySQL 5.7.

1733/3812
Better precision for the data in the
thread_pool_dedicated_listener 0 - Information Schema
THREADPOOL_QUEUES Table.

Better precision for the data in the


thread_pool_exact_stats 0 - Information Schema
THREADPOOL_QUEUES Table.
thread_pool_idle_timeout 60 - See Using the Thread Pool .
thread_pool_max_threads 65536 - See Using the Thread Pool .
Windows-only. See Using the
thread_pool_min_threads 1 -
Thread Pool .
thread_pool_oversubscribe 3 - See Using the Thread Pool .
thread_pool_prio_kickup auto - See Using the Thread Pool .
thread_pool_priority auto - See Using the Thread Pool .
See Using the Thread Pool . *Only
thread_pool_size Number of processors 16* available in MySQL with a
commercial plugin.
See Using the Thread Pool . *Only
thread_pool_stall_limit 500 6* available in MySQL with a
commercial plugin.
thread_stack 299008 Varies See Using the Thread Pool .
time_format %H:%i:%s - Removed in MySQL.
timed_mutexes OFF - Removed in MySQL.
Max size for data for an internal
tmp_disk_table_size 18446744073709551615 - temporary on-disk MyISAM or Aria
table.
tmp_memory_table_size 16777216 - Alias for tmp_table_size.
Variable for enabling batching of
transaction_allow_batching - OFF statements within the same
transaction in MySQL Cluster.
The MariaDB equivalent is
transaction_isolation - REPEATABLE-READ
tx_isolation.
The MariaDB equivalent is
transaction_read_only - OFF
tx_read_only.
transaction_write_set_extraction - OFF Unused MySQL-only variable.
The MySQL equivalent is
tx_isolation REPEATABLE-READ -
transaction_isolation.
The MySQL equivalent is
tx_read_only OFF -
transaction_read_only.
Controls the use of engine-
use_stat_tables preferably_for_queries -
independent table statistics.
Whether to activate MariaDB's User
userstat OFF - Statistics implementation, not
available in MySQL.
Version of the zlib library compiled
version_compile_zlib - *
in.
version_malloc_library * - Version of the used malloc library.
Permits seeing exactly which
version_source_revision Varies - version of the source was used for a
build.
version_ssl_library * - Version of the used TLS library.
MySQL option allowing safety to be
windowing_high_use_precision - * sacrificed for speed in window
function calculations.
Galera cluster is only available in
wsrep_* * -
MariaDB.
Variable MariaDB 10.6 MySQL 8.0 Notes

See Also
System Variable Differences Between MariaDB 10.5 and MySQL 8.0

2.1.14.1.11.5 System Variable Differences


Between MariaDB 10.5 and MySQL 8.0
Contents
1. Comparison Table
2. See Also

The following is a comparison of variables that either appear only in MariaDB 10.5 or MySQL 8.0, or have different
default settings in MariaDB 10.5, and MySQL 8.0. The RC release MariaDB 10.5.3 and the stable MySQL 8.0.11, with

1734/3812
only default plugins enabled, were used for the comparison. Note that MySQL 8 is an 'evergreen' release, so features
may be added or removed in later releases.
The most notable differences are that MariaDB includes, by default, the Aria storage engine (resulting in extra memory
allocation), Galera Cluster, and has a different thread pool implementation . For this reason, a default implementation
of MariaDB 10.5 will use more memory than MySQL 8.0. MariaDB 10.5 and MySQL 8.0 also have different GTID
implementations.
MariaDB's extra memory usage can be handled with the following rules of thumb:
If you are not using MyISAM and don't plan to use Aria:
Set key_buffer_size to something very low (16K) as it's not used.
Set aria_pagecache_buffer_size to what you think you need for handling internal tmp tables that didn't fit in
memory.
Normally this is what before you had set for key_buffer_size (at least 1M).
If you are using MyISAM and not planning to use Aria:
Set aria_pagecache_buffer_size to what you think you need for handling internal tmp tables that didn't fit in
memory.
If you are planning to use Aria, you should set aria_pagecache_buffer_size to something that fits a big part of
your normal data + overflow temporary tables.

Comparison Table
Variable MariaDB 10.5 Default MySQL 8.0 Default Notes
Determines whether to automatically
activate_all_roles_on_login - OFF
activate roles on login.
MariaDB 10.3 introduced new
ALTER TABLE ALGORITHM
clauses to avoid slow copies in
alter_algorithm DEFAULT -
certain instances. This variable
allows setting this if no ALGORITHM
clause is specified.
Percentage of rows from the table
analyze_sample_percentage 100.0000 - ANALYZE TABLE will sample to
collect table statistics.
The Aria storage engine is only
aria_* * -
available in MariaDB.
Whether to automatically generate
auto_generate_certs - ON
SSL key and certificate files.
Determines whether ALTER TABLE
avoid_temporal_upgrade - OFF implicitly upgrades temporal
columns.
MariaDB and MySQL have different
back_log Autosized Autosized
autosizing algorithms.
Introduced in MariaDB 5.3 for
binlog-annotate-row-events ON - replicating between MariaDB 5.3 and
MySQL/MariaDB 5.1.
For use in MariaDB's parallel
binlog_commit_wait_count 0 -
replication.
For use in MariaDB's parallel
binlog_commit_wait_usec 100000 -
replication.
MySQL-only variable for controlling
binlog_error_action ABORT_SERVER what happens when the server
cannot write to the binary log.
Sets the binary log expiration period
binlog_expire_logs_seconds - 2592000
in seconds
For setting the size of the file cache
binlog_file_cache_size 16184 -
for the binary log.
MariaDB and MySQL have differing
binlog_format MIXED ROW
binary log formats.
MySQL-only variable for controlling
binlog_group_commit_sync_delay 0 the wait time before synchronizing
the binary log file to disk.
MySQL-only variable for setting the
maximum number of transactions to
binlog_group_commit_sync_no_delay_count 0 wait for before aborting the current
binlog_group_commit_sync_delay
delay.
MySQL-only GTID variable.
binlog_gtid_simple_recovery - ON MariaDB's GTID implementation is
different.

Specifies a timeout for reading


transactions from the flush queue
binlog_max_flush_queue_time - 0
before continuing with group commit
and syncing log to disk.
For optimized kernel thread
binlog_optimize_thread_scheduling ON -
scheduling.

1735/3812
Determines whether transactions
binlog_order_commits - ON
may be committed in parallel.
Determines the amount of table
binlog_row_metadata NO_LOG MINIMAL metadata added to the binary log
with row-based logging.
Permits an alternative binlog format
binlog_row_value_options - (empty)
for JSON document updates.
MySQL-only variable for logging
binlog_rows_query_log_events - OFF extra information in row-based
logging.
Maximum number of row hashes
binlog_transaction_dependency_history_size - 25000 kept for looking up transactions that
last modified a given row.
For determining how to best use the
binlog_transaction_dependency_tracking - COMMIT_ORDER
slave's multithreaded applier.
MySQL-only variable for controlling
block_encryption_mode - aes-128-ecb the block encryption mode for block-
based algorithms.
For use with MySQL's SHA-256
caching_sha2_password* - *
authentication with caching.
MySQL 8.0 defaults to the utf8mb4
character_set_* latin1 or utf8 utf8mb4
character set.
Permits disabling constraint checks,
for example when loading a table
check_constraint_checks ON -
that violates some constraints that
you plan to fix later.
MySQL-only variable for controlling
whether the server performs proxy
check_proxy_users OFF
user mapping for authentication
plugins.
MySQL 8.0 defaults to the utf8mb4
collation_* latin1_swedish_ci or utf8_general_ci utf8mb4_0900_ai_ci
character set.
MariaDB supports Storage-engine
column_compression_threshold 100 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_level 6 -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_strategy DEFAULT_STRATEGY -
Independent Column Compression.
MariaDB supports Storage-engine
column_compression_zlib_wrap OFF -
Independent Column Compression.
When MySQL 8.0 introduced
common table expressions they
cte_max_recursion_depth - 1000 used a different name. MariaDB's
variable is called
max_recursive_iterations.
Unused variable removed in MySQL
date_format %Y-%m-%d -
8.0
Unused variable removed in MySQL
datetime_format %Y-%m-%d -
8.0
The Aria storage engine is only
deadlock_search_depth_long 15 -
available in MariaDB.
The Aria storage engine is only
deadlock_search_depth_short 4 -
available in MariaDB.
The Aria storage engine is only
deadlock_timeout_long 50000000 -
available in MariaDB.
The Aria storage engine is only
deadlock_timeout_short 10000 -
available in MariaDB.
Disable system thread alarm calls,
debug_no_thread_alarm OFF -
for debugging or testing.
MySQL 8 introduced a new
default_authentication_plugin - caching_sha2_password
authentication plugin.
For internal use in MySQL 8
default_collation_for_utf8mb4 - utf8mb4_0900_ai_ci
replication.
For use with MariaDB's multi-source
default_master_connection empty -
replication.
MariaDB defaults to password
default_password_lifetime 0 360
expiration off.
For handling incompatibilities
default_regex_flags empty - between MariaDB's PCRE and the
old regex library.
Default storage engine used for
default_tmp_storage_engine empty InnoDB tables created with CREATE
TEMPORARY TABLE.
MySQL-only variable for disabling
disabled_storage_engines empty
specific storage engines.
MariaDB password expiration is off
by default, and by default does not
disconnect_on_expired_password OFF ON
disconnect a client when a password
has expired.

1736/3812
MariaDB enables table and
encrypt_binlog OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_files OFF -
tablespace encryption.
MariaDB enables table and
encrypt_tmp_disk_tables OFF -
tablespace encryption.
MySQL-only variable for adding end
end_markers_in_json - OFF
markers to JSON output.
MariaDB and MySQL have different
enforce_gtid_consistency - OFF
GTID implementations.
Forces the use of a particular
enforce_storage_engine none
storage engine for new tables.
Variable for tuning when the
optimizer should switch from using
eq_range_index_dive_limit 0 200
index dives to index statistics for
qualifying rows estimation.
MySQL enables the event scheduler
event_scheduler OFF ON
by default.
Used for determining expensive
expensive_subquery_limit 100 -
queries for optimization.
MySQL 8 disables the old
explicit_defaults_for_timestamp OFF ON
timestamp behavior.
Introduced in the MariaDB 5.1
extra_max_connections 1 -
threadpool.
Introduced in the MariaDB 5.1
extra_port 0 -
threadpool.
MariaDB increases the maximum
group_concat_max_len 1048576 1024 length for a GROUP_CONCAT()
result from 1K to 1M.
MariaDB and MySQL have different
gtid_binlog_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_binlog_state empty -
GTID implementations.
MariaDB and MySQL have different
gtid_cleanup_batch_size 64 -
GTID implementations.
MariaDB and MySQL have different
gtid_current_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_domain_id 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_executed - empty
GTID implementations.
MariaDB and MySQL have different
gtid_executed_compression_period - 1000
GTID implementations.
MariaDB and MySQL have different
gtid_ignore_duplicates OFF -
GTID implementations.
MariaDB and MySQL have different
gtid_mode - OFF
GTID implementations.
MariaDB and MySQL have different
gtid_next - AUTOMATIC
GTID implementations.
MariaDB and MySQL have different
gtid_owned - empty
GTID implementations.
MariaDB and MySQL have different
gtid_pos_auto_engines empty -
GTID implementations.
MariaDB and MySQL have different
gtid_purged - empty
GTID implementations.
MariaDB and MySQL have different
gtid_seq_no 0 -
GTID implementations.
MariaDB and MySQL have different
gtid_slave_pos empty -
GTID implementations.
MariaDB and MySQL have different
gtid_strict_mode OFF -
GTID implementations.
MySQL has removed the ENCRYPT
have_crypt YES -
function.
MariaDB's version indicates whether
YaSSL or openssl was used.
have_openssl
MySQL's is a synonym for
have_ssl .

MySQL has removed the query


have_query_cache YES -
cache.
Whether MySQL's statement
have_statement_timeout - execution timeout feature is
available.
MySQL has removed symlink
have_symlink YES DISABLED
support.
Added when MySQL 8 introduced
histogram_generation_max_mem_size - 20000000 Histogram-based Statistics.
MariaDB uses histogram_size

1737/3812
MariaDB introduced Histogram-
histogram_size 0 -
based Statistics.
MariaDB introduced Histogram-
histogram_type SINGLE_PREC_HB -
based Statistics.
Time in seconds that the server
idle_readonly_transaction_timeout 0 -
waits for idle read-only transactions.
Time in seconds that the server
idle_transaction_timeout 0 -
waits for idle transactions.
Time in seconds that the server
idle_write_transaction_timeout 0 -
waits for idle write transactions.
ignore_builtin_innodb OFF - Ignored and removed in MySQL 8.
Controls the Conversion of Big IN
in_predicate_conversion_threshold 1000 - Predicates Into Subqueries
optimization.
Set to 1 if you are in a transaction,
in_transaction 0 -
and 0 if not.
Time until MySQL Information
information_schema_stats_expiry - 86400
Schema cached statistics expire.
Adaptive flushing is enabled when
this this low water mark percentage
innodb_adaptive_flushing_lwm 10.000000 10 of the redo log capacity is reached.
MariaDB's variable is a double,
MySQL's an integer.
Defaulting to OFF is a performance
improvement especially for DROP
innodb_adaptive_hash_index OFF ON
TABLE, TRUNCATE TABLE, ALTER
TABLE, or DROP INDEX operations
Specific to MySQL's memcached,
innodb_api_* - *
removed in MariaDB 10.2.
MariaDB has an extra mode, 3 , for
skipping the rollback of connected
innodb_autoinc_lock_mode 1 2 transactions. MySQL defaults to
row-based replication, so can safely
use 2 .
Earlier versions of MariaDB had
innodb_background_* * - support for background data
scrubbing.
fullcrc32 permits encryption to be
innodb_checksum_algorithm full_crc32 crc32 supported over a SPATIAL INDEX,
which crc32 does not support.
Deprecated option removed in
innodb_checksums ON -
MySQL.
Introduced with MariaDB's InnoDB
innodb_compression_* * -
compression.
MySQL option that automatically
configures various settings if the
innodb_dedicated_server - OFF
server is a dedicated InnoDB
database server.
Default encryption key id used for
innodb_default_encryption_key_id 1 - table encryption. See Data at Rest
Encryption.
MariaDB can defragment InnoDB
innodb_defragment * - tablespaces.

Used to search for tablespace files


innodb_directories - (empty) when moving or restoring a new
location.
Tell InnoDB to stop any writes to
innodb_disallow_writes OFF -
disk.
See MariaDB's Data at Rest
innodb_encrypt_* 1 -
Encryption.
MariaDB's fatal semaphore timeout
innodb_fatal_semaphore_wait_threshold 600 -
is configurable.
MariaDB 10.4 has restored this
innodb_file_format (empty) - unused, deprecated variable for
compatibility reasons.
MySQL 8 by default now assumes
innodb_flush_neighbors 1 0
the use of an SSD device.
If set to 1 in MariaDB (0 is default)
CREATE TABLEs without a primary
innodb_force_primary_key OFF - or unique key where all keyparts are
NOT NULL will not be accepted, and
will return an error.
Up to what percentage of dirty pages
in MariaDB should be flushed when
innodb_idle_flush_pct 100 -
InnoDB finds it has spare resources
to do so.
MariaDB has support for data
innodb_immediate_scrub_data_uncompressed OFF -
scrubbing.
See Instant ADD COLUMN for
innodb_instant_alter_column_allowed add_drop_reorder -
InnoDB.

1738/3812
MariaDB 10.4 has restored this
innodb_large_prefix (empty) - unused, deprecated variable for
compatibility reasons.
MariaDB has an improved algorithm
for deciding which of the waiting
innodb_lock_schedule_algorithm VATS -
transactions should be granted a
lock once it has been released.
Deprecated option in MariaDB for
disabling gap locking for searches
innodb_locks_unsafe_for_binlog OFF - and index scans. Deprecated in
MariaDB, use READ COMMITTED
transaction isolation instead.
Deprecated and ignored in MariaDB.
Previously determined whether redo
innodb_log_optimize_ddl OFF - logging should be reduced when
natively creating indexes or
rebuilding tables.
MySQL variables for constraining
innodb_log_spin_* - * CPU usage while waiting for flushed
redo.
MySQL variable for constraining
innodb_log_wait_for_flush_spin_hwm - * CPU usage while waiting for flushed
redo.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct 75 90
90.
MySQL 8 increased the default to
innodb_max_dirty_pages_pct_lwm 0 10
10.
MariaDB 10.2 reduced the limit for
innodb_max_undo_log_size 10485760 1073741824 when an undo tablespace is marked
for truncation.
In most systems, autosized based
on the table_open_cache setting,
innodb_open_files Autosized (2000) Autosized (4000)
which differs between MariaDB and
MySQL.
MariaDB includes the Facebook
innodb_prefix_index_cluster_optimization OFF -
prefix index queries optimization.
MySQL option for writing DDL logs
innodb_print_ddl_logs - OFF
to stderr.
MySQL 8 has also now introduced
redo log encryption, but used a
innodb_redo_log_encrypt - OFF
different name. The equivalent option
in MariaDB is innodb_encrypt_log.
Earlier version of MariaDB included
innodb_scrub_* * -
options to scrub the redo log.
MariaDB changed the default from 6
innodb_spin_wait_delay 4 6 to 4 based on extensive
benchmarking.
MariaDB option to control the
innodb_stats_modified_counter 0 -
calculation of new statistics.
Deprecated MariaDB option for
innodb_stats_sample_pages 8 - control over index distribution
statistics.
Enabling gives a larger sample of
pages for larger tables for the
innodb_stats_traditional ON -
purposes of index statistics
calculation.
MySQL option for encrypting undo
innodb_undo_log_encrypt - OFF logs residing in separate undo
tablespaces.
MySQL 8 changes the default to
innodb_undo_log_truncate OFF ON ON, marking larger undo logs for
truncation.
innodb_undo_logs 128 - Removed in MySQL 8.
Number of tablespace files used for
dividing up the undo logs. MySQL 8
innodb_undo_tablespaces 0 2 has deprecated this setting, and
increased the default (and minimum)
to 2.
Atomic writes are a faster alternative
to innodb_doublewrite and MariaDB
innodb_use_atomic_writes ON -
automatically detects when
supporting SSD cards are used.
MySQL uses this variable to set the
internal_tmp_disk_storage_engine - INNODB storage engine for on-disk internal
temporary tables.
MySQL and MariaDB use different
formats for temporary tables. In
internal_tmp_mem_storage_engine - TEMPTABLE MariaDB, the
aria_used_for_temp_tables performs
a similar function.
Maximum size in bytes of the query
join_buffer_space_limit 2097152 - buffer. See block-based join
algorithms.

1739/3812
For determining the join algorithms.
join_cache_level 2 -
See block-based join algorithms
Size of the buffer for the index
key_buffer_size 134217728 8388608 blocks used by MyISAM tables and
shared for all threads.
Number of hash buckets for open
key_cache_file_hash_size 512 -
and changed files.
The number of segments in a key
key_cache_segments 0 -
cache. See Segmented Key Cache.
Whether MySQL 8's keyring
keyring_operations - ON
operations are enabled.
MariaDB and MySQL have different
last_gtid - empty
GTID implementations.
MySQL no longer supports LOAD
local_infile ON OFF
DATA LOCAL by default.
MariaDB has reduced the timeout for
lock_wait_timeout 86400 31536000
acquiring metadata locks.
MySQL 8 enables the binary log by
log_bin OFF ON
default.
MariaDB setting for whether or not
log_bin_compress OFF -
the binary log can be compressed.
Minimum length of sql statement (in
statement mode) or record (in row
log_bin_compress_min_len 256 - mode) that can be compressed. See
Compressing Events to Reduce Size
of the Binary Log.
MySQL-only variable showing
log_bin_use_v1_row_events - OFF whether or not MySQL's version 2
binary logging format is being used.
Disable logging of certain
log_disabled_statements sp -
statements to the general log.
Components to enable for MySQL
log_error_services - log_filter_internal; log_sink_internal
error logging.
MySQL variable for setting verbosity
log_error_verbosity - 3 of error, warning, and note
messages in the error log.

MySQL 8 has by default enabled


log_slave_updates OFF ON binary logging of updates a slave
receives from a master.
MariaDB logs slow admin
log_slow_admin_statements ON OFF statements to the slow query log by
default.
Disable logging of certain
log_slow_disabled_statements admin,call,slave,sp -
statements to the slow query log.
admin, filesort, filesort_on_disk,
full_join, full_scan, query_cache,
log_slow_filter - For slow query log filtering.
query_cache_miss, tmp_table,
tmp_table_on_disk
Limits the number of queries logged
log_slow_rate_limit 1 -
to the slow query log.
MariaDB logs slow slave statements
log_slow_slave_statements ON OFF
to the slow query log by default.
Controls information to be added to
log_slow_verbosity empty - the slow query log. See also Slow
Query Log Extended Statistics.
MySQL setting for controlling
log_statements_unsafe_for_binlog - ON whether binlog warnings are written
to the error log.
MySQL variables with settings for
log_syslog* platform-dependent -
writing to syslog.
Size in bytes of the transaction
log_tc_size 24576 - coordinator log, defined in multiples
of 4096.
MySQL-only variable for limiting the
number of statements without
log_throttle_queries_not_using_indexes - 0
indexes written to the slow query
log.
MySQL-only variable controlling the
log_timestamps - UTC timezone for certain logging
conditions.
MySQL 8 has replaced with
log_warnings 2 -
log_error_verbosity .

MySQL variable for assigning roles


mandatory_roles - (empty)
to all users.
Whether slave logs master status
master_info_repository - TABLE and connection info to a table or a
file.
max_allowed_packet 16M 64M

1740/3812
Specifies the maximum number of
messages stored for display by
max_error_count 64 1024
SHOW ERRORS and SHOW
WARNINGS statements.
MySQL renamed the
max_execution_time - 0
max_statement_time variable.
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
max_length_for_sort_data 64 1024
these are added to the sort key. This
can speed up the sort as there's no
need 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.
Maximum size for parameter values
sent with
max_long_data_size 16777216 -
mysql_stmt_send_long_data().
Removed in MySQL 5.6.
Maximum number of failed
max_password_errors 4294967295 - connections attempts before no
more are permitted.
Maximum points_per_circle for
max_points_in_geometry - 65536 MySQL's ST_Buffer_Strategy()
function.
Maximum number of iterations when
max_recursive_iterations 4294967295 -
executing recursive queries.
max_relay_log_size 1073741824 0 Can be set by session in MariaDB.
The most key seeks required when
searching with an index, regardless
4294967295 (32-bit) or of the actual index cardinality. If this
max_seeks_for_key 4294967295
18446744073709547520 (64-bit) value is set lower than its default and
maximum, indexes will tend to be
preferred over table scans.
Amount of memory a single user
max_session_mem_used 9223372036854775807 -
session is allowed to allocate.
Maximum time in seconds that a
query can execute before being
max_statement_time 0 - aborted. MySQL used to have a
variable of this name before
renaming it max_execution_time .
max_tmp_tables 32 - Unused variable removed in MySQL.
Read lock requests will be permitted
4294967295 (32-bit) or
max_write_lock_count 4294967295 for processing after this many write
18446744073709547520 (64-bit)
locks.
Size of buffer to use when using
mrr_buffer_size 262144 - multi-range read with range access.
See Multi Range Read optimization.
Block size used for MyISAM index
myisam_block_size 1024 -
pages.
myisam_recover_options BACKUP,QUICK OFF MyISAM recovery mode.
Size in bytes of the buffer allocated
myisam_sort_buffer_size 134216704 8388608 when creating or sorting indexes on
a MyISAM table.
Whether MySQL's authentication
mysql_native_password_proxy_users - OFF
plugin supports proxy users. I
Causes MariaDB to use the MySQL-
5.6 low level formats for TIME,
mysql56_temporal_format ON
DATETIME and TIMESTAMP
instead of the MariaDB 5.3+ version.
Used for backward-compatibility with
new - OFF
MySQL 4.1, not present in MariaDB.
mysqlx+* - * MySQL's X plugin related variables.
Sets the n-gram token size for
ngram_token_size - 2
MySQL's n-gram full-text parser.
MySQL settting for specifying
offline_mode - OFF whether the server should run in
offline mode.
old_alter_table DEFAULT OFF An alias for alter_algorithm.
Used for getting MariaDB to emulate
behavior from an old version of
old_mode Empty string -
MySQL or MariaDB. See OLD
Mode.
MySQL 8 is no longer compatible
old_passwords OFF - with the old pre-MySQL 4.1 form of
password hashing.
Controls number of record samples
optimizer_selectivity_sampling_limit 100 -
to check condition selectivity.

1741/3812
A series of flags for controlling the
optimizer_switch See details query optimizer. MariaDB has
introduced a number of new settings.
MySQL has more settings for
optimizer_trace_* - *
optimizer tracing.
Controls which statistics can be
optimizer_use_condition_selectivity 4 - used by the optimizer when looking
for the best query execution plan.
Used by MySQL 8 for delaying
original_commit_timestamp - *
replication.
4294967295 (32-bit) or MySQL variable for limiting memory
parser_max_mem_size -
18446744073709547520 (64-bit) available to the parser.
Controls reuse of previous
password_* - *
passwords in MySQL.
The Performance Schema is off by
performance_schema OFF ON
default in MariaDB.
Many performance schema variables
are autoset in MySQL, and MySQL
performance_schema_*
has a different version, with
additional variables.

plugin_maturity One less than the server maturity - Minimum acceptable plugin maturity.

You might also like