{"slug":"databases-mariadb","title":"MariaDB Managed Database","description":"MariaDB is a community-developed, commercially supported fork of MySQL. DanubeData offers fully managed MariaDB databases with automatic backups, high availability, and easy scaling.","section":"Features","url":"https://docs.danubedata.ro/databases-mariadb","markdown_url":"https://docs.danubedata.ro/databases-mariadb.md","breadcrumbs":[{"title":"Features","slug":null},{"title":"Databases","slug":"databases-overview"},{"title":"MariaDB","slug":"databases-mariadb"}],"headings":[{"level":1,"title":"MariaDB Managed Database","id":"mariadb-managed-database"},{"level":2,"title":"Overview","id":"overview"},{"level":3,"title":"Why Choose MariaDB?","id":"why-choose-mariadb"},{"level":2,"title":"Supported Versions","id":"supported-versions"},{"level":2,"title":"Creating a MariaDB Database","id":"creating-a-mariadb-database"},{"level":3,"title":"Via Dashboard","id":"via-dashboard"},{"level":3,"title":"Configuration Options","id":"configuration-options"},{"level":4,"title":"Resource Profiles","id":"resource-profiles"},{"level":4,"title":"High Availability (Replicas)","id":"high-availability-replicas"},{"level":2,"title":"Connecting to MariaDB","id":"connecting-to-mariadb"},{"level":3,"title":"Connection Details","id":"connection-details"},{"level":3,"title":"Connection String","id":"connection-string"},{"level":3,"title":"SSL/TLS Connection","id":"ssltls-connection"},{"level":3,"title":"Connection from Application","id":"connection-from-application"},{"level":4,"title":"PHP (PDO)","id":"php-pdo"},{"level":4,"title":"Python (PyMySQL)","id":"python-pymysql"},{"level":4,"title":"Node.js (mysql2)","id":"nodejs-mysql2"},{"level":2,"title":"Database Management","id":"database-management"},{"level":3,"title":"Creating Additional Databases","id":"creating-additional-databases"},{"level":3,"title":"Creating Users","id":"creating-users"},{"level":3,"title":"User Permissions","id":"user-permissions"},{"level":2,"title":"MariaDB-Specific Features","id":"mariadb-specific-features"},{"level":3,"title":"Storage Engines","id":"storage-engines"},{"level":4,"title":"InnoDB (Default)","id":"innodb-default"},{"level":4,"title":"Aria (Crash-safe MyISAM replacement)","id":"aria-crash-safe-myisam-replacement"},{"level":4,"title":"ColumnStore (Analytics)","id":"columnstore-analytics"},{"level":3,"title":"Sequences","id":"sequences"},{"level":3,"title":"JSON Functions","id":"json-functions"},{"level":3,"title":"Virtual Columns","id":"virtual-columns"},{"level":2,"title":"Performance Optimization","id":"performance-optimization"},{"level":3,"title":"Query Cache","id":"query-cache"},{"level":3,"title":"Indexes","id":"indexes"},{"level":3,"title":"Query Optimization","id":"query-optimization"},{"level":3,"title":"Connection Pooling","id":"connection-pooling"},{"level":2,"title":"Monitoring and Maintenance","id":"monitoring-and-maintenance"},{"level":3,"title":"Performance Monitoring","id":"performance-monitoring"},{"level":3,"title":"Slow Query Log","id":"slow-query-log"},{"level":3,"title":"Database Size","id":"database-size"},{"level":2,"title":"Backups and Recovery","id":"backups-and-recovery"},{"level":3,"title":"Automatic Backups","id":"automatic-backups"},{"level":3,"title":"Manual Backups","id":"manual-backups"},{"level":3,"title":"Restoring from Backup","id":"restoring-from-backup"},{"level":3,"title":"Exporting Data","id":"exporting-data"},{"level":2,"title":"Migration","id":"migration"},{"level":3,"title":"Migrating from MySQL to MariaDB","id":"migrating-from-mysql-to-mariadb"},{"level":3,"title":"Best Practices for Migration","id":"best-practices-for-migration"},{"level":2,"title":"Security Best Practices","id":"security-best-practices"},{"level":3,"title":"User Security","id":"user-security"},{"level":3,"title":"SSL/TLS Connections","id":"ssltls-connections"},{"level":3,"title":"Regular Security Updates","id":"regular-security-updates"},{"level":2,"title":"Troubleshooting","id":"troubleshooting"},{"level":3,"title":"Connection Issues","id":"connection-issues"},{"level":3,"title":"Performance Issues","id":"performance-issues"},{"level":3,"title":"Storage Full","id":"storage-full"},{"level":3,"title":"Too Many Connections","id":"too-many-connections"},{"level":2,"title":"Related Documentation","id":"related-documentation"}],"format":"markdown","word_count":360,"content":"# MariaDB Managed Database\n\nMariaDB is a community-developed, commercially supported fork of MySQL. DanubeData offers fully managed MariaDB databases with automatic backups, high availability, and easy scaling.\n\n## Overview\n\nMariaDB provides enhanced performance, improved replication, and additional storage engines compared to MySQL. It's fully compatible with MySQL, making migration straightforward.\n\n### Why Choose MariaDB?\n\n- **MySQL Compatibility**: Drop-in replacement for MySQL with better performance\n- **Open Source**: Truly open-source with no vendor lock-in\n- **Advanced Features**: Improved optimizer, parallel replication, and more storage engines\n- **Active Development**: Regular updates and security patches\n- **Enterprise Features**: Features like Galera Cluster, Thread Pool, and more\n\n## Supported Versions\n\nDanubeData supports the following MariaDB versions:\n\n- **MariaDB 11.6** (Latest - Recommended)\n- **MariaDB 11.4** (LTS)\n- **MariaDB 10.11** (LTS)\n\n> **Recommendation**: Use MariaDB 11.6 for new databases. It offers the best performance and latest features.\n\n## Creating a MariaDB Database\n\n### Via Dashboard\n\n1. Navigate to **Databases** in the main menu\n2. Click **Create Database**\n3. Select **MariaDB** as the engine\n4. Choose your preferred version\n5. Select a resource profile (see below)\n6. Choose a data center location\n7. Configure optional settings:\n   - Database name\n   - User credentials\n   - Enable replicas\n   - Backup schedule\n8. Click **Create Database**\n\nYour database will be provisioned within 3-5 minutes.\n\n### Configuration Options\n\n#### Resource Profiles\n\nMariaDB databases are available in multiple resource profiles:\n\n| Profile | vCPU | RAM | Storage | Price/Month |\n|---------|------|-----|---------|-------------|\n| **Small** | 2 | 4 GB | 50 GB | €19.99 |\n| **Medium** | 4 | 8 GB | 100 GB | €39.99 |\n| **Large** | 8 | 16 GB | 200 GB | €79.99 |\n\n#### High Availability (Replicas)\n\nEnable high availability by creating read replicas:\n\n- **Primary-Replica Setup**: Automatic failover\n- **Asynchronous Replication**: Low-latency replication\n- **Read Scaling**: Distribute read queries across replicas\n- **Automatic Promotion**: Replica promotion on primary failure\n\n## Connecting to MariaDB\n\n### Connection Details\n\nAfter creation, you'll receive connection details:\n\n```\nHost: db-mariadb-123456.danubedata.ro\nPort: 3306\nDatabase: danubedata\nUser: admin\nPassword: [secure_password]\n```\n\n### Connection String\n\n```bash\nmysql -h db-mariadb-123456.danubedata.ro -P 3306 -u admin -p danubedata\n```\n\n### SSL/TLS Connection\n\nAll connections support SSL/TLS encryption for security.\n\n**Modern MySQL/MariaDB clients (5.7.11+)**:\n```bash\nmysql -h db-mariadb-123456.danubedata.ro \\\n  -P 3306 \\\n  -u admin \\\n  -p \\\n  --ssl-mode=REQUIRED \\\n  --ssl-verify-server-cert=OFF \\\n  danubedata\n```\n\n**Older MySQL/MariaDB clients (pre-5.7.11)**:\n```bash\nmysql -h db-mariadb-123456.danubedata.ro \\\n  -P 3306 \\\n  -u admin \\\n  -p \\\n  --ssl \\\n  --ssl-verify-server-cert=0 \\\n  danubedata\n```\n\n**Check your client version**:\n```bash\nmysql --version\n```\n\n### Connection from Application\n\n#### PHP (PDO)\n\n```php\n<?php\n$host = 'db-mariadb-123456.danubedata.ro';\n$port = 3306;\n$dbname = 'danubedata';\n$user = 'admin';\n$password = 'your_password';\n\n$dsn = \"mysql:host=$host;port=$port;dbname=$dbname;charset=utf8mb4\";\n\n$options = [\n    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,\n    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,\n    PDO::ATTR_EMULATE_PREPARES   => false,\n    PDO::MYSQL_ATTR_SSL_CA       => '/path/to/ca-certificate.crt',\n    PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,\n];\n\ntry {\n    $pdo = new PDO($dsn, $user, $password, $options);\n} catch (\\PDOException $e) {\n    throw new \\PDOException($e->getMessage(), (int)$e->getCode());\n}\n```\n\n#### Python (PyMySQL)\n\n```python\nimport pymysql\n\nconnection = pymysql.connect(\n    host='db-mariadb-123456.danubedata.ro',\n    port=3306,\n    user='admin',\n    password='your_password',\n    database='danubedata',\n    charset='utf8mb4',\n    ssl={'ca': '/path/to/ca-certificate.crt'},\n    ssl_verify_cert=True,\n    ssl_verify_identity=True\n)\n```\n\n#### Node.js (mysql2)\n\n```javascript\nconst mysql = require('mysql2');\n\nconst connection = mysql.createConnection({\n  host: 'db-mariadb-123456.danubedata.ro',\n  port: 3306,\n  user: 'admin',\n  password: 'your_password',\n  database: 'danubedata',\n  ssl: {\n    ca: fs.readFileSync('/path/to/ca-certificate.crt')\n  }\n});\n```\n\n## Database Management\n\n### Creating Additional Databases\n\nYou can create multiple databases within a single MariaDB instance:\n\n```sql\nCREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n```\n\n### Creating Users\n\nCreate additional database users with specific permissions:\n\n```sql\n-- Create user\nCREATE USER 'myapp_user'@'%' IDENTIFIED BY 'secure_password';\n\n-- Grant permissions\nGRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'myapp_user'@'%';\n\n-- Flush privileges\nFLUSH PRIVILEGES;\n```\n\n### User Permissions\n\nGrant appropriate permissions based on requirements:\n\n```sql\n-- Read-only user\nGRANT SELECT ON myapp.* TO 'readonly_user'@'%';\n\n-- Read-write user\nGRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'readwrite_user'@'%';\n\n-- Full access (including schema changes)\nGRANT ALL PRIVILEGES ON myapp.* TO 'admin_user'@'%';\n\n-- Grant specific permissions\nGRANT SELECT, INSERT, UPDATE ON myapp.users TO 'app_user'@'%';\n```\n\n## MariaDB-Specific Features\n\n### Storage Engines\n\nMariaDB supports multiple storage engines:\n\n#### InnoDB (Default)\n\n```sql\nCREATE TABLE users (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    name VARCHAR(255),\n    email VARCHAR(255) UNIQUE\n) ENGINE=InnoDB;\n```\n\n#### Aria (Crash-safe MyISAM replacement)\n\n```sql\nCREATE TABLE logs (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    message TEXT,\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n) ENGINE=Aria;\n```\n\n#### ColumnStore (Analytics)\n\n```sql\n-- Create a columnstore table for analytics\nCREATE TABLE analytics_events (\n    event_id BIGINT,\n    user_id INT,\n    event_type VARCHAR(50),\n    event_data JSON,\n    created_at TIMESTAMP\n) ENGINE=ColumnStore;\n```\n\n### Sequences\n\nMariaDB has native sequence support:\n\n```sql\n-- Create a sequence\nCREATE SEQUENCE user_id_seq START WITH 1000 INCREMENT BY 1;\n\n-- Use in INSERT\nINSERT INTO users (id, name) VALUES (NEXT VALUE FOR user_id_seq, 'John Doe');\n\n-- Get current value\nSELECT LASTVAL(user_id_seq);\n```\n\n### JSON Functions\n\nMariaDB provides powerful JSON functions:\n\n```sql\n-- Create table with JSON column\nCREATE TABLE products (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    name VARCHAR(255),\n    attributes JSON\n);\n\n-- Insert JSON data\nINSERT INTO products (name, attributes) \nVALUES ('Laptop', '{\"brand\": \"Dell\", \"cpu\": \"Intel i7\", \"ram\": 16}');\n\n-- Query JSON data\nSELECT name, JSON_VALUE(attributes, '$.brand') as brand\nFROM products\nWHERE JSON_VALUE(attributes, '$.ram') > 8;\n\n-- Update JSON data\nUPDATE products\nSET attributes = JSON_SET(attributes, '$.ram', 32)\nWHERE id = 1;\n```\n\n### Virtual Columns\n\nMariaDB supports virtual (computed) columns:\n\n```sql\nCREATE TABLE orders (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    quantity INT,\n    price DECIMAL(10, 2),\n    total DECIMAL(10, 2) AS (quantity * price) VIRTUAL,\n    INDEX (total)\n);\n```\n\n## Performance Optimization\n\n### Query Cache\n\nMariaDB includes query cache (deprecated in MySQL 8.0):\n\n```sql\n-- Enable query cache (configured by default)\nSET GLOBAL query_cache_type = 1;\nSET GLOBAL query_cache_size = 268435456; -- 256 MB\n\n-- Check query cache status\nSHOW STATUS LIKE 'Qcache%';\n```\n\n> **Note**: Query cache is most effective for read-heavy workloads with repetitive queries.\n\n### Indexes\n\nCreate appropriate indexes for your queries:\n\n```sql\n-- Single column index\nCREATE INDEX idx_email ON users(email);\n\n-- Composite index\nCREATE INDEX idx_name_email ON users(name, email);\n\n-- Unique index\nCREATE UNIQUE INDEX idx_unique_email ON users(email);\n\n-- Full-text index\nCREATE FULLTEXT INDEX idx_fulltext_content ON articles(content);\n\n-- Analyze index usage\nSHOW INDEX FROM users;\n```\n\n### Query Optimization\n\nUse `EXPLAIN` to analyze query performance:\n\n```sql\nEXPLAIN SELECT * FROM users WHERE email = 'user@example.com';\n```\n\n### Connection Pooling\n\nImplement connection pooling in your application:\n\n- Reuse database connections\n- Reduce connection overhead\n- Improve application performance\n- Handle connection failures gracefully\n\n## Monitoring and Maintenance\n\n### Performance Monitoring\n\nMonitor database performance via the dashboard:\n\n- **CPU Usage**: Track CPU utilization\n- **Memory Usage**: Monitor RAM consumption\n- **Disk I/O**: Watch read/write operations\n- **Connections**: Active and total connections\n- **Query Performance**: Slow query log\n\n### Slow Query Log\n\nIdentify slow queries for optimization:\n\n```sql\n-- Enable slow query log\nSET GLOBAL slow_query_log = 1;\nSET GLOBAL long_query_time = 2; -- Queries taking > 2 seconds\n\n-- View slow queries in dashboard or via CLI\nSELECT * FROM mysql.slow_log ORDER BY query_time DESC LIMIT 10;\n```\n\n### Database Size\n\nCheck database and table sizes:\n\n```sql\n-- Database size\nSELECT \n    table_schema AS 'Database',\n    ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)'\nFROM information_schema.tables\nGROUP BY table_schema;\n\n-- Table sizes\nSELECT \n    table_name AS 'Table',\n    ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'\nFROM information_schema.tables\nWHERE table_schema = 'myapp'\nORDER BY (data_length + index_length) DESC;\n```\n\n## Backups and Recovery\n\n### Automatic Backups\n\nAll MariaDB databases include automatic daily backups:\n\n- **Daily Backups**: Taken during off-peak hours\n- **Retention**: 3 days\n- **Point-in-Time Recovery**: Restore to any point within retention period\n- **Backup Storage**: Stored within the Falkenstein (fsn1) datacenter\n\n### Manual Backups\n\nCreate on-demand backups:\n\n1. Navigate to your database\n2. Click **Backups** tab\n3. Click **Create Backup**\n4. Provide a descriptive name\n5. Backup will be created within minutes\n\n### Restoring from Backup\n\nRestore your database from a backup:\n\n1. Go to **Backups** tab\n2. Select the backup to restore\n3. Click **Restore**\n4. Choose restoration method:\n   - **Restore to existing database**: Overwrites current data\n   - **Restore to new database**: Creates a new database instance\n\n> **Warning**: Restoring to an existing database will overwrite all current data. This action cannot be undone.\n\n### Exporting Data\n\nExport your database using `mysqldump`:\n\n```bash\n# Export entire database\nmysqldump -h db-mariadb-123456.danubedata.ro \\\n  -u admin -p \\\n  --ssl-mode=REQUIRED \\\n  --single-transaction \\\n  --quick \\\n  danubedata > backup.sql\n\n# Export specific tables\nmysqldump -h db-mariadb-123456.danubedata.ro \\\n  -u admin -p \\\n  --ssl-mode=REQUIRED \\\n  danubedata users orders > tables_backup.sql\n\n# Export with compression\nmysqldump -h db-mariadb-123456.danubedata.ro \\\n  -u admin -p \\\n  --ssl-mode=REQUIRED \\\n  danubedata | gzip > backup.sql.gz\n```\n\n## Migration\n\n### Migrating from MySQL to MariaDB\n\nMariaDB is compatible with MySQL, making migration straightforward:\n\n1. **Export from MySQL**:\n   ```bash\n   mysqldump -h old-mysql-server -u root -p mydatabase > mysql_dump.sql\n   ```\n\n2. **Import to MariaDB**:\n   ```bash\n   mysql -h db-mariadb-123456.danubedata.ro -u admin -p danubedata < mysql_dump.sql\n   ```\n\n3. **Verify Data**:\n   ```sql\n   -- Check table count\n   SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'danubedata';\n   \n   -- Check row counts\n   SELECT table_name, table_rows \n   FROM information_schema.tables \n   WHERE table_schema = 'danubedata';\n   ```\n\n### Best Practices for Migration\n\n- **Test First**: Migrate to a test database first\n- **Check Compatibility**: Verify all features work in MariaDB\n- **Update Connection Strings**: Update application configuration\n- **Monitor Performance**: Watch for performance differences\n- **Backup Before Migration**: Always backup before starting\n\n## Security Best Practices\n\n### User Security\n\n```sql\n-- Use strong passwords\nCREATE USER 'myuser'@'%' IDENTIFIED BY 'Very$trong@P@ssw0rd!2024';\n\n-- Limit user access by IP\nCREATE USER 'admin'@'203.0.113.0/24' IDENTIFIED BY 'password';\n\n-- Remove anonymous users (done by default)\nDELETE FROM mysql.user WHERE User='';\n\n-- Remove test database (done by default)\nDROP DATABASE IF EXISTS test;\n```\n\n### SSL/TLS Connections\n\nAll database instances support encrypted SSL/TLS connections:\n\n**Command Line - Simple SSL**:\n```bash\n# Modern clients (MariaDB 10.2+, MySQL 5.7.11+)\nmysql -h db-mariadb-123456.danubedata.ro -u admin -p \\\n  --ssl-mode=REQUIRED --ssl-verify-server-cert=OFF\n\n# Older clients\nmysql -h db-mariadb-123456.danubedata.ro -u admin -p \\\n  --ssl --ssl-verify-server-cert=0\n```\n\n**Command Line - Full SSL with Client Certificates**:\n```bash\n# Modern clients with full certificate authentication\nmysql -h db-mariadb-123456.danubedata.ro -u admin -p \\\n  --ssl-ca=/etc/database-certs/mariadb-instance-ca.pem \\\n  --ssl-cert=/etc/database-certs/mariadb-instance-client-cert.pem \\\n  --ssl-key=/etc/database-certs/mariadb-instance-client-key.pem\n```\n\n**Application (PHP PDO)**:\n```php\n$options = [\n    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,\n    PDO::MYSQL_ATTR_SSL_CA => '/etc/database-certs/mariadb-123456-ca.pem',\n    PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false, // Skip hostname verification\n];\n```\n\n**Why skip hostname verification?**  \nMariaDB auto-generates SSL certificates with generic names that don't match the actual hostname. Skipping hostname verification while using SSL still provides encryption for data in transit, which is safe for internal cluster traffic.\n\n**SSL certificates** are automatically provisioned to VPS instances at:\n- `/etc/database-certs/{database-name}-ca.pem`\n- `/etc/database-certs/{database-name}-client-cert.pem`\n- `/etc/database-certs/{database-name}-client-key.pem`\n\n### Regular Security Updates\n\nMariaDB instances are automatically updated with security patches:\n\n- **Minor updates**: Applied automatically during maintenance windows\n- **Major updates**: Require manual initiation\n- **Maintenance windows**: Configurable, typically off-peak hours\n- **Notifications**: Email notifications before scheduled maintenance\n\n## Troubleshooting\n\n### Connection Issues\n\n**Problem**: Cannot connect to database\n\n**Solutions**:\n- Verify connection details in dashboard\n- Check firewall rules allow your IP\n- Ensure SSL certificate is correctly configured\n- Test connection with `mysql` CLI tool\n- Check database status in dashboard\n\n### Performance Issues\n\n**Problem**: Slow queries or high CPU usage\n\n**Solutions**:\n- Review slow query log\n- Check for missing indexes\n- Analyze query execution plans with `EXPLAIN`\n- Consider upgrading to a larger profile\n- Optimize database schema and queries\n- Enable query cache for read-heavy workloads\n\n### Storage Full\n\n**Problem**: Database running out of storage\n\n**Solutions**:\n- Enable [storage autoscaling](https://docs.danubedata.ro/databases-overview#storage-autoscaling) so disk grows automatically before it fills up\n- Clean up old data\n- Archive historical records\n- Optimize tables with `OPTIMIZE TABLE`\n- Upgrade to a profile with more storage\n- Implement data retention policies\n\n### Too Many Connections\n\n**Problem**: \"Too many connections\" error\n\n**Solutions**:\n- Implement connection pooling\n- Reduce max connection lifetime\n- Close connections properly in application\n- Increase `max_connections` (contact support)\n- Upgrade to a larger profile with more max connections\n\n## Related Documentation\n\n- [Database Overview](https://docs.danubedata.ro/databases-overview)\n- [MySQL](https://docs.danubedata.ro/databases-mysql)\n- [PostgreSQL](https://docs.danubedata.ro/databases-postgresql)\n- [Database Replicas](https://docs.danubedata.ro/databases-replicas)\n- [Database Backups](https://docs.danubedata.ro/databases-backups)\n- [Parameter Groups](https://docs.danubedata.ro/databases-parameters)\n\n","prev":{"title":"SQL Studio","slug":"databases-sql-studio","url":"https://docs.danubedata.ro/databases-sql-studio","markdown_url":"https://docs.danubedata.ro/databases-sql-studio.md","json_url":"https://docs.danubedata.ro/databases-sql-studio.json"},"next":{"title":"Replicas","slug":"databases-replicas","url":"https://docs.danubedata.ro/databases-replicas","markdown_url":"https://docs.danubedata.ro/databases-replicas.md","json_url":"https://docs.danubedata.ro/databases-replicas.json"},"index_url":"https://docs.danubedata.ro/index.json"}