ℹ️

MariaDB System & Info Functions

MariaDB

Complete reference for MariaDB system and info functions covering VERSION(), DATABASE(), USER(), CONNECTION_ID(), LAST_INSERT_ID(), FOUND_ROWS(), and CURRENT_ROLE(). Every function includes syntax, use cases, and notes on session-scoped vs global behaviour. Updated for MariaDB 11.x.

27 functions

What are MariaDB System & Info Functions?

MariaDB system information functions return metadata about the current server session, database, and user. LAST_INSERT_ID() returns the AUTO_INCREMENT value generated by the most recent INSERT, FOUND_ROWS() returns the number of rows that would have been returned by the last SELECT without LIMIT, and ROW_COUNT() returns the number of rows affected by the last INSERT, UPDATE, DELETE, or REPLACE. These are frequently used in stored procedures and application code to handle post-insert logic.

VERSION

VARCHAR

Returns the MariaDB server version string, always including the '-MariaDB' suffix.

Signature

VERSION()

Examples

Get server version

sql
SELECT VERSION();
-- 10.11.4-MariaDB

System variable alternative

sql
SELECT @@version;
-- 10.11.4-MariaDB

Confirm running MariaDB

sql
SELECT VERSION() LIKE '%MariaDB%';
-- 1

Extract major version

sql
SELECT SUBSTRING_INDEX(VERSION(), '.', 1) AS major;
-- 10

Store in variable

sql
SELECT VERSION() INTO @v; SELECT @v;
-- 10.11.4-MariaDB
Anti-PatternChecking for MySQL with VERSION()

Checking VERSION() LIKE 'MySQL%' will fail on MariaDB. The string contains '-MariaDB' suffix.

✓ Instead: Check VERSION() LIKE '%MariaDB%' or use @@version_comment.

MariaDB Note

Always includes '-MariaDB' in the version string.

⇄ vs MySQL: MySQL VERSION() returns '8.x.x' without '-MariaDB' suffix.
⇄ vs PostgreSQL: PostgreSQL uses version() or current_setting('server_version').

DATABASE

VARCHAR

Returns the name of the currently selected database, or NULL if no database is selected.

Signature

DATABASE()

Examples

Current database name

sql
SELECT DATABASE();
-- mydb

Check if database selected

sql
SELECT DATABASE() IS NULL;
-- 0

After USE statement

sql
USE information_schema; SELECT DATABASE();
-- information_schema

Cross-reference with catalog

sql
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = DATABASE();
-- mydb

Save current DB to variable

sql
SET @db = DATABASE(); SELECT @db;
-- mydb
Anti-PatternHardcoding database name in queries

Using a literal database name in queries makes them non-portable across environments.

✓ Instead: Use DATABASE() to dynamically reference the current database in procedures.

MariaDB Note

Synonym for SCHEMA(). Returns NULL if no database is selected.

⇄ vs MySQL: Identical behavior in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses current_database().

SCHEMA

VARCHAR

Synonym for DATABASE(). Returns the name of the currently selected database.

Signature

SCHEMA()

Examples

Current schema/database name

sql
SELECT SCHEMA();
-- mydb

SCHEMA and DATABASE are identical

sql
SELECT SCHEMA() = DATABASE();
-- 1

Fallback if no DB selected

sql
SELECT COALESCE(SCHEMA(), 'none') AS db;
-- mydb

After switching database

sql
USE test; SELECT SCHEMA();
-- test

List tables in current DB

sql
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = SCHEMA();
-- (list of tables)
Anti-PatternMixing SCHEMA() and DATABASE() inconsistently

Using both interchangeably without convention can confuse readers.

✓ Instead: Pick one and use it consistently; SCHEMA() is closer to standard SQL.

MariaDB Note

Exact synonym for DATABASE().

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses current_schema() or current_database().

USER

VARCHAR

Returns the current MariaDB user and host as 'user@host', representing the connection's authentication credentials.

Signature

USER()

Examples

Current user and host

sql
SELECT USER();
-- admin@localhost

Extract just the username

sql
SELECT SUBSTRING_INDEX(USER(), '@', 1) AS username;
-- admin

Extract just the host

sql
SELECT SUBSTRING_INDEX(USER(), '@', -1) AS host;
-- localhost

Compare to current_user

sql
SELECT USER() = CURRENT_USER();
-- 1 (usually)

DUAL table form

sql
SELECT USER() FROM DUAL;
-- admin@localhost
Anti-PatternUsing USER() for permission checks

USER() returns the login credentials, not the effective privilege account. Security checks based on USER() can be bypassed via proxy users.

✓ Instead: Use CURRENT_USER() which reflects the actual privilege account.

MariaDB Note

Returns 'user@host'. May differ from CURRENT_USER() when using definer-context or proxy accounts.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses session_user or current_user.

CURRENT_USER

VARCHAR

Returns the username and hostname combination that was matched in the grant tables for the current session, reflecting the effective privilege account.

Signatures

CURRENT_USER()
CURRENT_USER

Examples

Matched grant account

sql
SELECT CURRENT_USER();
-- admin@%

Without parentheses (standard SQL)

sql
SELECT CURRENT_USER;
-- admin@%

May differ with wildcards

sql
SELECT USER(), CURRENT_USER();
-- admin@localhost | admin@%

Show own grants

sql
SHOW GRANTS FOR CURRENT_USER();
-- GRANT ... TO 'admin'@'%'

Store in variable

sql
SELECT CURRENT_USER() INTO @cu;
-- admin@%
Anti-PatternConfusing USER() and CURRENT_USER()

USER() is what you logged in as; CURRENT_USER() is the grant row matched. For security decisions, always use CURRENT_USER().

✓ Instead: Use CURRENT_USER() for privilege-related logic.

MariaDB Note

Supports both CURRENT_USER and CURRENT_USER() forms per SQL standard.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses current_user (keyword, no parentheses needed).

SESSION_USER

VARCHAR

Synonym for USER(). Returns the current client user and hostname used for authentication.

Signature

SESSION_USER()

Examples

Session user

sql
SELECT SESSION_USER();
-- admin@localhost

SESSION_USER and USER are identical

sql
SELECT SESSION_USER() = USER();
-- 1

Extract username part

sql
SELECT SUBSTRING_INDEX(SESSION_USER(), '@', 1);
-- admin

DUAL table form

sql
SELECT SESSION_USER() FROM DUAL;
-- admin@localhost

Embed in view

sql
CREATE VIEW session_info AS SELECT SESSION_USER() AS login_user;
-- View created
Anti-PatternUsing SESSION_USER instead of CURRENT_USER for access control

SESSION_USER returns the login identity, not the privilege-matched account. Proxy users can log in as one user but match a different grant.

✓ Instead: Use CURRENT_USER() for access control decisions.

MariaDB Note

Exact synonym for USER().

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses session_user.

SYSTEM_USER

VARCHAR

Synonym for USER(). Returns the current authenticated user and host. Provided for SQL standard compatibility.

Signature

SYSTEM_USER()

Examples

System user

sql
SELECT SYSTEM_USER();
-- admin@localhost

All three user functions agree

sql
SELECT SYSTEM_USER() = SESSION_USER();
-- 1

Synonym confirmation

sql
SELECT SYSTEM_USER() = USER();
-- 1

Audit logging

sql
INSERT INTO audit_log (action, who) VALUES ('login', SYSTEM_USER());
-- 1 row affected

Extract connecting host

sql
SELECT SUBSTRING_INDEX(SYSTEM_USER(), '@', -1) AS client_host;
-- localhost
Anti-PatternAssuming SYSTEM_USER() returns an OS-level user

Despite the name, SYSTEM_USER() in MariaDB returns the database login user, not the operating system user running the server process.

✓ Instead: To get the OS user, query @@global.secure_file_priv or use external tools.

MariaDB Note

Exact synonym for USER() and SESSION_USER().

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses session_user.

CONNECTION_ID

BIGINT UNSIGNED

Returns the unique thread (connection) ID for the current client session. Useful for debugging, locking, and kill commands.

Signature

CONNECTION_ID()

Examples

Current connection thread ID

sql
SELECT CONNECTION_ID();
-- 42

Find self in process list

sql
SHOW PROCESSLIST;
-- (includes row with Id = CONNECTION_ID())

Query own process info

sql
SELECT * FROM information_schema.PROCESSLIST WHERE ID = CONNECTION_ID();
-- (current session row)

Kill own running query

sql
SELECT CONNECTION_ID() INTO @cid; KILL QUERY @cid;
-- (kills own query)

Log connection ID

sql
INSERT INTO session_log (conn_id, ts) VALUES (CONNECTION_ID(), NOW());
-- 1 row affected
Anti-PatternUsing CONNECTION_ID() as a globally unique row ID

Connection IDs are reused after a connection closes. Using them as a permanent unique identifier in tables can cause collisions.

✓ Instead: Use UUID() or an AUTO_INCREMENT column for permanent unique identifiers.

MariaDB Note

Each new client connection gets a unique, incrementing thread ID.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses pg_backend_pid().

LAST_INSERT_ID

BIGINT UNSIGNED

Returns the AUTO_INCREMENT value generated by the most recent INSERT statement in the current session, or sets a custom value for subsequent calls.

Signatures

LAST_INSERT_ID()
LAST_INSERT_ID(expr)

Parameters

ParameterTypeDescription
exprBIGINTIf supplied, sets the return value for subsequent LAST_INSERT_ID() calls without performing an actual insert.

Examples

ID of just-inserted row

sql
INSERT INTO orders (product) VALUES ('Widget'); SELECT LAST_INSERT_ID();
-- 101

Bulk insert returns first ID

sql
INSERT INTO t (a) VALUES (1),(2),(3); SELECT LAST_INSERT_ID();
-- (ID of first inserted row)

Manually set the value

sql
SELECT LAST_INSERT_ID(42); SELECT LAST_INSERT_ID();
-- 42

Atomic counter pattern

sql
UPDATE counters SET n = LAST_INSERT_ID(n+1) WHERE name='hits'; SELECT LAST_INSERT_ID();
-- (incremented value)

System variable alternative

sql
SELECT @@last_insert_id;
-- 101
Anti-PatternAssuming LAST_INSERT_ID() works across sessions

LAST_INSERT_ID() is session-specific. Another connection's inserts do not affect your session's value.

✓ Instead: Always call LAST_INSERT_ID() in the same session immediately after the INSERT.

MariaDB Note

The two-argument form LAST_INSERT_ID(expr) is useful for implementing atomic counters in a single UPDATE statement.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses RETURNING id clause or lastval() / currval().

ROW_COUNT

BIGINT

Returns the number of rows affected by the most recent INSERT, UPDATE, DELETE, or REPLACE statement. Returns -1 for SELECT or statements that produce a result set.

Signature

ROW_COUNT()

Examples

Rows deleted

sql
DELETE FROM logs WHERE created_at < '2024-01-01'; SELECT ROW_COUNT();
-- 1500

Rows updated

sql
UPDATE users SET active=0 WHERE last_login < NOW() - INTERVAL 1 YEAR; SELECT ROW_COUNT();
-- 23

Rows inserted

sql
INSERT INTO t VALUES (1),(2),(3); SELECT ROW_COUNT();
-- 3

SELECT always returns -1

sql
SELECT 1; SELECT ROW_COUNT();
-- -1

After stored procedure

sql
CALL some_proc(); SELECT ROW_COUNT();
-- (rows from last DML in proc)
Anti-PatternCalling ROW_COUNT() after a SELECT

ROW_COUNT() returns -1 after a SELECT statement. It only reflects DML operations.

✓ Instead: Use FOUND_ROWS() or COUNT(*) to count SELECT results.

MariaDB Note

Returns -1 for SELECT; 0 or positive for DML. The CLIENT_FOUND_ROWS connection flag changes UPDATE counting behavior.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses GET DIAGNOSTICS row_count in PL/pgSQL, or check the command tag.

FOUND_ROWS

MySQL deprecated in 8.0; MariaDB retains full support.BIGINT

Returns the number of rows that the preceding SELECT with SQL_CALC_FOUND_ROWS would have returned without the LIMIT clause. Used for pagination to get total result count in one round-trip.

Signature

FOUND_ROWS()

Examples

Total rows ignoring LIMIT

sql
SELECT SQL_CALC_FOUND_ROWS * FROM articles LIMIT 10; SELECT FOUND_ROWS();
-- 342

Pagination: total count

sql
SELECT SQL_CALC_FOUND_ROWS id FROM products WHERE active=1 LIMIT 20 OFFSET 40; SELECT FOUND_ROWS();
-- 150

Without SQL_CALC_FOUND_ROWS returns rows in last result

sql
SELECT * FROM t; SELECT FOUND_ROWS();
-- (same as ROW_COUNT of resultset)

Zero results

sql
SELECT SQL_CALC_FOUND_ROWS * FROM t WHERE 1=0 LIMIT 10; SELECT FOUND_ROWS();
-- 0

Store total for use in procedure

sql
SELECT FOUND_ROWS() INTO @total;
-- @total = 342
Anti-PatternUsing FOUND_ROWS() without SQL_CALC_FOUND_ROWS

Without the SQL_CALC_FOUND_ROWS hint, FOUND_ROWS() just returns the number of rows in the last result set, not the full count without LIMIT.

✓ Instead: Always pair FOUND_ROWS() with SELECT SQL_CALC_FOUND_ROWS ... LIMIT n.

MariaDB Note

Not deprecated in MariaDB. Actively maintained and preferred for pagination in many MariaDB applications.

⇄ vs MySQL: MySQL 8.0 deprecated SQL_CALC_FOUND_ROWS and FOUND_ROWS(). MariaDB keeps them active and has no deprecation plan.
⇄ vs PostgreSQL: PostgreSQL has no direct equivalent; use a CTE with COUNT(*) or a window function.

BENCHMARK

INT

Executes an expression a specified number of times and returns 0. Used to measure the performance/speed of scalar expressions.

Signature

BENCHMARK(count, expr)

Parameters

ParameterTypeDescription
countBIGINT UNSIGNEDNumber of times to evaluate the expression.
exprany scalarThe scalar expression to evaluate repeatedly.

Examples

Benchmark MD5 hashing

sql
SELECT BENCHMARK(1000000, MD5('hello'));
-- 0 (check elapsed time)

Benchmark encryption

sql
SELECT BENCHMARK(500000, AES_ENCRYPT('text', 'key'));
-- 0

Baseline arithmetic benchmark

sql
SELECT BENCHMARK(1000000, 1+1);
-- 0

Compare SHA2 cost

sql
SELECT BENCHMARK(100000, SHA2('password', 256));
-- 0

Benchmark a subquery (use low count)

sql
SELECT BENCHMARK(1000, (SELECT COUNT(*) FROM large_table));
-- 0
Anti-PatternUsing BENCHMARK() with very high counts on expensive queries

Running BENCHMARK(1000000, complex_subquery) can lock up your server. Subqueries are re-executed each iteration.

✓ Instead: Use small counts (100–10000) for subqueries, or benchmark with scalar built-in functions only.

MariaDB Note

Returns 0, not timing data. Timing is observed via client elapsed time.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL has no built-in BENCHMARK(); use pgbench or EXPLAIN ANALYZE.

CHARSET

VARCHAR

Returns the character set of a string argument. Reflects the character set encoding of the given value.

Signature

CHARSET(str)

Parameters

ParameterTypeDescription
strVARCHAR/anyThe string value whose character set is to be returned.

Examples

Default client charset

sql
SELECT CHARSET('hello');
-- utf8mb4

After CONVERT

sql
SELECT CHARSET(CONVERT('hello' USING latin1));
-- latin1

System function result charset

sql
SELECT CHARSET(USER());
-- utf8mb3

Check column charset

sql
SELECT col, CHARSET(col) FROM t LIMIT 1;
-- (col value) | utf8mb4

Charset introducer

sql
SELECT CHARSET(_utf8mb4 'test');
-- utf8mb4
Anti-PatternAssuming all strings have the same charset

Mixing charsets (e.g., utf8mb3 and utf8mb4) in JOINs or comparisons can cause implicit conversions and index misses.

✓ Instead: Use CHARSET() to diagnose, then standardize columns to utf8mb4.

MariaDB Note

Returns the character set name as a string.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL does not have a CHARSET() function; use pg_catalog functions.

COERCIBILITY

INT

Returns the collation coercibility value of a string argument. The coercibility value determines which collation wins when two strings of different collations are compared.

Signature

COERCIBILITY(str)

Parameters

ParameterTypeDescription
strVARCHAR/anyThe string expression whose coercibility is checked.

Examples

Literal string = coercibility 4

sql
SELECT COERCIBILITY('hello');
-- 4

System function = coercibility 3

sql
SELECT COERCIBILITY(USER());
-- 3

Column = coercibility 2

sql
SELECT COERCIBILITY(col) FROM t LIMIT 1;
-- 2

Explicit COLLATE = coercibility 0

sql
SELECT COERCIBILITY('x' COLLATE utf8mb4_bin);
-- 0

NULL = coercibility 6 (ignorable)

sql
SELECT COERCIBILITY(NULL);
-- 6
Anti-PatternIgnoring coercibility when diagnosing collation errors

When you get 'Illegal mix of collations', not knowing the coercibility of each side makes the error hard to fix.

✓ Instead: Run SELECT COERCIBILITY(expr) on both sides to understand which should be cast.

MariaDB Note

Scale: 0 (explicit COLLATE) < 1 (no collation) < 2 (column) < 3 (system func) < 4 (literal) < 5 (numeric/temporal) < 6 (NULL).

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL handles collation differently; no direct COERCIBILITY() equivalent.

COLLATION

VARCHAR

Returns the collation name of the given string argument.

Signature

COLLATION(str)

Parameters

ParameterTypeDescription
strVARCHAR/anyThe string expression whose collation is to be returned.

Examples

Default collation for literal

sql
SELECT COLLATION('hello');
-- utf8mb4_general_ci

Collation of a table column

sql
SELECT COLLATION(col) FROM t LIMIT 1;
-- utf8mb4_unicode_ci

After CONVERT

sql
SELECT COLLATION(CONVERT('hi' USING utf8mb4));
-- utf8mb4_general_ci

Explicit collation

sql
SELECT COLLATION('x' COLLATE utf8mb4_bin);
-- utf8mb4_bin

System function collation

sql
SELECT COLLATION(USER());
-- utf8mb3_general_ci
Anti-PatternAssuming columns are case-insensitive

A column with _bin or _cs collation will treat 'Hello' and 'hello' as different values.

✓ Instead: Use COLLATION(col) to check, then add a COLLATE clause if you need to override.

MariaDB Note

Returns the full collation name including charset prefix.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL does not have a COLLATION() function; use pg_attribute or information_schema.

CURRENT_ROLE

Available since MariaDB 10.0.5.VARCHAR

Returns the currently active role(s) for the session, or NONE if no role is set. MariaDB roles were introduced in 10.0.5.

Signature

CURRENT_ROLE()

Examples

No role currently active

sql
SELECT CURRENT_ROLE();
-- NONE

After activating a role

sql
SET ROLE analyst; SELECT CURRENT_ROLE();
-- analyst

Activate all granted roles

sql
SET ROLE ALL; SELECT CURRENT_ROLE();
-- (all granted roles)

Set default role

sql
SET DEFAULT ROLE analyst FOR 'bob'@'%'; SELECT CURRENT_ROLE();
-- analyst (on next login)

Store role in variable

sql
SELECT CURRENT_ROLE() INTO @role; SELECT @role;
-- analyst
Anti-PatternExpecting CURRENT_ROLE() to auto-activate roles

Even if a user has been granted a role, CURRENT_ROLE() returns NONE unless SET ROLE or SET DEFAULT ROLE has been applied.

✓ Instead: Use SET DEFAULT ROLE for automatic activation, or SET ROLE at session start.

MariaDB Note

Roles introduced in MariaDB 10.0.5. MySQL has a different role activation model.

⇄ vs MySQL: MySQL 8.0 added roles but uses @@role_xxx variables; behavior differs subtly.
⇄ vs PostgreSQL: PostgreSQL uses current_role (SQL keyword).

DEFAULT

varies

Returns the default value defined for a table column. Used in INSERT/UPDATE statements to explicitly request the column's DEFAULT value.

Signature

DEFAULT(col_name)

Parameters

ParameterTypeDescription
col_namecolumn referenceThe table column whose default value is to be retrieved.

Examples

Show default for a timestamp column

sql
SELECT DEFAULT(created_at) FROM orders LIMIT 1;
-- CURRENT_TIMESTAMP

Insert using column default

sql
INSERT INTO orders (status) VALUES (DEFAULT(status));
-- 1 row affected

Reset column to default

sql
UPDATE orders SET priority = DEFAULT(priority) WHERE id = 5;
-- 1 row affected

Numeric column default

sql
SELECT DEFAULT(stock) FROM products LIMIT 1;
-- 0

Compare value to default

sql
SELECT col, DEFAULT(col) FROM t LIMIT 3;
-- (value | default_val)
Anti-PatternUsing DEFAULT(col) on columns without a defined default

Calling DEFAULT() on a column that has no DEFAULT clause results in an error.

✓ Instead: Check information_schema.COLUMNS for COLUMN_DEFAULT before using DEFAULT().

MariaDB Note

Can be used in both DML and SELECT contexts.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses column_default from information_schema.columns; no DEFAULT() function.

GET_LOCK

INT

Acquires a named advisory lock. Returns 1 if the lock was obtained, 0 if timed out, NULL on error. In MariaDB, multiple named locks per session are supported simultaneously.

Signature

GET_LOCK(str, timeout)

Parameters

ParameterTypeDescription
strVARCHARThe name of the advisory lock to acquire.
timeoutINTNumber of seconds to wait for the lock. Use -1 for indefinite wait, 0 for immediate (no wait).

Examples

Acquired within 10 seconds

sql
SELECT GET_LOCK('my_task', 10);
-- 1

Already locked, no wait

sql
SELECT GET_LOCK('my_task', 0);
-- 0

Multiple locks in one session

sql
SELECT GET_LOCK('lock_a', 5), GET_LOCK('lock_b', 5);
-- 1 | 1

Wait forever for lock

sql
DO GET_LOCK('import_job', -1);
-- (waits indefinitely)

Check before proceeding

sql
SELECT GET_LOCK('task', 30) INTO @got; IF @got = 1 THEN /* do work */ END IF;
-- conditional logic
Anti-PatternForgetting to release advisory locks

Locks held with GET_LOCK() are automatically released when the session ends, but if you hold them through long operations, other sessions block. Not releasing explicitly causes unnecessary waits.

✓ Instead: Always call RELEASE_LOCK() when the critical section is complete, or use RELEASE_ALL_LOCKS().

MariaDB Note

Multiple simultaneous named locks per session are natively supported.

⇄ vs MySQL: MySQL 5.7 and earlier could only hold one named lock per session; MySQL 8.0+ supports multiple. MariaDB has always (since 10.0) supported multiple.
⇄ vs PostgreSQL: PostgreSQL uses pg_advisory_lock() / pg_advisory_unlock().

RELEASE_LOCK

INT

Releases the named advisory lock acquired with GET_LOCK(). Returns 1 if the lock was released, 0 if the lock was not held by this thread, NULL if the lock does not exist.

Signature

RELEASE_LOCK(str)

Parameters

ParameterTypeDescription
strVARCHARThe name of the advisory lock to release.

Examples

Successfully released

sql
SELECT RELEASE_LOCK('my_task');
-- 1

Lock does not exist

sql
SELECT RELEASE_LOCK('nonexistent_lock');
-- NULL

Not held by this thread

sql
SELECT RELEASE_LOCK('other_sessions_lock');
-- 0

Acquire then release pattern

sql
SELECT GET_LOCK('job', 10); /* work */ SELECT RELEASE_LOCK('job');
-- 1 | 1

Release multiple locks

sql
SELECT RELEASE_LOCK('a'), RELEASE_LOCK('b');
-- 1 | 1
Anti-PatternReleasing a lock from a different session

RELEASE_LOCK() can only release locks held by the current session. Attempting to release another session's lock returns 0 (not an error), which may mislead callers into thinking the resource is free.

✓ Instead: Use IS_USED_LOCK() to check which connection holds the lock before attempting release.

MariaDB Note

Supports releasing individual named locks from a multi-lock session.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses pg_advisory_unlock().

IS_FREE_LOCK

INT

Checks whether the named advisory lock is free (not held by any session). Returns 1 if free, 0 if in use, NULL if an error occurred.

Signature

IS_FREE_LOCK(str)

Parameters

ParameterTypeDescription
strVARCHARThe name of the advisory lock to check.

Examples

Lock is not held

sql
SELECT IS_FREE_LOCK('my_task');
-- 1

After acquiring, no longer free

sql
SELECT GET_LOCK('my_task',0); SELECT IS_FREE_LOCK('my_task');
-- 1 | 0

Check before trying to acquire

sql
SELECT IS_FREE_LOCK('import_job') AS available;
-- 1

Polling pattern (use with caution)

sql
WHILE IS_FREE_LOCK('resource') = 0 DO SELECT SLEEP(0.1); END WHILE;
-- (busy wait loop)

Human-readable status

sql
SELECT IF(IS_FREE_LOCK('task'), 'Available', 'Busy') AS status;
-- Available
Anti-PatternTOCTOU race between IS_FREE_LOCK and GET_LOCK

Checking IS_FREE_LOCK() then calling GET_LOCK() is not atomic. Another session can grab the lock between the two calls.

✓ Instead: Call GET_LOCK() with timeout=0 directly; check the return value for 1 (acquired) or 0 (already locked).

MariaDB Note

Returns NULL on error (e.g., invalid lock name).

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses pg_try_advisory_lock() for non-blocking acquisition.

IS_USED_LOCK

BIGINT UNSIGNED

Returns the connection ID of the session that holds the named advisory lock, or NULL if the lock is not held.

Signature

IS_USED_LOCK(str)

Parameters

ParameterTypeDescription
strVARCHARThe name of the advisory lock to check.

Examples

Lock is free

sql
SELECT IS_USED_LOCK('my_task');
-- NULL

Returns holder connection ID

sql
SELECT GET_LOCK('my_task',0); SELECT IS_USED_LOCK('my_task');
-- 42

Check if current session holds it

sql
SELECT IS_USED_LOCK('import') = CONNECTION_ID() AS i_hold_it;
-- 1

Identify the blocking session

sql
SELECT * FROM information_schema.PROCESSLIST WHERE ID = IS_USED_LOCK('task');
-- (holder's process info)

Descriptive status

sql
SELECT IF(IS_USED_LOCK('job') IS NULL, 'Free', CONCAT('Held by conn ', IS_USED_LOCK('job'))) AS status;
-- Free
Anti-PatternKILLing the lock holder without investigation

Seeing IS_USED_LOCK() return a connection ID and immediately KILL-ing it can interrupt important operations.

✓ Instead: Use SHOW PROCESSLIST or query INFORMATION_SCHEMA.PROCESSLIST to understand what the holder is doing before taking action.

MariaDB Note

Returns NULL when the lock is not held by any session.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses pg_locks view to see advisory lock holders.

RELEASE_ALL_LOCKS

Available since MariaDB 10.0.2.INT

Releases all named advisory locks held by the current session at once. Returns the number of locks released.

Signature

RELEASE_ALL_LOCKS()

Examples

Released 3 locks held by this session

sql
SELECT RELEASE_ALL_LOCKS();
-- 3

Acquire two then release all

sql
SELECT GET_LOCK('a',1); SELECT GET_LOCK('b',1); SELECT RELEASE_ALL_LOCKS();
-- 1 | 1 | 2

No locks held returns 0

sql
SELECT RELEASE_ALL_LOCKS();
-- 0

Silent release

sql
DO RELEASE_ALL_LOCKS();
-- (no result set)

Named result column

sql
SELECT RELEASE_ALL_LOCKS() AS locks_freed;
-- 1
Anti-PatternRelying on session end instead of RELEASE_ALL_LOCKS()

Locks are released when a session closes, but a long-lived connection pool keeps sessions open. This can starve other sessions of advisory locks.

✓ Instead: Call RELEASE_ALL_LOCKS() explicitly in cleanup or FINALLY-equivalent error handler code.

MariaDB Note

Returns count of released locks. Particularly important in MariaDB since multiple named locks per session are the norm.

⇄ vs MySQL: Available in MySQL 5.7.5+. MariaDB has supported multiple locks per session longer.
⇄ vs PostgreSQL: PostgreSQL uses pg_advisory_unlock_all().

MASTER_GTID_WAIT

Available since MariaDB 10.0.9.INT

Waits until the replica has applied all transactions up to the given GTID position, or until the timeout expires. Returns 0 on success, -1 on timeout, 1 on error.

Signatures

MASTER_GTID_WAIT(gtid_pos)
MASTER_GTID_WAIT(gtid_pos, timeout)

Parameters

ParameterTypeDescription
gtid_posVARCHARThe GTID position string to wait for (e.g., '0-1-100').
timeoutDECIMALMaximum seconds to wait. Omit or use -1 for indefinite wait.

Examples

Wait until replica reaches GTID

sql
SELECT MASTER_GTID_WAIT('0-1-150');
-- 0

Timeout after 5 seconds

sql
SELECT MASTER_GTID_WAIT('0-1-150', 5);
-- -1

Non-blocking check

sql
SELECT MASTER_GTID_WAIT('0-1-150', 0);
-- 0 or -1

Read-your-own-writes pattern

sql
SET @gtid = (SELECT @@last_gtid); /* do something on replica */ SELECT MASTER_GTID_WAIT(@gtid, 30);
-- 0

Status message

sql
SELECT IF(MASTER_GTID_WAIT('0-1-200', 10) = 0, 'Synced', 'Timeout') AS replication_status;
-- Synced
Anti-PatternUsing MASTER_GTID_WAIT with an indefinite timeout in production

Omitting the timeout or passing -1 can block an application thread indefinitely if replication lags.

✓ Instead: Always specify a reasonable timeout and handle the -1 (timeout) return value with a fallback or retry.

MariaDB Note

MariaDB GTID format is 'domain_id-server_id-sequence_no', different from MySQL's UUID-based GTIDs.

⇄ vs MySQL: MySQL uses WAIT_FOR_EXECUTED_GTID_SET() with a different GTID format.
⇄ vs PostgreSQL: PostgreSQL uses pg_wal_replay_pause() / pg_wal_replay_resume() and pg_last_wal_replay_lsn() for similar patterns.

SLEEP

INT

Pauses execution for the specified number of seconds (fractional seconds supported). Returns 0 on normal completion, 1 if interrupted.

Signature

SLEEP(seconds)

Parameters

ParameterTypeDescription
secondsDECIMALDuration to sleep in seconds. Fractional values (e.g., 0.5) are accepted.

Examples

Sleep 1 second

sql
SELECT SLEEP(1);
-- 0

Sleep 250 milliseconds

sql
SELECT SLEEP(0.25);
-- 0

Returns 1 if interrupted by KILL

sql
SELECT SLEEP(60);
-- 1 (if killed)

Use with BENCHMARK

sql
SELECT BENCHMARK(1, SLEEP(2));
-- 0 (after 2 sec)

Zero-sleep status check

sql
SELECT IF(SLEEP(0) = 0, 'OK', 'Interrupted') AS status;
-- OK
Anti-PatternUsing SLEEP() in production queries for throttling

SLEEP() holds a connection and any locks for the entire duration. Using it to throttle query rates blocks connection pool slots.

✓ Instead: Handle throttling in application code, outside the database connection context.

MariaDB Note

Returns 1 when the sleep is interrupted via KILL QUERY.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses pg_sleep(seconds).

UUID

VARCHAR(36)

Generates a universally unique identifier (UUID) conforming to RFC 4122 version 1, returned as a 36-character string with hyphens.

Signature

UUID()

Examples

Generate UUID v1

sql
SELECT UUID();
-- '6ccd780c-baba-1026-9564-5b8c656024db'

UUID without hyphens

sql
SELECT REPLACE(UUID(), '-', '') AS uuid_hex;
-- '6ccd780cbaba102695645b8c656024db'

Use UUID as row ID

sql
INSERT INTO events (id, name) VALUES (UUID(), 'click');
-- 1 row affected

Two calls always differ

sql
SELECT UUID() = UUID();
-- 0

Compact binary storage

sql
SELECT UNHEX(REPLACE(UUID(),'-','')) AS uuid_binary;
-- (16 bytes)
Anti-PatternUsing VARCHAR(36) UUID as a clustered primary key

Random UUID values inserted as the clustered index key (InnoDB PRIMARY KEY) cause random page splits and severe insert fragmentation.

✓ Instead: Use UUID_SHORT() for monotonic 64-bit IDs, or store UUIDs in BINARY(16) and keep an AUTO_INCREMENT PK for clustering.

MariaDB Note

Returns a UUID v1 (time-based). The MAC address portion may be random on VMs.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses gen_random_uuid() (v4) or uuid_generate_v1() via extension.

UUID_SHORT

BIGINT UNSIGNED

Returns a short universally unique 64-bit integer that is monotonically increasing per server. Combines server_id, startup time, and a per-session sequence counter.

Signature

UUID_SHORT()

Examples

64-bit unique integer

sql
SELECT UUID_SHORT();
-- 92395783831158784

Monotonically increasing

sql
SELECT UUID_SHORT() < UUID_SHORT();
-- 1

Use as primary key

sql
INSERT INTO records (id, data) VALUES (UUID_SHORT(), 'hello');
-- 1 row affected

Capture for reuse

sql
SELECT UUID_SHORT() INTO @id; SELECT @id;
-- 92395783831158784

Pair with timestamp

sql
SELECT UUID_SHORT() AS id, NOW() AS created;
-- (id | timestamp)
Anti-PatternUsing UUID_SHORT() with duplicate server_id values

UUID_SHORT() incorporates @@server_id. If multiple servers have the same server_id (misconfigured replication), UUID_SHORT() can produce collisions.

✓ Instead: Ensure every server in the topology has a unique @@server_id before using UUID_SHORT() as a distributed unique key.

MariaDB Note

The value encodes: (server_id << 56) + (server_startup_time_sec << 24) + per-connection auto-increment.

⇄ vs MySQL: Identical in MySQL.
⇄ vs PostgreSQL: PostgreSQL uses sequences or gen_random_uuid(); no direct monotonic 64-bit UUID function.

SYS_GUID

Available since MariaDB 10.3 Oracle compatibility mode.VARCHAR(32)

Oracle compatibility function that generates a globally unique identifier. Returns a 32-character hexadecimal string (UUID without hyphens). Only available when the SQL_MODE includes 'ORACLE' or when running MariaDB's Oracle compatibility mode.

Signature

SYS_GUID()

Examples

UUID in Oracle format

sql
SET SQL_MODE='ORACLE'; SELECT SYS_GUID();
-- '6CCD780CBABA102695645B8C656024DB'

Always 32 hex characters

sql
SET SQL_MODE='ORACLE'; SELECT LENGTH(SYS_GUID());
-- 32

Use as row identifier

sql
SET SQL_MODE='ORACLE'; INSERT INTO t (id) VALUES (SYS_GUID());
-- 1 row affected

Each call produces unique value

sql
SET SQL_MODE='ORACLE'; SELECT SYS_GUID() = SYS_GUID();
-- 0

Standard SQL equivalent

sql
SELECT REPLACE(UUID(), '-', '') AS same_as_sys_guid;
-- '6ccd780cbaba102695645b8c656024db'
Anti-PatternUsing SYS_GUID() without Oracle SQL mode enabled

SYS_GUID() is only available in Oracle compatibility mode (sql_mode=ORACLE). Calling it in standard mode raises an error.

✓ Instead: Use UUID() or REPLACE(UUID(), '-', '') in standard MariaDB code.

MariaDB Note

Only available in Oracle SQL mode (sql_mode contains 'ORACLE'). Returns uppercase hex without hyphens.

⇄ vs MySQL: MySQL does not have SYS_GUID(). This is a MariaDB Oracle compatibility extension.
⇄ vs PostgreSQL: PostgreSQL uses gen_random_uuid() which returns UUID v4.

Related MariaDB Categories