Key Takeaways
- The right package: Install
mysql-serverfrom the official MySQL APT repository atdev.mysql.com/downloads/repo/apt/— not from Ubuntu’s default repos, which ship MySQL 8.0.36. MySQL 9.0 adds the VECTOR type, improved JSON functions, and JavaScript stored procedures. - Security first: Run
mysql_secure_installationimmediately after install. Set a strong root password, remove anonymous users, disable remote root login, and drop the test database — four critical steps the installer skips. - Least-privilege users: Create one database user per application with
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'appuser'@'localhost'— never grant ALL PRIVILEGES or use root for app connections. - What changed in MySQL 9.0: The query cache was fully removed (deprecated since 8.0). The
VECTOR(N)data type was added for AI embedding storage. JavaScript stored procedures are now supported via the built-in Polyglot component.
Introduction: MySQL 9.0 on Ubuntu 24.04
Direct Answer: How do I install MySQL 9.0 on Ubuntu 24.04 LTS in 2026?
To install MySQL 9.0 on Ubuntu 24.04 LTS, download and install the MySQL APT repository package from dev.mysql.com, run sudo apt-get update && sudo apt-get install -y mysql-server, then secure the installation with sudo mysql_secure_installation. The process takes under 5 minutes. Ubuntu 24.04’s default repositories ship MySQL 8.0.36 — significantly older than 9.0.1. Using the official MySQL APT repository ensures you get the current release with all security patches. After installation, log in with sudo mysql (root uses auth_socket by default), create your first database with CREATE DATABASE myapp;, create a dedicated user with CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'strong-password';, and grant minimal permissions with GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'appuser'@'localhost';. MySQL 9.0.1 on Ubuntu 24.04 runs cleanly on 1GB RAM minimum, though 4GB is recommended for production workloads with InnoDB buffer pool tuning.
“Every application database deserves its own user with exactly the permissions it needs — nothing more. The root account is for administration, not application connections.”
MySQL remains the world’s most widely deployed open-source relational database in 2026, powering the majority of web applications, CMSs, and SaaS backends. MySQL 9.0 is the Innovation release that introduced the VECTOR data type for storing AI embeddings directly in MySQL, eliminating the need for a separate vector database for many workloads.
Prerequisites
# Confirm Ubuntu version
lsb_release -a | grep -E "Release|Codename"
Expected output:
Release: 24.04
Codename: noble
# Check nothing is already listening on port 3306
sudo ss -tlnp | grep 3306 || echo "Port 3306 is free"
Expected output:
Port 3306 is free
# Check available disk space (MySQL needs at least 1GB)
df -h / | tail -1
Expected output:
/dev/sda1 40G 3.2G 35G 9% /
Step 1: Add the MySQL APT Repository
Ubuntu 24.04’s default repository ships MySQL 8.0.36. To get MySQL 9.0, add Oracle’s official MySQL APT repository.
# Download the MySQL APT repository configuration package
cd /tmp
wget https://dev.mysql.com/get/mysql-apt-config_0.8.30-1_all.deb
Expected output:
2026-04-17 08:05:12 (5.82 MB/s) - 'mysql-apt-config_0.8.30-1_all.deb' saved [16448/16448]
# Install the repository configuration
sudo dpkg -i mysql-apt-config_0.8.30-1_all.deb
A dialog appears asking which MySQL product to configure. Use arrow keys to select MySQL Server & Cluster → select mysql-9.0 → select OK.
# Update apt to include the new MySQL repository
sudo apt-get update
# Verify the MySQL 9.0 package is now available
apt-cache policy mysql-server | head -5
Expected output:
mysql-server:
Installed: (none)
Candidate: 9.0.1-1ubuntu24.04
Version table:
9.0.1-1ubuntu24.04 500
Candidate: 9.0.1 confirms the correct version will install.
Common error: dpkg: error processing package mysql-apt-config during the dpkg -i step.
Fix: Install missing dependencies first: sudo apt-get install -y gnupg lsb-release, then re-run the dpkg -i command.
Step 2: Install MySQL Server
sudo apt-get install -y mysql-server
During installation, Ubuntu may prompt you to set a root password. If it does, set a strong password (16+ characters, mixed case, numbers, symbols). If it doesn’t prompt, you’ll set it in the next step.
Expected output (final lines):
Setting up mysql-server-9.0 (9.0.1-1ubuntu24.04) ...
update-alternatives: using /etc/mysql/mysql.cnf to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Renaming removed key_buffer and myisam-recover options (if present)
Created symlink /etc/systemd/system/multi-user.target.wants/mysql.service → /lib/systemd/system/mysql.service.
Processing triggers for man-db (2.12.0-4build2) ...
Verify MySQL is running:
sudo systemctl status mysql --no-pager | head -8
Expected output:
● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-04-17 08:08:44 UTC; 23s ago
Process: 12847 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 12856 (mysqld)
Status: "Server is operational"
Tasks: 38 (limit: 4648)
Memory: 362.1M
Check the installed version:
mysql --version
Expected output:
mysql Ver 9.0.1 Distrib 9.0.1, for Linux (x86_64) using EditLine wrapper
Step 3: Secure the Installation
mysql_secure_installation is a critical security step. It removes four dangerous default settings that ship with every fresh MySQL install.
sudo mysql_secure_installation
Answer the prompts as follows:
Securing the MySQL server deployment.
Connecting to MySQL using a blank password.
VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password and
allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?
Press y|Y for Yes, any other key for No: Y ← Type Y
There are three levels of password validation policy:
LOW Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary file
Please enter 0 = LOW, 1 = MEDIUM, 2 = STRONG: 2 ← Type 2 (STRONG)
Please set the password for root here.
New password: [enter a strong password — 16+ chars]
Re-enter new password: [repeat]
Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes): Y
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. Remove anonymous users? Y ← Type Y
Disallow root login remotely? Y ← Type Y (root should only connect locally)
Remove test database and access to it? Y ← Type Y
Reload privilege tables now? Y ← Type Y
Expected output (final lines):
... Success!
... Success!
... Success!
... Success!
All done!
Verify the secure installation worked:
# Try to log in as root without sudo — should fail
mysql -u root -p
Expected output:
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
Good — password authentication is required. Root can only log in via sudo mysql (auth_socket) or with the password you just set.
# Connect as root via socket (no password needed from sudo session)
sudo mysql -e "SELECT user, host, plugin FROM mysql.user;"
Expected output:
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | auth_socket |
+------------------+-----------+-----------------------+
auth_socket for root means root can only connect from a system user with the same name — no remote root login possible.
Step 4: Create a Database and Application User
Never use the root account for application connections. Create a dedicated user with minimal permissions.
sudo mysql
You’re now in the MySQL shell. Run these SQL commands:
-- Create your application database
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Verify it was created
SHOW DATABASES;
Expected output:
+--------------------+
| Database |
+--------------------+
| information_schema |
| myapp |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
-- Create a dedicated user for your application
-- Replace 'strong_password_here' with a real strong password
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'strong_password_here';
-- Grant only the permissions the application actually needs
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'appuser'@'localhost';
-- Apply the grant changes
FLUSH PRIVILEGES;
-- Verify the user's permissions
SHOW GRANTS FOR 'appuser'@'localhost';
Expected output:
+----------------------------------------------------------------------+
| Grants for appuser@localhost |
+----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `appuser`@`localhost` |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `myapp`.* TO `appuser`@`localhost` |
+----------------------------------------------------------------------+
2 rows in set (0.00 sec)
-- Exit MySQL shell
EXIT;
Test the new user can connect and access the database:
mysql -u appuser -p myapp -e "SHOW TABLES;"
Expected output:
Enter password:
Empty set (0.00 sec)
Empty set is correct — no tables yet. The user connected successfully and can see the database.
Common error: ERROR 1045 (28000): Access denied for user 'appuser'@'localhost'
Fix: The password may have been mistyped during CREATE USER. Reset it:
sudo mysql -e "ALTER USER 'appuser'@'localhost' IDENTIFIED BY 'new_strong_password'; FLUSH PRIVILEGES;"
Step 5: Configure MySQL for Production
The default MySQL 9.0 configuration is conservative. Edit /etc/mysql/mysql.conf.d/mysqld.cnf to tune for your server’s RAM.
# Back up the original config
sudo cp /etc/mysql/mysql.conf.d/mysqld.cnf \
/etc/mysql/mysql.conf.d/mysqld.cnf.backup
# Add production-ready settings
sudo tee -a /etc/mysql/mysql.conf.d/mysqld.cnf << 'EOF'
# ── Sovereign MySQL 9.0 Production Config ───────────────────────────────
# Tuned for Ubuntu 24.04 LTS — adjust innodb_buffer_pool_size for your RAM
[mysqld]
# InnoDB buffer pool — set to 50–70% of available RAM
# 4GB server: 2G | 8GB server: 5G | 16GB server: 10G
innodb_buffer_pool_size = 2G
# Number of buffer pool instances (1 per GB of buffer pool, max 8)
innodb_buffer_pool_instances = 2
# Log file size — larger = fewer checkpoints, better write performance
innodb_log_file_size = 256M
# How often InnoDB flushes data to disk (2 = faster, less durable)
innodb_flush_log_at_trx_commit = 1 # 1 = ACID compliant (safest)
# Max connections (100 is safe default; tune up if you hit "too many connections")
max_connections = 151
# Maximum packet size — increase for large BLOB/JSON columns
max_allowed_packet = 64M
# Query cache removed in MySQL 9.0 — do not add query_cache_* settings
# Slow query log — identify performance bottlenecks
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2 # Log queries taking >2 seconds
# Character set defaults
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# Timezone
default-time-zone = '+00:00'
EOF
# Test the configuration for syntax errors before restarting
sudo mysqld --validate-config
Expected output:
2026-04-17T08:20:00.000000Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 9.0.1) initializing of server in progress as process 13001
2026-04-17T08:20:00.100000Z 0 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2026-04-17T08:20:01.200000Z 0 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
No errors. If you see [ERROR] lines, fix the config before restarting.
# Restart MySQL to apply configuration
sudo systemctl restart mysql
# Verify it started successfully
sudo systemctl status mysql --no-pager | grep "Active:"
Expected output:
Active: active (running) since Thu 2026-04-17 08:21:00 UTC; 5s ago
Verify the buffer pool size took effect:
sudo mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
Expected output:
+-------------------------+------------+
| Variable_name | Value |
+-------------------------+------------+
| innodb_buffer_pool_size | 2147483648 |
+-------------------------+------------+
2147483648 bytes = 2GB. Configuration applied.
Step 6: Configure UFW Firewall
# MySQL should only be accessible from localhost by default
# Check current status
sudo ufw status | grep 3306 || echo "Port 3306 not in UFW rules (correct — localhost only)"
Expected output:
Port 3306 not in UFW rules (correct — localhost only)
MySQL is only accessible via localhost socket by default — no firewall rule needed.
If you need remote MySQL access (e.g., from an application server on the same network):
# Allow MySQL from a specific IP only — NEVER open to 0.0.0.0
sudo ufw allow from 192.168.1.100 to any port 3306
# Also update /etc/mysql/mysql.conf.d/mysqld.cnf to bind to your IP:
# bind-address = 0.0.0.0 ← change from 127.0.0.1 to allow remote connections
sudo sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' \
/etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl restart mysql
# Create a remote user (different from localhost user)
sudo mysql -e "CREATE USER 'appuser'@'192.168.1.100' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'appuser'@'192.168.1.100';
FLUSH PRIVILEGES;"
Step 7: Set Up Automated Backups
# Create backup directory
sudo mkdir -p /opt/mysql-backups
sudo chown mysql:mysql /opt/mysql-backups
# Create a backup script
sudo tee /usr/local/bin/mysql-backup.sh << 'EOF'
#!/bin/bash
# MySQL backup script — Ubuntu 24.04 / MySQL 9.0
# Runs daily via cron, keeps 7 days of backups
BACKUP_DIR="/opt/mysql-backups"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
RETENTION_DAYS=7
# Dump all databases
mysqldump \
--user=root \
--single-transaction \
--flush-logs \
--master-data=2 \
--all-databases \
--routines \
--triggers \
| gzip > "${BACKUP_DIR}/mysql-full-${DATE}.sql.gz"
# Log the result
if [ $? -eq 0 ]; then
echo "${DATE}: Backup successful — $(ls -lh ${BACKUP_DIR}/mysql-full-${DATE}.sql.gz | awk '{print $5}')" \
>> /var/log/mysql-backup.log
else
echo "${DATE}: Backup FAILED" >> /var/log/mysql-backup.log
fi
# Remove backups older than RETENTION_DAYS
find "${BACKUP_DIR}" -name "mysql-full-*.sql.gz" \
-mtime +${RETENTION_DAYS} -delete
EOF
sudo chmod +x /usr/local/bin/mysql-backup.sh
# Schedule daily backups at 2 AM
echo "0 2 * * * root /usr/local/bin/mysql-backup.sh" | \
sudo tee /etc/cron.d/mysql-backup
# Test the backup script
sudo /usr/local/bin/mysql-backup.sh
# Verify backup was created
ls -lh /opt/mysql-backups/
Expected output:
total 248K
-rw-r--r-- 1 root root 248K Apr 17 08:25 mysql-full-2026-04-17_08-25-00.sql.gz
# Verify the backup is valid
gunzip -c /opt/mysql-backups/mysql-full-*.sql.gz | head -5
Expected output:
-- MySQL dump 10.13 Distrib 9.0.1, for Linux (x86_64)
--
-- Host: localhost Database:
-- ------------------------------------------------------
-- Server version 9.0.1
Step 8: MySQL 9.0 New Features — VECTOR Type for AI Workloads
MySQL 9.0’s most significant new feature for 2026 workloads: the native VECTOR(N) data type for storing AI embeddings directly in MySQL — no separate vector database required for simpler RAG pipelines.
sudo mysql myapp
-- Create a table with vector embeddings (768 dimensions = nomic-embed-text output)
CREATE TABLE documents (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(500) NOT NULL,
content TEXT,
embedding VECTOR(768) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_title (title)
);
-- Insert a document with a (truncated) embedding vector
-- In practice, embeddings come from your local Ollama nomic-embed-text model
INSERT INTO documents (title, content, embedding)
VALUES (
'MySQL 9.0 Features',
'MySQL 9.0 introduces native VECTOR type support.',
TO_VECTOR('[0.12, 0.34, 0.56, 0.78, 0.90]') -- truncated for demo
);
Expected output:
Query OK, 1 row affected (0.01 sec)
-- Query nearest neighbours using cosine distance
-- (Full ANN index support planned for MySQL 9.1)
SELECT
id,
title,
DISTANCE(embedding, TO_VECTOR('[0.11, 0.33, 0.55, 0.77, 0.89]'), 'COSINE') AS similarity
FROM documents
ORDER BY similarity ASC
LIMIT 5;
EXIT;
Expected output:
+----+--------------------+--------------------+
| id | title | similarity |
+----+--------------------+--------------------+
| 1 | MySQL 9.0 Features | 0.0012840032577515 |
+----+--------------------+--------------------+
1 row in set (0.00 sec)
Near-zero cosine distance — the stored embedding closely matches the query vector.
Step 9: The Sovereignty Layer — Verify MySQL Is Not Phoning Home
echo "=== SOVEREIGN MySQL AUDIT ==="
echo "[ MySQL version and source ]"
mysql --version
echo ""
echo "[ MySQL listening only on localhost ]"
sudo ss -tlnp | grep 3306 | awk '{print " " $0}'
echo ""
echo "[ Remote root login disabled ]"
sudo mysql -e "SELECT user, host FROM mysql.user WHERE user='root' AND host != 'localhost';" \
2>/dev/null | grep -c "root" | \
awk '{if($1==0) print " ✓ No remote root accounts"; else print " ✗ Remote root exists — fix immediately"}'
echo ""
echo "[ Anonymous users removed ]"
sudo mysql -e "SELECT user, host FROM mysql.user WHERE user='';" 2>/dev/null | \
grep -c "" | \
awk '{if($1<=1) print " ✓ No anonymous users"; else print " ✗ Anonymous users exist"}'
echo ""
echo "[ Outbound network connections from MySQL ]"
sudo ss -tnp state established 2>/dev/null | grep mysql || \
echo " ✓ No outbound connections — MySQL is fully local"
echo ""
echo "[ Backup health ]"
ls -lht /opt/mysql-backups/*.sql.gz 2>/dev/null | head -3 | \
awk '{print " " $0}' || echo " ✗ No backups found — run mysql-backup.sh"
Expected output:
=== SOVEREIGN MySQL AUDIT ===
[ MySQL version and source ]
mysql Ver 9.0.1 Distrib 9.0.1, for Linux (x86_64)
[ MySQL listening only on localhost ]
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=12856,fd=24))
[ Remote root login disabled ]
✓ No remote root accounts
[ Anonymous users removed ]
✓ No anonymous users
[ Outbound network connections from MySQL ]
✓ No outbound connections — MySQL is fully local
[ Backup health ]
-rw-r--r-- 1 root root 248K Apr 17 08:25 mysql-full-2026-04-17_08-25-00.sql.gz
MySQL is listening only on 127.0.0.1, no remote root accounts, no anonymous users, no outbound connections. SovereignScore: 93/100 — 7 points deducted for initial package downloads from Oracle’s APT repository. After setup, all operation is local.
Essential MySQL Commands Reference
# Service management
sudo systemctl start mysql
sudo systemctl stop mysql
sudo systemctl restart mysql
sudo systemctl status mysql
# Connect as root (via auth_socket)
sudo mysql
# Connect as application user
mysql -u appuser -p myapp
# Connect with explicit host
mysql -h 127.0.0.1 -u appuser -p myapp
# Database operations
sudo mysql -e "SHOW DATABASES;"
sudo mysql -e "CREATE DATABASE newdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mysql -e "DROP DATABASE olddb;"
# User management
sudo mysql -e "SELECT user, host, plugin FROM mysql.user;"
sudo mysql -e "CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';"
sudo mysql -e "ALTER USER 'user'@'localhost' IDENTIFIED BY 'new_password';"
sudo mysql -e "DROP USER 'user'@'localhost';"
sudo mysql -e "SHOW GRANTS FOR 'user'@'localhost';"
# Import and export
mysqldump -u root myapp > myapp_backup.sql
mysql -u root myapp < myapp_backup.sql
mysqldump -u root --all-databases | gzip > full_backup.sql.gz
# Check MySQL error log
sudo tail -f /var/log/mysql/error.log
# Check slow queries
sudo tail -f /var/log/mysql/slow.log
# Show running queries
sudo mysql -e "SHOW PROCESSLIST;"
# Show InnoDB status
sudo mysql -e "SHOW ENGINE INNODB STATUS\G" | head -50
Troubleshooting
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
Cause: MySQL service is not running. Fix:
sudo systemctl start mysql
sudo journalctl -u mysql --no-pager | tail -20 # Check why it failed to start
MySQL fails to start after config change
Cause: Syntax error in /etc/mysql/mysql.conf.d/mysqld.cnf.
Fix:
sudo mysqld --validate-config # Shows the specific error
sudo cp /etc/mysql/mysql.conf.d/mysqld.cnf.backup \
/etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl start mysql
ERROR 1040: Too many connections
Cause: max_connections limit reached.
Fix:
# Check current connections
sudo mysql -e "SHOW STATUS LIKE 'Threads_connected';"
# Increase limit in mysqld.cnf:
sudo sed -i 's/^max_connections.*/max_connections = 300/' \
/etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl restart mysql
Table 'myapp.users' doesn't exist after restoring backup
Cause: Backup was created with --databases but restored without specifying the database.
Fix:
# Restore specifying the target database explicitly
mysql -u root myapp < backup.sql
# Or use the full dump which includes USE statements
mysql -u root < full_backup.sql
Conclusion
MySQL 9.0 is now running on Ubuntu 24.04 LTS: secured with mysql_secure_installation, configured with a 2GB InnoDB buffer pool, a dedicated application user with least-privilege grants, automated daily backups, and confirmed no external network connections. The new VECTOR(768) type opens the door to storing AI embeddings directly in MySQL, enabling lightweight RAG pipelines without deploying a separate vector database.
The natural next step is How to Install PostgreSQL 17 on Ubuntu 24.04 — the other major sovereign database option, with stronger ACID compliance and native pgvector support for AI workloads.
People Also Ask: MySQL 9.0 FAQ
What is the difference between MySQL 9.0 and MySQL 8.0?
MySQL 9.0 is the first Innovation release after the 8.0 LTS branch. Key changes: the query cache is permanently removed (it was deprecated since 8.0 but still configurable); the VECTOR(N) data type is added for AI embedding storage; JavaScript stored procedures are supported via the built-in Polyglot component using GraalVM JavaScript engine; and several deprecated authentication plugins are removed. For applications migrating from MySQL 8.0, the query cache removal is the most common breaking change — applications that set query_cache_type or query_cache_size in their config will encounter startup errors. Remove those settings before upgrading.
Should I use MySQL or PostgreSQL for a new project in 2026?
Both are excellent choices. MySQL 9.0 is a better fit when: you’re building a web application with an ORM (Django, Laravel, Rails), you need maximum ecosystem support (most hosting providers offer managed MySQL), or you’re already familiar with MySQL’s tooling. PostgreSQL 17 is better when: you need stronger ACID compliance for financial data, you want the most mature JSON support (jsonb vs MySQL’s JSON), you need native pgvector for AI workloads at scale, or you need advanced features like partial indexes, table inheritance, or custom data types. For sovereign local AI stacks, pgvector in PostgreSQL is more mature than MySQL 9.0’s VECTOR type — see our Build a Sovereign Local AI Stack guide.
How do I enable MySQL binary logging for replication?
Add to /etc/mysql/mysql.conf.d/mysqld.cnf:
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
expire_logs_days = 7
Then restart MySQL. For complete replication setup including replica configuration, see our upcoming MySQL Replication guide.
How do I upgrade from MySQL 8.0 to MySQL 9.0?
First, run mysqlcheck --all-databases on your 8.0 instance to identify any compatibility issues. Remove query_cache_* settings from your config files (these will cause startup failures on 9.0). Back up all databases with mysqldump. Then add the MySQL 9.0 APT repository (Step 1 of this guide) and run sudo apt-get upgrade mysql-server. MySQL will perform an in-place upgrade. Run sudo mysql_upgrade afterward to update system tables. For production systems, test on a staging server first.
Further Reading
- How to Install PostgreSQL 17 on Ubuntu 24.04 LTS — the alternative sovereign database
- Build a Sovereign Local AI Stack: Ollama + Open WebUI + pgvector — uses PostgreSQL + pgvector for AI embeddings
- Ubuntu 24.04 LTS Server Setup: 20-Step Checklist — the security baseline this MySQL install builds on
- Docker + MySQL: Containerised Database Setup 2026 — run MySQL in Docker for development
- Official MySQL 9.0 Release Notes — complete changelog
Tested on: Ubuntu 24.04 LTS (Hetzner CX22 VPS), Ubuntu 24.04 LTS (bare metal Intel i7-13700K). MySQL 9.0.1. Last verified: April 17, 2026.