Como resolver o erro 1698 de acesso negado no MySQL e MariaDB

Se você obteve a mensagem ERROR 1698 ACCESS DENIED FOR USER ao tentar acessar o seu banco de dados MySQL ou MariaDB, este passo a passo pode ajudar a resolver o problema.
Abra um terminal e autentique-se no sistema como superusuário.
Agora, siga o procedimento:

  1. Autentique-se como administrador no servidor de banco de dados:
    
    mysql -u root
    

    e acesse o ‘mysql’:

    
    use mysql
    
  2. Faça a seguinte edição:
    
    update user set plugin='' where User='root';
    
  3. Por fim, “refresque” o cache e saia do servidor:
    
    flush privileges;
    exit
    

Estes 3 passos devem resolver o problema.

ERROR 1698 (28000): Access denied for user 'root'@'localhost'
ERROR 1698 (28000): Access denied for user ‘root’@’localhost’

Referências

https://superuser.com/questions/957708/mysql-mariadb-error-1698-28000-access-denied-for-user-rootlocalhost.
https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_access_denied_no_password_error.

Uma medida simples de segurança que você precisa tomar após instalar o MariaDB

O procedimento, descrito abaixo, é recomendado logo após instalar o servidor MySQL ou MariaDB.
Este texto é uma continuação do artigo instalação do servidor LAMP no Debian 9, onde explico os passos que o antecedem.
Antes de disponibilizar um servidor de banco de dados MySQL ou MariaDB em ambiente de produção, alguns ajustes de segurança se fazem necessários.
Podem ser feitos com a execução do mysql_secure_installation, já presente no seu sistema — ele foi instalado junto com o banco de dados.

O contexto em que este post foi escrito é uma instalação Debian 9.
Nesta versão, a distro iniciou uma transição do MySQL para o MariaDB, a exemplo de outras grandes distribuições.

Resumidamente, trata-se de um assistente para implementar as seguintes medidas de segurança:

  1. configurar a senha root (administrativa) do banco de dados
  2. remover o acesso root de fora do servidor local
  3. remover contas de usuários anônimos
  4. remover o banco de dados test, que oferece acesso padrão a todos os usuários, inclusive anônimos — além de privilégios que permite acessar indiscriminadamente bancos de dados que comecem com a string “_test”.

As medidas são necessárias e recomendadas em um servidor de banco de dados em produção.
Se você instalou o banco de dados para o seu aprendizado, para realizar testes ou para desenvolver aplicativos, provavelmente não vai precisar se preocupar com isto.

O utilitário deve ser executado sem argumentos, assim:


mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): 

Para poder se autenticar no MariaDB, para torná-lo mais seguro, será necessário fornecer a senha de usuário root.
Neste caso, o usuário root, a que nos referimos, é o do banco de dados e não o do Linux.
Se você acabou de instalar o MariaDB e ainda não configurou esta senha, ela ainda estará em branco.
Neste caso, pressione Enter, ao fim do texto.
O sistema irá pedir uma nova senha e a confirmação.

Em seguida irá perguntar se deve remover os usuários anônimos do seu sistema.
É seguro responder que sim (ou Yes).

O próximo passo irá perguntar se você quer desabilitar o acesso remoto do root.
Se fizer isto, o superusuário só poderá logar localmente, via localhost.
A opção segura é confirmar o ajuste (Yes).

A próxima opção pede para remover o banco de dados ‘test’, que é útil para quem deseja usar o servidor apenas para aprender ou testar código.
Em máquinas de produção, o seguro é remover este item (Yes).

Por fim, recarregue a tabela de privilégios, para que as alterações tenham efeito imediato no servidor (Yes).

… e pronto!
Como você pôde ver, foi fácil. Você pode responder Yes para todas as perguntas, exceto para redefinir a senha.

Assinar blog por e-mail

Digite seu endereço de e-mail para assinar este blog e receber notificações de novas publicações por e-mail.

Quais as diferenças entre Firebird Classic, Super e SuperClassic?

O servidor de bancos de dados Firebird vêm em 2 sabores, chamados arquiteturas: Classic Server e Super Server.
Desde a versão 2.5, o Firebird Classic Server pode operar em dois modos, chamados Classic (o “tradicional”) e SuperClassic.
Desta maneira, temos um total de 3 modelos disponíveis para instalação.
Qual deles é o mais adequado para você?
Firebird logo
Neste texto, vou listar as principais diferenças entre estas opções — já frisando que, na maioria dos casos, todos os três modelos funcionam igualmente bem e oferecem (quase) as mesmas possibilidades.
Entre as principais diferenças, citadas pela documentação do produto, segue a lista:

  • Processos — o Classic Server usa um processo separado para cada conexão; o SuperClassic Server e o Super Server (ou apenas Super) usam apenas um processo.
    Portanto, se um processo “quebrar”, durante sua execução, no Classic, as outras conexões não serão afetadas.
    No SuperClassic e no Super, um processo “quebrado” pode trazer abaixo todas as conexões.
  • O Guardian (ou guardião) — o Super pode rodar sob o controle do Firebird Guardian, que automaticamente o reinicia no caso de um crash.
    O SuperClassic só oferece a opção Guardian para instalações profissionais com Linux e o Classic, simplesmente, não a oferece.
  • Uso de recursos do sistema — Sendo single-process, o SuperClassic e o Super, usam os recursos do sistema com mais eficiência do que o Classic, à medida em que o número de conexões simultâneas cresce.
    O Super é o mais eficiente dos 3 porque dispõe, ainda, de um espaço de cache compartilhado.
  • Conexões locais — o Classic e o SuperClassic oferecem um modo de conexão local embarcado ou embedded, no Linux, que é muito rápido — mas não tão seguro quanto uma conexão de rede regular.
    No Windows, um servidor embarcado está disponível — mas é ainda mais inseguro. Contudo pode ser bastante prático se você deseja empacotar o Firebird com suas aplicações.
  • Conexões simultâneas — apenas o Classic e o SuperClassic permitem conexões simultâneas ao banco de dados do servidor regular e de um ou dois servidores embarcados.
  • Multiprocessamento — No Windows, o padrão do Super é usar apenas o primeiro processador ou núcleo (core) em seu computador. Para fazê-lo usar a capacidade plena da CPU, é preciso alterar a variável CpuAffinityMask no arquivo de configuração firebird.conf.
    Todos os outros servidores (o que inclui o Super no Linux), suportam naturalmente o multiprocessamento e ignoram o valor de CpuAffinityMask.

Ao executar os comandos “search”, em distribuições Linux, como o Debian ou o Ubuntu, você será apresentado a estes três modelos de instalação. Clique na imagem, abaixo, para ver mais detalhes.
aptitude search firebird2.5
Como você pode ver, nenhum dos 3 modelos consegue superar os outros 2 em todos os quesitos.
Se você não tem certeza sobre qual escolher, o SuperClassic pode ser uma boa opção em sistemas 64 bits.
Já nos sistemas 32 bits, o modelo SuperClassic será o primeiro a encher o espaço da memória em situação de sobrecarga do sistema.
O Super, com o uso de recursos de memória cache compartilhada e o Classic, com seus processos correndo em separado, obtém melhor performance em sistemas 32 bits.
Note que você sempre poderá mudar para outro modelo, quando quiser.
Suas aplicações e bancos de dados continuarão funcionando normalmente.
A única coisa que se altera são os servidores.

Como inserir o resultado de uma query SELECT em uma tabela MySQL

Neste post vou mostrar como pegar o resultado de uma consulta MySQL e gravá-lo em uma tabela preexistente, em vez de exibi-lo.
Se você deseja criar uma nova tabela a partir de uma query SELECT, sugiro ler o artigo Como criar uma tabela a partir de uma declaração SELECT no MySQL.
Mountain high and mysql logo
O servidor MySQL normalmente retorna o resultado de um SELECT ao cliente que o requisitou.
Se você faz uma requisição a partir do terminal cliente MySQL, é para onde os resultados serão enviados e exibidos.
Neste texto vou mostrar como enviar os resultados de um SELECT para dentro de uma outra tabela.
Copiar resultados de uma tabela para outra pode ser útil em vários casos:

  1. Se você estiver desenvolvendo um algoritmo que modifica uma tabela, certamente seria mais seguro trabalhar em uma cópia — o que evita ter que lidar com as consequências de um desastre em cima de informações importantes para você ou para a empresa em que você trabalha.
  2. Em algumas operações, pode ser interessante trabalhar em uma tabela temporária e, mais tarde, copiar os dados conferidos para a tabela definitiva.
  3. Você pode usar o recurso em um script, que toma dados de uma tabela maior e cria uma pequena tabela de serviços e vai atualizando a tabela principal aos poucos (ou em horários de menor fluxo na rede).
  4. Se você está aprendendo MySQL, pode ser interessante transferir dados para tabelas “de aprendizado” e deixar as tabelas de produção em paz.

Vou mostrar como usar o INSERT ... SELECT para obter informações de uma tabela e inseri-las em outra.
Para isto, vou fazer uso das tabelas ClientesCidades e CliCred. Sugiro adequar os exemplos às suas próprias tabelas. Contudo, se quiser, você pode pegar as minhas mal acabadas tabelas aqui.

Como inserir os resultados da query em uma tabela

A tabela CliCred tem 3 campos coincidentes com a tabela ClientesCidades. Veja o que o comando EXPLAIN mostra (em destaque):

EXPLAIN CliCred;
+-----------+-----------------------+------+-----+---------+----------------+
| Field     | Type                  | Null | Key | Default | Extra          |
+-----------+-----------------------+------+-----+---------+----------------+
| id        | mediumint(8) unsigned | NO   | PRI | NULL    | auto_increment |
| cc_nome   | varchar(255)          | YES  |     | NULL    |                |
| cc_cidade | varchar(255)          | YES  |     | NULL    |                |
| cc_cred   | mediumint(9)          | YES  |     | NULL    |                |
| cc_limite | mediumint(9)          | YES  |     | NULL    |                |
+-----------+-----------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

Embaixo, após o comando EXPLAIN, destaquei os campos que correspondem aos que foram destacados em cima:

EXPLAIN ClientesCidades;
+---------------+-----------------------+------+-----+---------+----------------+
| Field         | Type                  | Null | Key | Default | Extra          |
+---------------+-----------------------+------+-----+---------+----------------+
| id            | mediumint(8) unsigned | NO   | PRI | NULL    | auto_increment |
| NomeCliente   | varchar(255)          | YES  |     | NULL    |                |
| IdadeCliente  | mediumint(9)          | YES  |     | NULL    |                |
| CidadeCliente | varchar(255)          | YES  |     | NULL    |                |
| CredCliente   | mediumint(9)          | YES  |     | NULL    |                |
+---------------+-----------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

Cada uma destas 2 tabelas tem 100 registros.
Ao final da operação, a tabela ClientesCidades terá recebido os 100 registros da tabela CliCred — e passará a ter 200 registros.
Veja:

INSERT INTO ClientesCidades (NomeCliente, CidadeCliente, CredCliente) SELECT cc_nome, cc_cidade, cc_cred FROM CliCred; 

Vamos analisar o comando dado:

  • INSERT INTO ClientesCidades — Determina em que tabela ocorrerá a alteração (inserção de novos dados).
  • (NomeCliente, CidadeCliente, CredCliente) — Estes são os campos (as colunas) que serão alterados na tabela ClientesCidades.
  • SELECT cc_nome, cc_cidade, cc_cred FROM CliCred — Seleciona os valores contidos nos campos cc_nome, cc_cidade, cc_cred na tabela CliCred, para inserir na primeira tabela.

Veja uma listagem parcial (apenas os 10 últimos registros) da nova tabela ClientesCidades:

SELECT * FROM ClientesCidades where id > 190;
+-----+-------------------+--------------+----------------+-------------+
| id  | NomeCliente       | IdadeCliente | CidadeCliente  | CredCliente |
+-----+-------------------+--------------+----------------+-------------+
| 191 | Paula Wiley       |         NULL | St. Catharines |         187 |
| 192 | Cathleen Thornton |         NULL | Rouvroy        |         289 |
| 193 | Laurel Espinoza   |         NULL | Boneffe        |         131 |
| 194 | Amber Sparks      |         NULL | Kailua         |         256 |
| 195 | Elizabeth Bean    |         NULL | Beaconsfield   |         147 |
| 196 | Eleanor Cleveland |         NULL | Rosciano       |         295 |
| 197 | Virginia Dillon   |         NULL | Metairie       |         209 |
| 198 | Jana Dyer         |         NULL | Birori         |         135 |
| 199 | Kendall Reid      |         NULL | Westkapelle    |         274 |
| 200 | Katell Robinson   |         NULL | Colonnella     |         149 |
+-----+-------------------+--------------+----------------+-------------+
10 rows in set (0.03 sec)

Em uma análise do resultado, note que:

  1. o último valor do campo id, em ClientesCidades, reflete o acréscimo de mais 100 registros. Agora são 200 registros;
  2. 100 nomes de clientes, de cidades e valores de Crédito foram adicionados nos campos NomeCliente, CidadeCliente e CredCliente;
  3. A tabela CliCred não tem o campo IdadeCliente, por isto o valor NULL (nulo) foi gravado nos campos correspondentes.

Como copiar todos os valores de uma tabela para outra

Isto é bem mais fácil e pode realizado com um comando mais enxuto e menor preocupação com a sintaxe.
Vamos supor a existência das tabelas tabela_Origem e tabela_Destino, ambas com estruturas idênticas.
Para copíar os valores da primeira para dentro da segunda, use o seguinte comando:

INSERT INTO tabela_Destino SELECT * FROM tabela_Origem;

E se eu quisesse copiar apenas as informações sobre clientes com créditos superiores a 300?
Vamos retomar (e alterar) o exemplo acima:

INSERT INTO ClientesCidades (NomeCliente, CidadeCliente, CredCliente) SELECT cc_nome, cc_cidade, cc_cred FROM CliCred WHERE cc_cred > 300; 

Como, no caso da minha tabela, nenhum cliente tem valor de crédito superior a 300, o resultado foi este:

Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

Uma última dica: Você pode usar a mesma tabela como origem e destino.

Divirta-se e tenha um bom aprendizado!

Como conectar ao MySQL de um script em PHP

A tarefa mais básica de scripts que fazem uso do servidor de bancos de dados é a conexão. Em seguida, vem a seleção do banco de dados, da tabela e as consultas (queries).
php and mysql logos
O exemplo de script PHP, usado neste texto, necessita que você tenha tanto o MySQL quanto o PHP instalados no seu sistema.
Se você não tem certeza de que este é o seu caso, pode usar as dicas no final do artigo Como instalar Linux, MySQL, Apache e PHP, para saber se tudo está ok.
Embora o PHP e o MySQL possam ser executados da linha de comando, este texto vai se voltar para a execução a partir de um servidor web.
Sinta-se à vontade para usar a caixa de busca, no canto superior direito deste site, sempre que quiser alguma informação adicional (neste momento, temos quase 500 tutoriais…) 😉

Como se conectar ao MySQL via PHP

Por ser uma atividade tão trivial, programadores mais ocupados criam bibliotecas de scripts que fazem a conexão — e chamam estes scripts de dentro de seus outros scripts.
É comum programadores experientes terem esquecido como realizar tarefas básicas como esta.
Se você é iniciante, não se esqueça de usar um editor de textos adequado a escrever códigos de programas, para evitar problemas na execução dos seus scripts.
Do lado de cá, vou criar um arquivo chamado conecta.php, dentro do qual vou inserir o código em PHP para fazer uma simples conexão ao banco de dados MySQL e, em seguida, desconectar.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Página de conexão ao banco de dados</title>
</head>
<body>
<!-- O script PHP começa abaixo -->

<?php
    conecta.php - script de conexão ao servidor MySQL
    if (!($con = @mysql_connect ("localhost", "justincase", "minhasenha")))
    {
        die ("Não foi possível conectar ao servidor. <br />");
    }
    print ("Conexão bem sucedida. <br />");
    if (!@mysql_select_db ("tutorial", $con))
    {
        die ("Não foi possível selecionar o banco de dados. <br />");
    }
    mysql_close ($con);
    print ("Conexão terminada. <br />");
?>

<!-- Fim do script PHP -->
</body>
</html>

A partir deste código, é possível construir o que você quiser.
A parte em HTML do código, logo no começo, serve apenas para localizar a página e permitir que as mensagens (em português) sejam exibidas com as palavras devidamente acentuadas — não fazem parte, portanto, do programa em si.

Entenda o código em PHP

  • if (!($con = @mysql_connect ("localhost", "justincase", "minhasenha"))) — esta parte tenta fazer uma conexão com a função mysql_connect(), usando os dados de nome do servidor, nome do usuário “justincase” e a senha “minhasenha”.
  • die ("Não foi possível conectar ao servidor.");
    — se nada der certo, o script será interrompido pela função die(), com a exibição da mensagem entre as aspas.
    Se a conexão se efetivar, o programa prossegue a próxima instrução e armazena as informações da conexão na variável $con.
  • print ("Conexão bem sucedida."); — exibe a mensagem entre aspas.
  • if (!@mysql_select_db ("tutorial", $con))
    — tenta selecionar o banco de dados “tutorial”, com as informações armazenadas na variável $con. Se isto não for possível, executa a instrução que segue:
  • die ("Não foi possível selecionar o banco de dados."); — finaliza o script e devolve a mensagem entre aspas.
  • mysql_close ($con); — se tudo correu bem, até aqui, o script irá fechar a conexão, baseado nas informações contidas em $con.
  • print ("Conexão terminada."); — exibe a frase entre aspas.

Captura de tela do komodo editor - código PHP para conectar ao banco de dados MySQL

Funções PHP para conectar ao MySQL

Neste artigo, usei a função mysql_connect(), para fazer a conexão ao banco de dados. Alternativamente, você pode usar a função mysql_pconnect() — para estabelecer uma conexão persistente.
Pode ser útil caso você queira deixar a conexão aberta para ser reutilizada por outros scripts subsequentes — evitando, assim, alguma sobrecarga ao servidor.
Iniciar conexões persistentes e deixá-las abertas (por esquecimento), pode acarretar, como consequência a negação de abertura de novas conexões por parte do servidor MySQL.
Portanto, seja organizado(a) neste ponto.