Para melhor visualização, recomendo resolução de no mínimo 1280 x 800 e navegador Mozilla Firefox


quinta-feira, 1 de agosto de 2019

MongoDB - Redimensionando o tamanho do oplog

Por Eduardo Legatti

Olá,

No MongoDB a partir da versão 3.6 em um ambiente de replicasets, temos a opção de redimensionar o tamanho do oplog de forma online através da função replSetResizeOplog. No exemplo abaixo poderemos executar o comando para aumentar o oplog para 32 GB nos membros SECONDARY primeiro e por último no membro PRIMARY.

PrdSet:SECONDARY> db.adminCommand({replSetResizeOplog: 1, size: 32768})

Nas versões do MongoDB anteriores a versão 3.6 precisamos fazer de forma offline, ou seja, os membros da replicaset precisam sofrer shutdown e subir de forma standalone para poder redimensionar o oplog. O ideal é verificar se existe retenção suficiente no oplog do membro primário quando o membro subir e voltar novamente como membro da replicaset de forma que a sincronização tenha tempo suficiente para ser realizada. No mais, segue abaixo os procedimentos necessários realizados para redimensionar o tamanho do oplog em um ambiente de replicaset que utilizam o MongoDB 3.2. O propósito será aumentar o tamanho do oplog de 1GB para 32GB de forma que a sincronização entre os membros tenham uma margem de tempo razoável.

Abaixo, irei checar o status da replicaset de todos os membros envolvidos.

[mongodb@linux2 ~]$ mongo --port 27017
MongoDB shell version: 3.2.17
connecting to: 127.0.0.1:27017/test

PrdSet:SECONDARY> rs.status()
{
        "set" : "PrdSet",
        "myState" : 1,
        "term" : NumberLong(37),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "members" : [
                {
                        "_id" : 0,
                        "name" : "linux.local.net:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 201,
                        "configVersion" : 4,
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "linux2.local.net:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 194,
                        "pingMs" : NumberLong(0),
                        "syncingTo" : "linux.local.net:27017",
                        "configVersion" : 4
                },
                {
                        "_id" : 2,
                        "name" : "linux3.local.net:27017",
                        "health" : 1,
                        "state" : 7,
                        "stateStr" : "ARBITER",
                        "uptime" : 194,
                        "pingMs" : NumberLong(0),
                        "configVersion" : 4
                }
        ],
        "ok" : 1
}

A estratégia é realizar o procedimento primeiro nos membros SECONDARY e por último no membro PRIMARY. irei realizar o shutdown do MongoDB no nó linux2.local.net:27017 e subi-lo standalone utilizando a porta 37018 conforme a seguir.

[mongodb@linux2 ~]$ mongod --dbpath /mongodb/data --shutdown
killing process with pid: 1786

[mongodb@linux ~]$ mongod --fork --port 37018 --dbpath /mongodb/data/ --logpath /mongodb/log/mongo_PRD.log
about to fork child process, waiting until server is ready for connections.
forked process: 1954
child process started successfully, parent exiting

Após subir a instância do MongoDB como standalone na porta 37018, irei conectar nele e realizar os procedimentos para redimensionamento do oplogsize de 1GB para 32GB. Observe abaixo que ao executar o comando db.printReplicationInfo(), temos a informação do tamanho atual do oplog além da informação de que a retenção do oplog atual do membro PRIMARY está em 4.5 horas, ou seja, um membro SECONDARY conseguiria ficar em média até 4.5 horas fora da replicaset e mesmo assim conseguir se sincronizar com o PRIMARY até esse tempo.

[mongodb@linux2 ~]$ mongo --port 37018
MongoDB shell version: 3.2.17

> //Recreate the Oplog with a New Size and a Seed entry
> use local
switched to db local
> db = db.getSiblingDB('local')
local

> //get size of the oplog
> db.printReplicationInfo()
configured oplog size:   1024MB
log length start to end: 16200secs (4.5hrs)

> //Ensure that the temp temporary collection is empty by dropping the collection
> db.temp.drop()
false

> //Use the db.collection.save() method and a sort on reverse natural order to find the last entry and save it to a temporary collection
> db.temp.save(db.oplog.rs.find( { }, { ts: 1, h: 1 } ).sort( {$natural : -1} ).limit(1).next())
WriteResult({ "nInserted" : 1 })

> //Remove the Existing Oplog Collection
> db.oplog.rs.drop()
true

> //Create a New Oplog
> db.runCommand({ create: "oplog.rs", capped: true, size: (32 * 1024 * 1024 * 1024) })
{ "ok" : 1 }

> //Insert the Last Entry of the Old Oplog into the New Oplog
> db.oplog.rs.save(db.temp.findOne())
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 1,
        "nModified" : 0,
        "_id" : ObjectId("5d1fb2f43037c7e5b94410cf")
})

> exit
bye

Pronto. Agora podemos subir o MongoDB novamente como membro da replicaset na sua porta usual.

[mongodb@linux2 ~]$ mongod --dbpath /mongodb/data --shutdown
killing process with pid: 1954

[mongodb@linux2 ~]$ mongod --fork --journal --replSet PrdSet --port 27017 --dbpath /mongodb/data/ --logpath /mongodb/log/mongo_PRD.log
about to fork child process, waiting until server is ready for connections.
forked process: 3348
child process started successfully, parent exiting

Podemos ver abaixo que o oplog agora está com tamanho de 32GB.

[mongodb@linux2 ~]$ mongo --port 27017
MongoDB shell version: 3.2.17
connecting to: 127.0.0.1:27017/test

PrdSet:SECONDARY> db.printReplicationInfo()
configured oplog size:   32768MB
log length start to end: 16200secs (4.5hrs)

Feito esse procedimento em todos os membros SECONDARY, o último passo será realizá-lo no membro PRIMARY. será necessário apenas repetir o mesmo procedimento. Para tanto, de forma a não gerar indisponibilidade no cluster do MongoDB, será necessário eleger um novo membro PRIMARY antes de realizar essa operação. Basta executar o comando rs.stepDown() no membro PRIMARY de forma que algum membro SECONDARY assuma como PRIMARY. Após a realização do stepDown, o antigo PRIMARY se tornará SECONDARY e o procedimento poderá ser realizado normalmente.

quarta-feira, 10 de julho de 2019

GUOB TECH DAY 2019

Por Eduardo Legatti

Olá,

 
 
 
Com grande sucesso, o GUOB prepara mais uma edição de seu evento nacional no dia 10/08/2019 em São Paulo na Universidade Nove de Julho, UNINOVE, o qual proporcionará um grande encontro de usuários de tecnologia Oracle do Brasil com a participação de palestrantes internacionais e nacionais.

Estarão presentes palestrantes como Anil Nair, Sandesh Rao, Mike Dietrich, Nirmala Sundarappa, Alex Zaballa , entre outros.

Como resultado esperado contaremos com a qualidade das palestras, as quais garantirão o investimento dos participantes em dedicar um dia para estar presente em nosso evento. Além do netwoking proporcionado aos associados do GUOB e aos profissionais usuários de tecnologia Oracle.

Participe da 10o. edição do GUOB TECH DAY / Groundbreakers Tour LATAM 2019. Faça sua inscrição ainda hoje.

GUOB - Grupo de Usuários de Tecnologia Oracle do Brasil.

terça-feira, 2 de julho de 2019

Oracle - ALTER SYSTEM CANCEL SQL no Oracle 12 R2 (18c)

Por Eduardo Legatti

Olá,

A partir do Oracle 12c R2 (18c) temos a opção de abortar a execução de uma instrução SQL em andamento de uma sessão. Nas versões anteriores tínhamos apenas a opção de de matar a sessão (ALTER SYSTEM KILL SESSION). Segue abaixo um exemplo.

A sessão mais abaixo teve sua instrução em andamento interrompida após a execução do comando a seguir. Pode-se observar que a sessão continua conectada mesmo após a execução do comando ALTER SYSTEM CANCEL SQL.

C:\>sqlplus system/manager@linuxserver:1521/ORCLPDB1

SQL> ALTER SYSTEM CANCEL SQL '52, 43281';

Sistema alterado.

C:\>sqlplus scott/tiger@linuxserver/ORCLPDB1

Conectado a:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production

SQL> select sid,serial# from v$session where sid in (select distinct sid from v$mystat);

                 SID              SERIAL#
-------------------- --------------------
                  52                43281

SQL> select count(*) from t1;
select count(*) from t1
                     *
ERRO na linha 1:
ORA-01013: o usuário solicitou o cancelamento da operação atual

SQL> select sysdate from dual;

SYSDATE
----------
02/07/2019

Caso queiramos realmente matar a sessão devemos proceder com o comando a seguir.


C:\>sqlplus system/manager@linuxserver:1521/ORCLPDB1

SQL> ALTER SYSTEM KILL SESSION '52, 43281';

Sistema alterado.

C:\>sqlplus scott/tiger@linuxserver/ORCLPDB1

Conectado a:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production

SQL> select sid,serial# from v$session where sid in (select distinct sid from v$mystat);

                 SID              SERIAL#
-------------------- --------------------
                  52                43281

SQL> select count(*) from t1;
select count(*) from t1
*
ERRO na linha 1:
ORA-00028: a sessão foi cancelada

O comando ALTER SYSTEM CANCEL SQL pode receber outros parâmetros. Segue um resumo.

-- Instrução SQL corrente da sessão
ALTER SYSTEM CANCEL SQL '52, 43281';

-- Instrução SQL corrente da sessão em um ambiente RAC no node 1
ALTER SYSTEM CANCEL SQL '52, 43281, @1';

-- SQL_ID específico de uma sessão
ALTER SYSTEM CANCEL SQL '52, 43281, 12czs5bwerdfg';

-- SQL_ID específico de uma sessão em um ambiente RAC no node 1
ALTER SYSTEM CANCEL SQL '52, 43281, @1, 12czs5bwerdfg';

quinta-feira, 6 de junho de 2019

MySQL - Procedimento de Diagnóstico utilizando o PERFORMANCE_SCHEMA

Por Eduardo Legatti

Olá,

No MySQL a partir da versão 5.7 tem uma procedimento de diagnóstico da instância que pode ser útil em casos que precise de um relatório geral sobre o ambiente. Pode-se dizer que é um tipo de AWR do Oracle disponível para o MySQL só que para o workload atual. O relatório é extenso mas segue abaixo algumas imagens sobre saída do mesmo gerado em HTML. Seguindo a documentação, eu pedi no exemplo abaixo para fazer uma iteração a cada 30 segundos durante 60 segundos.

mysql -uroot -p -H -e"CALL sys.diagnostics(60, 30, 'current');" > /tmp/mysql_report.html









quinta-feira, 2 de maio de 2019

Oracle - Acessando a view V$SESSION em um ambiente Multitenant

Por Eduardo Legatti

Olá,

Nos ambientes de banco de dados Multitenant a partir do Oracle 12c podemos podemos ter um ou mais bancos de dados plugáveis em uma instância CDB$ROOT. Utilizando o Oracle 18c a seguir, irei mostrar que a view dinâmica de desempenho V$SESSION retorna as sessões de todos os bancos de dados quando executada a partir do banco de dados CDB$ROOT e, quando executada a partir de um banco de dados PDB, irá ser retornado apenas as sessões conectadas apenas neste PDB.

Abaixo é possível perceber que ao conectar no banco de dados CDB$ROOT podemos visualizar todos os datafiles de todos os bancos de dados CDB e PDBs através da view CDB_DATA_FILES. Ao acessar a view V$SESSION também é possível visualizar todas as sessões de todos os bancos de dados.

C:\>sqlplus sys/manager@bdserver:1521/ORCLCDB as sysdba

SQL*Plus: Release 12.2.0.1.0 Production on Qui Mai 2 9:35:50 2019

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Conectado a:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production


SQL> select sys_context('USERENV','CON_NAME') from dual;

SYS_CONTEXT('USERENV','CON_NAME')
---------------------------------
CDB$ROOT

SQL> select file_name,file_id,tablespace_name,bytes,status from CDB_DATA_FILES;

FILE_NAME                                                FILE_ID TABLESPACE_NAME            BYTES STATUS
----------------------------------------------------- ---------- ------------------- ------------ -----------
/opt/oracle/oradata/ORCLCDB/users01.dbf                        7 USERS                    5242880 AVAILABLE
/opt/oracle/oradata/ORCLCDB/undotbs01.dbf                      4 UNDOTBS1               319815680 AVAILABLE
/opt/oracle/oradata/ORCLCDB/system01.dbf                       1 SYSTEM                 891289600 AVAILABLE
/opt/oracle/oradata/ORCLCDB/sysaux01.dbf                       3 SYSAUX                 555745280 AVAILABLE
/opt/oracle/oradata/ORCLCDB/ORCLPDB1/system01.dbf              9 SYSTEM                 283115520 AVAILABLE
/opt/oracle/oradata/ORCLCDB/ORCLPDB1/sysaux01.dbf             10 SYSAUX                 387973120 AVAILABLE
/opt/oracle/oradata/ORCLCDB/ORCLPDB1/undotbs01.dbf            11 UNDOTBS1               104857600 AVAILABLE
/opt/oracle/oradata/ORCLCDB/ORCLPDB1/users01.dbf              12 USERS                    5242880 AVAILABLE

SQL> select sid,serial#,service_name,username,status,osuser,terminal,program
  2    from v$session
  3   where osuser='eduardo.legatti';

   SID      SERIAL# SERVICE_NAME     USERNAME      STATUS     OSUSER               TERMINAL          PROGRAM
------ ------------ ---------------- ------------- ---------- -------------------- ----------------- ---------------
      38         9924 orclpdb1       SCOTT         INACTIVE   eduardo.legatti      SRVNOT001         sqlplus.exe
     262        16107 ORCLCDB        SYS           INACTIVE   eduardo.legatti      SRVNOT001         sqlplus.exe
     265        28378 orclpdb1       ADAM          INACTIVE   eduardo.legatti      SRVNOT001         sqlplus.exe
     273         7253 orclpdb1       SYS           INACTIVE   eduardo.legatti      SRVNOT001         sqlplus.exe
     275        59715 ORCLCDB        SYS           ACTIVE     eduardo.legatti      SRVNOT001         sqlplus.exe


Ao conectar em um banco de dados PDB específico as views irão mostrar apenas informações do banco de dados PDB específico. 

C:\>sqlplus sys/manager@bdserver:1521/ORCLPDB1 as sysdba

SQL*Plus: Release 12.2.0.1.0 Production on Qui Mai 2 9:48:54 2019

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Conectado a:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production

SQL> select sys_context('USERENV','CON_NAME') from dual;

SYS_CONTEXT('USERENV','CON_NAME')
---------------------------------
ORCLPDB1

SQL> select file_name,file_id,tablespace_name,bytes,status from CDB_DATA_FILES;

FILE_NAME                                             FILE_ID TABLESPACE_NAME           BYTES STATUS
--------------------------------------------------- --------- ------------------ ------------ -----------
/opt/oracle/oradata/ORCLCDB/ORCLPDB1/system01.dbf           9 SYSTEM                283115520 AVAILABLE
/opt/oracle/oradata/ORCLCDB/ORCLPDB1/sysaux01.dbf          10 SYSAUX                387973120 AVAILABLE
/opt/oracle/oradata/ORCLCDB/ORCLPDB1/undotbs01.dbf         11 UNDOTBS1              104857600 AVAILABLE
/opt/oracle/oradata/ORCLCDB/ORCLPDB1/users01.dbf           12 USERS                   5242880 AVAILABLE


SQL> select sid,serial#,service_name,username,status,osuser,terminal,program
  2    from v$session
  3   where osuser='eduardo.legatti';

   SID     SERIAL# SERVICE_NAME    USERNAME     STATUS     OSUSER             TERMINAL      PROGRAM
------ ----------- --------------- ------------ ---------- ------------------ ------------- --------------
    38       9924 orclpdb1         SCOTT        INACTIVE   eduardo.legatti    SRVNOT001     sqlplus.exe
   265      28378 orclpdb1         ADAM         INACTIVE   eduardo.legatti    SRVNOT001     sqlplus.exe
   273       7253 orclpdb1         SYS          ACTIVE     eduardo.legatti    SRVNOT001     sqlplus.exe

sexta-feira, 26 de abril de 2019

Oracle 19c disponível para download nas plataformas Linux x86-64

Por Eduardo Legatti

Olá,

A Oracle disponibilizou para download a versão do Oracle 19c para as plataformas Linux x86-64.

terça-feira, 2 de abril de 2019

MySQL - Gerando arquivos CSV incluindo cabeçalho de colunas da tabela

Por Eduardo Legatti

Olá,

No artigo de Janeiro/2019 eu demonstrei como carregar um arquivo CSV para uma tabela no MySQL. Agora irei demonstrar como gerar um arquivo CSV a partir de uma tabela, incluindo também as colunas da tabela como cabeçalho.

mysql> select * from customer;
+------+------+
| id   | name |
+------+------+
|    1 | Joe  |
|    2 | Jack |
|    3 | Zack |
+------+------+
3 rows in set (0.00 sec)

Utilizarei o template abaixo para geração de um arquivo CSV.

SET @table_name = 'nome_da_tabela';
SET @table_schema = 'nome_do_banco_de_dados';
SET SESSION group_concat_max_len = 1000000;
SET @col_names = (
  SELECT GROUP_CONCAT(QUOTE(`column_name`)) AS columns
  FROM information_schema.columns
  WHERE table_schema = @table_schema
  AND table_name = @table_name);
SET @cols = CONCAT('(SELECT ', @col_names, ')');
SET @query = CONCAT('(SELECT * FROM ', @table_schema, '.', @table_name,
  ' INTO OUTFILE \'/tmp/nome_do_arquivo.csv\'
  FIELDS TERMINATED BY \',\' ENCLOSED BY \'"\')');
SET @sql = CONCAT(@cols, ' UNION ALL ', @query);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


Segue exemplo abaixo na qual irei gerar um arquivo CSV da tabela customer.

mysql> SET @table_name = 'customer';
Query OK, 0 rows affected (0.00 sec)

mysql> SET @table_schema = 'bd01';
Query OK, 0 rows affected (0.00 sec)

mysql> SET SESSION group_concat_max_len = 1000000;
Query OK, 0 rows affected (0.00 sec)

mysql> SET @col_names = (
    ->   SELECT GROUP_CONCAT(QUOTE(`column_name`)) AS columns
    ->   FROM information_schema.columns
    ->   WHERE table_schema = @table_schema
    ->   AND table_name = @table_name);
Query OK, 0 rows affected (0.00 sec)

mysql> SET @cols = CONCAT('(SELECT ', @col_names, ')');
Query OK, 0 rows affected (0.00 sec)

mysql> SET @query = CONCAT('(SELECT * FROM ', @table_schema, '.', @table_name,
    ->   ' INTO OUTFILE \'/tmp/customer.csv\'
    '>   FIELDS TERMINATED BY \',\' ENCLOSED BY \'"\')');
Query OK, 0 rows affected (0.00 sec)

mysql> SET @sql = CONCAT(@cols, ' UNION ALL ', @query);
Query OK, 0 rows affected (0.00 sec)

mysql> PREPARE stmt FROM @sql;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> EXECUTE stmt;
Query OK, 4 rows affected (0.00 sec)

mysql> DEALLOCATE PREPARE stmt;
Query OK, 0 rows affected (0.00 sec)

mysql> system cat /tmp/customer.csv;
"id","name"
"1","Joe"
"2","Jack"
"3","Zack"

Postagens populares