Skip to main content

Viewing Installed Extensions

Query installed extensions using the INFORMATION_SCHEMA view:
Output:
Usage:
  • Use in both interactive sessions and scripts
  • Standard SQL interface compatible with MySQL tools

Checking Extension Functions

Verify extension functions work after installation:

Extension Directory

Check where VillageSQL looks for .veb files:
List available extensions:

Configuring veb_dir

To change the extension directory location, set veb_dir in your MySQL configuration file: my.cnf / my.ini:
Requirements:
  • Path must be absolute (not relative)
  • Directory must exist before server start
  • MySQL user must have read permissions on the directory
  • Only one veb_dir is supported (cannot have multiple paths)
  • Changes require server restart to take effect
Verify after restart:

Troubleshooting

Quick Reference

Extension Not Found

Error: Extension 'my_extension' not found Debug steps:

Function Not Available After Install

Error: FUNCTION my_func does not exist Debug steps:

Extension Shows Old Behavior After Update

Symptom: After replacing a .veb file and reinstalling, the extension still runs old code. Cause: VillageSQL expands .veb files into {datadir}/.veb_expansion_cache/ on first load. If you copy a new .veb without first running UNINSTALL EXTENSION, the server continues using the previously-expanded .so that is already loaded in memory. Solution: Always follow the full UNINSTALL → replace → INSTALL cycle:
Then replace the .veb file in veb_dir and reinstall:
If the extension still shows old behavior, clear the expansion cache before reinstalling:

Cannot Uninstall Extension

Error: Cannot uninstall extension: types in use Solution:

Library Loading Errors

Error: Cannot load library: undefined symbol Causes:
  • Missing library dependencies
  • ABI compatibility mismatch
  • Incorrect MySQL version
Debug:

Extension Name Validation Errors

Error: Failed to load VEF extension 'extension_name' with log message Extension name mismatch Cause: The extension name in manifest.json doesn’t match the VEB filename. Debug steps:
  1. Check VEB filename matches manifest:
  2. Verify manifest.json name field:
Solution: Both names must be identical, using underscores (see Extension Naming Conventions):
  • VEB filename: my_extension.veb
  • manifest.json: "name": "my_extension"
Common mistakes:
  • Using hyphens in manifest: "name": "my-extension"
  • VEB filename doesn’t match: my-extension.veb vs "name": "my_extension"
Correct example:

Custom Type Comparison Errors

Error: Cannot compare types X and Y in = Cause: Both sides of the comparison are custom types but from different types or extensions.
Solution: Ensure both sides of a comparison use the same custom type. If you need to compare across types, convert one side explicitly using the appropriate type conversion function.
Error: Unable to implicitly cast a non-custom type during compare with a custom type in = Cause: One side of the comparison is a custom type column and the other is a value (literal or column) that cannot be automatically converted to that type.
Solution: String literals are automatically cast to the custom type using the type’s encode function. For other types (integers, floats), use an explicit conversion function:

Monitoring Extension Usage

Query Performance

Track VDF execution times using performance_schema:

Custom Type Usage

Track which tables use custom types:

Updating Extensions

To change an installed extension to a different version, use ALTER EXTENSION. It validates the new version against your existing data and applies the change the next time the server restarts. A manual uninstall and reinstall remains available as an alternative.

Changing an Extension Version

ALTER EXTENSION changes an installed extension to a different version, applied at the next server restart:
VillageSQL resolves the target version on disk and runs a compatibility precheck before accepting the change. The target VEB must exist in the extension directory as <name>-<version>.veb (here, update_test-1.2.0.veb); a missing file is rejected:
The precheck looks for known incompatibilities that would break stored data — for example a change to a custom type’s persisted length:
Once accepted, the change applies at the next restart. Until then, INFORMATION_SCHEMA.EXTENSIONS reports the current version alongside the target it will change to:
INFORMATION_SCHEMA.EXTENSIONS reports a scheduled change in four columns: One scheduled change is tracked at a time:
  • Cancel a scheduled change by requesting the current version again:
  • Requesting the current version when nothing is scheduled does nothing:
  • A different target is refused while a change is scheduled — cancel the existing one first:
The AT RESTART clause applies the change during the next server startup.

After a Successful Restart

On the next restart the pending change applies: EXTENSION_VERSION becomes the target and PENDING_VERSION clears. For the change scheduled above (update_test 1.0.0 → pending 1.2.0):
Any custom_columns and stored-procedure-parameter rows referencing the old version are rewritten during the same restart, so dependent tables and routines keep working with no manual migration.
The change applies during restart, not on a live connection — the values above are the post-restart state.

Recovering from a Pending Version Change at Startup

A scheduled version change is applied during the next server startup. If a pending action can’t be applied, the server can fail to start while persisting its pending-update decisions. Use --villagesql-skip-extension-updates when a queued ALTER EXTENSION ... AT RESTART is blocking startup and you need the server up before you can clear it. --villagesql-skip-extension-updates is a mysqld startup flag. When set, the server bypasses processing of pending ALTER EXTENSION ... AT RESTART actions: each extension loads at its currently-installed version, and its pending action is left intact on disk. The flag mutates nothing itself — it only skips applying the pending actions for that one startup. When the flag is set and at least one extension has a pending action, the server logs a single warning at startup naming how many were bypassed:
1

Start the server with the flag

In production, pass it as a normal mysqld command-line option or add it under [mysqld] in my.cnf:
In the dev harness, pass it through with --:
Success signal: the server starts, and the error log contains the bypassing N pending extension update(s) warning shown above.
2

Identify the pending actions

Success signal: each row’s PENDING_VERSION is the target you need to clear; PENDING_LAST_ERROR shows why it failed to apply.
3

Clear each pending action

For every extension returned above, request its current version to cancel the queued change (the cancel mechanism described under Changing an Extension Version):
Success signal: a Cleared pending update for extension '<name>' (target matches current version '<current>') note is returned, and re-running the previous query shows PENDING_VERSION is NULL.
4

Restart without the flag

Restart the server normally, omitting --villagesql-skip-extension-updates.Success signal: the server starts and the bypassing N pending extension update(s) warning no longer appears in the log.

Manual Update Process

  1. Uninstall the current version:
  2. Replace the .veb file:
  3. Install the new version:
  4. Verify the update:
Data Safety: If tables use custom types from the extension, you must drop or alter those tables before uninstalling. Back up your data first.
Example:

Cleaning Up

Remove Orphaned Expansion Directories

VillageSQL expands .veb files to {datadir}/.veb_expansion_cache/{name}/{sha256}/. Old versions accumulate over time.
Server restart automatically cleans up orphaned expansion directories.

Replication

Custom types require ROW format binlog. STATEMENT and MIXED modes are not supported for tables with custom type columns. INSERT, UPDATE, DELETE, and ALTER TABLE operations on custom type columns all replicate correctly in ROW format. INSTALL EXTENSION is not replicated — each server manages its own extensions. Install the extension on every replica before replication starts, using the same version as the source. The server enforces exact version matching; a version mismatch stops replication. If a replica encounters a custom type it doesn’t recognize, replication stops at the DDL statement — on CREATE TABLE or ALTER TABLE, before any dependent DML is applied. Install the correct extension version, then resume:
mysqldump preserves fully qualified custom type names in the output. Logical restores work as long as the extension is installed on the target server before importing the dump.
Behavior with the Clone plugin, XtraBackup, and InnoDB Cluster / Group Replication is not yet tested. Test your restore path before relying on it in production.

Using Extensions with Docker

When running VillageSQL in Docker, mount a local directory as veb_dir so you can add .veb files from the host without rebuilding the container. Docker Compose example:
Copy a .veb file into ./extensions/ on the host, then install from SQL:
To verify the directory the running server is using:

Getting Help

If you encounter issues not covered here:
  1. Check Error Log: Most extension errors are logged with details
  2. Review Extension Docs: Extension-specific troubleshooting may exist
  3. Ask on Discord: Join the VillageSQL Discord
  4. File an Issue: Report bugs on GitHub Issues

Next Steps

System Reference

Query system tables and views

Uninstall Extensions

Remove extensions safely

Extension Architecture

Understand the internals