MariaDB: Primeiros passos

Como começar a utilizar o MariaDB

👋 Bem-vindo à documentação da Stackhero!

A Stackhero oferece uma solução MariaDB cloud pronta para uso que proporciona uma série de benefícios, incluindo:

  • Conexões e transferências ilimitadas.
  • Interface web phpMyAdmin incluída.
  • Atualizações fáceis com apenas um clique.
  • Desempenho ótimo e segurança robusta alimentados por uma VM privada e dedicada.

Poupe tempo e simplifique a sua vida: leva apenas 5 minutos para experimentar a solução de MariaDB cloud hosting da Stackhero!

A forma mais simples de se ligar ao seu serviço MariaDB é utilizar o formato de URL do MySQL, desde que o seu driver o suporte:

mysql://root:<ROOT_PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/root?useSSL=true&requireSSL=true

Se estiver a utilizar Ruby, a URL MySQL é ligeiramente diferente:

mysql2://root:<ROOT_PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/root?reconnect=true&useSSL=true&requireSSL=true

Aqui ficam alguns exemplos de como pode ligar-se ao MariaDB a partir de PHP usando diferentes extensões. Embora estes exemplos utilizem a base de dados "root", recomenda-se criar uma base de dados e um utilizador dedicados para a sua aplicação, especialmente em ambientes de produção.

<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port     = '<PORT>';
$user     = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // Apenas para demonstração. Para boas práticas, crie a sua própria base de dados e utilizador no phpMyAdmin e utilize essas credenciais.

$mysqli = mysqli_init();
$mysqliConnected = $mysqli->real_connect($hostname, $user, $password, $database, $port, NULL, MYSQLI_CLIENT_SSL);
if (!$mysqliConnected) {
  die('Erro de ligação: ' . $mysqli->connect_error);
}

echo 'Ligação bem-sucedida... ' . $mysqli->host_info . "\n";

$mysqli->close();

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port     = '<PORT>';
$user     = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // Apenas para demonstração. Para boas práticas, crie a sua própria base de dados e utilizador no phpMyAdmin e utilize essas credenciais.

$mysqli = mysqli_init();
$mysqliConnected = mysqli_real_connect($mysqli, $hostname, $user, $password, $database, $port, NULL, MYSQLI_CLIENT_SSL);
if (!$mysqliConnected) {
  die('Erro de ligação: ' . mysqli_connect_error($mysqli));
}

echo 'Sucesso: ' . mysqli_get_host_info($mysqli) . "\n";

mysqli_close($mysqli);

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port     = '<PORT>';
$user     = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // Apenas para demonstração. Para boas práticas, crie a sua própria base de dados e utilizador no phpMyAdmin e utilize essas credenciais.

$dsn = "mysql:host=$hostname;port=$port;dbname=$database";

$options = array(
  // Se receber um erro como "Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed", certifique-se de que o diretório /etc/ssl/certs/ contém os certificados CA.
  PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/',
  // PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem',
  PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
);

$pdo = new PDO($dsn, $user, $password, $options);

$stm = $pdo->query('SELECT VERSION()');
$version = $stm->fetch();

echo 'Está ligado a uma base de dados com a versão ' . $version[0] . "\n";

?>

Se vir este erro:

Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed

é provável que o diretório /etc/ssl/certs/ não tenha os certificados CA necessários. Se tiver acesso ao sistema, aqui ficam algumas sugestões para os instalar:

  1. No Ubuntu, pode executar:

    apt-get install ca-certificates
    
  2. No Alpine Linux, tente:

    apk add ca-certificates
    

Se não tiver acesso ao sistema, pode adicionar o certificado manualmente:

  1. Faça o download do certificado: https://letsencrypt.org/certs/isrgrootx1.pem
  2. Coloque o ficheiro isrgrootx1.pem no seu projeto PHP.
  3. Comente a linha com PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/'
  4. Descomente a linha com PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem'

Se vir um erro como este:

Fatal error: Uncaught Error: Undefined constant PDO::MYSQL_ATTR_SSL_CAPATH

ou uma mensagem semelhante a referir uma constante PDO MySQL não definida, provavelmente a sua instalação PDO não inclui suporte para MySQL.

No Ubuntu/Debian

Pode instalar a extensão PHP MySQL necessária com:

sudo apt-get install php-mysql
Se estiver a utilizar Docker

Para garantir que o suporte MySQL está disponível, pode adicionar o seguinte ao seu Dockerfile:

RUN docker-php-ext-install pdo pdo_mysql

### Utilizar MariaDB com Symfony e Doctrine

Para começar, edite o seu ficheiro `.env` e defina a variável `DATABASE_URL` desta forma:

DATABASE_URL="mysql://<USER>:<PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/<DATABASE>"


De seguida, atualize o ficheiro `config/packages/doctrine.yaml` para definir o driver e as opções:

```yaml
doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
        driver: 'pdo_mysql'
        options:
            # PDO::MYSQL_ATTR_SSL_CAPATH
            1010: '/etc/ssl/certs'
            # PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT
            1014: true

Se se deparar com este erro:

Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed

provavelmente o seu sistema não tem os certificados CA instalados. Eis algumas formas de os instalar:

  • No Ubuntu/Debian, pode executar:

    sudo apt-get install ca-certificates
    
  • No Alpine Linux, tente:

    apk add ca-certificates
    

Se não conseguir instalar os certificados CA a nível de sistema, pode adicioná-los manualmente:

  1. Faça o download do certificado: https://letsencrypt.org/certs/isrgrootx1.pem

  2. Coloque o ficheiro isrgrootx1.pem no seu projeto Symfony.

  3. Atualize o ficheiro config/packages/doctrine.yaml:

    doctrine:
        dbal:
            url: '%env(resolve:DATABASE_URL)%'
            driver: 'pdo_mysql'
            options:
                # PDO::MYSQL_ATTR_SSL_CA
                1009: 'isrgrootx1.pem'
                # PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT
                1014: true
    

Para configurar o MariaDB com Laravel, abra o ficheiro config/database.php e atualize a configuração mysql da seguinte forma:

'mysql' => [
  'driver'   => 'mysql',
  'host'     => env('STACKHERO_MARIADB_HOST'),
  'port'     => env('STACKHERO_MARIADB_PORT'),
  'username' => env('STACKHERO_MARIADB_USER'),
  'password' => env('STACKHERO_MARIADB_PASSWORD'),
  'database' => env('STACKHERO_MARIADB_USER'),
  'charset'  => 'utf8mb4',
  'collation'=> 'utf8mb4_unicode_ci',
  'prefix'   => '',
  'prefix_indexes' => true,
  'strict'   => true,
  'engine'   => null,
  'sslmode'  => 'require',
  'options'  => extension_loaded('pdo_mysql')
    ? array_filter([
      // Se encontrar erros SSL como "Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed", consulte os passos de resolução acima.
      PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/',
      // PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem',
      PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
    ])
    : [],
],

No seu ficheiro database.php, pode configurar a ligação da seguinte forma:

$db['default'] = array(
  'hostname' => getenv('STACKHERO_MARIADB_HOST'),
  'port'     => getenv('STACKHERO_MARIADB_PORT'),
  'username' => getenv('STACKHERO_MARIADB_USER'),
  'password' => getenv('STACKHERO_MARIADB_PASSWORD'),
  'database' => getenv('STACKHERO_MARIADB_USER'), // Por convenção, o nome da base de dados corresponde ao nome do utilizador.
  'dbdriver' => 'mysqli',
  'dbprefix' => '',
  'pconnect' => TRUE,
  'char_set' => 'utf8',
  'dbcollat' => 'utf8_general_ci',
  'encrypt'  => array() // Importante: ative a encriptação TLS
);

É uma boa prática não colocar as credenciais diretamente no código, mas sim utilizar variáveis de ambiente. Pode obtê-las assim:

$hostname = getenv('STACKHERO_MARIADB_HOST');
$port     = getenv('STACKHERO_MARIADB_PORT');
$user     = getenv('STACKHERO_MARIADB_USER');
$password = getenv('STACKHERO_MARIADB_PASSWORD');
$database = getenv('STACKHERO_MARIADB_USER'); // Por convenção, o nome da base de dados corresponde ao nome do utilizador.

Ligar o WordPress ao Stackhero para MariaDB é simples. No seu ficheiro wp-config.php, defina os seguintes parâmetros de base de dados:

define('DB_HOST', '<XXXXXX>.stackhero-network.com');
define('DB_PORT', '<PORT>');
define('DB_NAME', 'root');
define('DB_USER', 'root');
define('DB_PASSWORD', '<yourPassword>');

// Ativar encriptação TLS (também chamado SSL)
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

O passo essencial aqui é ativar a encriptação TLS (por vezes chamada SSL). A ligação não funcionará sem isto.

Se estiver a utilizar Node.js, pode experimentar o pacote mysql2, que suporta promessas. Para instalar:

npm install mysql2

Aqui fica um exemplo que pode adaptar:

const mysql = require('mysql2/promise');

(async () => {
  const db = await mysql.createConnection({
    host: '<XXXXXX>.stackhero-network.com',
    port: '<PORT>',
    user: 'root',
    password: '<ROOT_PASSWORD>'
  });

  // Criar a base de dados se ainda não existir
  await db.query('CREATE DATABASE IF NOT EXISTS stackherotest');

  // Criar a tabela users se ainda não existir
  await db.query(
    'CREATE TABLE IF NOT EXISTS `stackherotest`.`users` (' +
      '`userId` INT UNSIGNED NOT NULL,' +
      '`name` VARCHAR(128) NOT NULL,' +
      '`address` TEXT NOT NULL,' +
      '`email` VARCHAR(265) NOT NULL' +
    ') ENGINE = InnoDB;'
  );

  // Inserir um utilizador de exemplo
  await db.query(
    'INSERT INTO `stackherotest`.`users` (`userId`, `name`, `address`, `email`) VALUES ?',
    [
      [
        Math.round(Math.random() * 100000), // Gerar um userId
        'User name',                         // name
        'User address',                      // address
        '[email protected]'                     // email
      ]
    ]
  );

  // Contar utilizadores na tabela
  const [usersCount] = await db.query('SELECT COUNT(*) AS `cpt` FROM `stackherotest`.`users`');
  console.log(`Existem agora ${usersCount[0].cpt} entradas na tabela "users"`);

  // Fechar a ligação
  await db.end();

})().catch(error => {
  console.error('');
  console.error('Ocorreu um erro!');
  console.error(error);
  process.exit(1);
});

Para Node.js, NestJS ou TypeORM, pode ativar SSL incluindo a opção ssl:

TypeOrmModule.forRoot({
  type: 'mysql',
  host: '<XXXXXX>.stackhero-network.com',
  port: '<PORT>',
  username: 'root',
  password: '<ROOT_PASSWORD>',
  database: 'root',
  entities: [],
  synchronize: true,
  ssl: {}
});

Para ligar ao MariaDB com Prisma, basta adicionar sslaccept=strict à sua URL de ligação. Por exemplo, se estiver a ligar-se como "root" à base de dados "root":

datasource db {
  provider = "mysql"
  url = "mysql://root:<ROOT_PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/root?sslaccept=strict"
}

Se ainda não o fez, pode instalar o módulo mysqlclient para ligar o Django ao MariaDB:

pip install mysqlclient

Se receber o erro Exception: Can not find valid pkg-config name durante a instalação, poderá ser necessário instalar primeiro o pacote libmysqlclient. Para Ubuntu/Debian:

apt-get update && apt-get install --no-install-recommends -y libmysqlclient-dev

Para testar a ligação, pode começar por colocar as credenciais diretamente em settings.py. Isto é aceitável para testes, mas não é seguro para produção.

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'HOST': '<XXXXXX>.stackhero-network.com',
    'PORT': '<PORT>',
    'OPTIONS': {
      'ssl_mode': 'REQUIRED',
    },
    'NAME': 'root',
    'USER': 'root',
    'PASSWORD': '<ROOT_PASSWORD>'
  }
}

Atenção: Este exemplo é apenas para testes. Não utilize credenciais hardcoded em produção.

Depois de confirmar que a ligação funciona, é mais seguro guardar as credenciais em variáveis de ambiente. Se utilizar django-environ, pode instalá-lo assim:

pip install django-environ

Depois, atualize o settings.py:

import environ
env = environ.Env()
environ.Env.read_env()

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'HOST': env('STACKHERO_MARIADB_HOST'),
    'PORT': env('STACKHERO_MARIADB_PORT'),
    'OPTIONS': {
      'ssl_mode': 'REQUIRED',
    },
    'NAME': 'root',
    'USER': 'root',
    'PASSWORD': env('STACKHERO_MARIADB_ROOT_PASSWORD')
  }
}

Depois, crie ou atualize o ficheiro .env (no mesmo diretório que o settings.py) com:

STACKHERO_MARIADB_HOST=<XXXXXX>.stackhero-network.com
STACKHERO_MARIADB_PORT=<PORT>
STACKHERO_MARIADB_ROOT_PASSWORD=<ROOT_PASSWORD>

Por fim, para manter as credenciais seguras, adicione .env ao seu .gitignore:

echo ".env" >> .gitignore

Para ligar uma aplicação Spring ao MariaDB, pode definir a variável de ambiente SPRING_DATASOURCE_URL com a sua URL de base de dados, usando o prefixo jdbc:. Por exemplo:

SPRING_DATASOURCE_URL=jdbc:mysql://root:<ROOT_PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/root?useSSL=true&requireSSL=true

Aqui fica um exemplo de como pode configurar a sua aplicação Grails para ligar ao MariaDB:

dataSource {
  pooled = true
  driverClassName = "com.mysql.cj.jdbc.Driver"
  dialect = org.hibernate.dialect.MySQL8Dialect
  // Propriedades específicas de SSL
  properties {
    useSSL = true
    requireSSL = true
    verifyServerCertificate = true
    sslMode = "REQUIRED"
  }
}

environments {
  production {
    dataSource {
      dbCreate = "none"
      url = "jdbc:mysql://" + System.env.STACKHERO_MYSQL_HOST + ":" + System.env.STACKHERO_MYSQL_PORT + "/root?useSSL=true&requireSSL=true&verifyServerCertificate=true&sslMode=required" // Substitua '/root' pelo nome real da sua base de dados.
      username = "root" // É aconselhável criar um utilizador dedicado para a sua aplicação.
      password = System.env.STACKHERO_MYSQL_ROOT_PASSWORD // Considere criar um utilizador dedicado.
      properties {
        maxActive = 50
        minEvictableIdleTimeMillis = 1800000
        timeBetweenEvictionRunsMillis = 1800000
        numTestsPerEvictionRun = 3
        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = false
        validationQuery = "SELECT 1"
      }
    }
  }
}

Para maior segurança, é preferível criar um utilizador dedicado para a sua aplicação em vez de utilizar o "root". Pode fazê-lo facilmente no phpMyAdmin:

  1. No phpMyAdmin, clique em User accounts no topo.
  2. Clique em Add user account.
  3. Preencha o formulário:
    • Escolha um nome de utilizador (normalmente o nome da sua aplicação).
    • Clique em Generate password para obter uma palavra-passe forte e copie-a.
    • Assinale Create database with same name and grant all privileges.

Depois de submeter, será criado o novo utilizador e uma base de dados correspondente.

O MariaDB é um fork independente do MySQL, criado pela comunidade open source após a aquisição do MySQL pela Oracle em 2010. Para a maioria dos casos de utilização, MariaDB e MySQL oferecem funcionalidades e compatibilidade muito semelhantes.