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


terça-feira, 3 de dezembro de 2019

Oracle - Wait event Library cache: mutex X

Por Eduardo Legatti

Olá,

Recentemente eu estava investigando um incidente na qual várias sessões no banco de dados simplesmente paravam em um wait específico e praticamente todo o banco de dados congelava e precisava ser reiniciado com "shutdown abort". Esse sintoma vinha ocorrendo com uma certa frequência em um ambiente específico na qual muitos sistemas compartilhavam os mesmos SQLs através de schemas distintos no banco de dados. Pelos gráficos abaixo identifiquei que os eventos estavam associados a wait class Concurrency, especificamente de waits Latch/mutex.






Para verificar qual objeto estava causando o evento de mutex (Tabela, índice, package, procure, SQL Cursor), identifiquei que sempre estava relacionado ao SQL_ID fnuugzjw1014k conforme demonstrado abaixo:

SQL> select a.cursors, a.sql_id,b.sql_text
  2  from
  3  (
  4    select count(*) as cursors, ssc.sql_id
  5    from v$sql_shared_cursor ssc
  6    group by ssc.sql_id
  7    order by cursors desc
  8  ) a,
  9  (select sa.sql_id, sa.sql_text, sa.parsing_schema_name from v$sqlarea sa) b
 10  where a.sql_id=b.sql_id
 11  and rownum<=5;

             CURSORS SQL_ID        SQL_TEXT
-------------------- ------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------
               88022 fnuugzjw1014k select * from (select D0.ain_code from t1 D0 where D0.ain_id = :1 and D0.ain_astcode = :2) where rownum <= :3
                6961 dsdny6fnhwjj7 select * from (select D0.gei_code from t2 D0, t3 D1 where D0.gei_gehcode = D1.geh_code and D1.geh_gelcode = :1) where rownum <= :3
                5134 5s3p206y7uxjp select count(1) as n from t2 D0, t3 D1 where D0.gei_gehcode = D1.geh_code and D1.geh_gelcode = :1 and D0.gei_pincode = :2
                3455 3am62hr7b3u75 select D0.elg_code from t0 D0 where D0.elg_eobcode = :1 and D0.elg_objpkvalue = :2 order by D0.elg_date
                3412 33f16tj5ukzzt select * from (select rownum sysRowNum, r.* from (select D0.gei_code from t2 D0, t3 D1 where D0.gei_gehcode = D1.geh_code) r) where sysRowNum between :3 and :4

O que me chamou a atenção é que as instruções SQL utilizam bind variables. Se tivessem usando literais e até entenderia o problema. Pelo que entendi, toda vez que o Oracle tenta utilizar o cursor na library cache para analisar o plano, o Oracle cria um lock (latch) no mesmo até terminar a análise da instrução. Como essa mesma instrução estava sendo chamada várias vezes de forma concorrente, criou-se uma fila muito grande. Talvez se o servidor tivesse mais memória (SGA), o problema não ocorreria com tanta frequência, mas é apenas uma suposição.

De qualquer forma estudando o assunto, descobri que a partir da versão Oracle 11g (11.2.0.2) foi criar uma procedure dbms_shared_pool.markhot que consegue marcar o objeto que está sofrendo latch/mutex de forma que o mesmo seja clonado várias vezes com SQL_ID diferentes de forma a diminuir a contenção em um único cursor. Desta forma executei o comando abaixo para achar o FULL_HASH_VALUE do SQL_ID fnuugzjw1014k.


SQL> SELECT hash_value,
  2         full_hash_value,
  3         namespace
  4    FROM v$db_object_cache
  5   WHERE name LIKE '%select * from (select D0.ain_code from t1 D0 where D0.ain_id = :1 and D0.ain_astcode = :2) where rownum <= :3%'
  6     AND rownum<=1;

          HASH_VALUE FULL_HASH_VALUE                  NAMESPACE
-------------------- -------------------------------- ---------
          2014315666 35e89608ac8d712eea6b4ffc78100492 SQL AREA

A partir do FULL_HASH_VALUE será possível marcar este objeto como "hot" através da procedure dbms_shared_pool.markhot de forma que o Oracle possa criar várias cópias desta instrução SQL na library cache com SQL_ID distintos a fim de diminuir essa contenção. Para isso, será necessário apenas executar o comando abaixo. No mais, vale a pena salientar que esse procedimento deverá ser executado toda vez que a instância for reiniciada.

SQL> exec dbms_shared_pool.markhot(hash =>'35e89608ac8d712eea6b4ffc78100492', namespace =>0);

sexta-feira, 1 de novembro de 2019

SQL Server - Como resetar a senha do usuário "sa" no Linux

Por Eduardo Legatti

Olá,

É comum precisarmos resetar a senha do usuário "sa" no SQL Server caso tenhamos esquecido a mesma. No SQL Server do Linux temos um jeito muito fácil de realizar este procedimento.

Supondo eu eu tenha esquecido a senha do usuário "sa":

[root@linux ~]# sqlcmd -S localhost -U sa -Psenha
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Login failed for user 'sa'..

Para definir uma nova senha, basta executarmos o procedimento set-sa-password conforme demonstrado a seguir.


[root@linux ~]# /opt/mssql/bin/mssql-conf set-sa-password
An instance of SQL Server is running. Please stop the SQL Server service
using the following command

    sudo systemctl stop mssql-server

Para realizar tal procedimento, a instância do SQL Server deverá sofrer shutdown caso a mesma esteja no ar.

[root@linux ~]# systemctl stop mssql-server

[root@linux ~]# /opt/mssql/bin/mssql-conf set-sa-password
Enter the SQL Server system administrator password: *********
Confirm the SQL Server system administrator password: *********
Configuring SQL Server...

ForceFlush is enabled for this instance.
ForceFlush feature is enabled for log durability.
The system administrator password has been changed.
Please run 'sudo systemctl start mssql-server' to start SQL Server.

Pronto. Após a definição da nova senha, poderemos reiniciar o SQL Server.

[root@linux ~]# systemctl start mssql-server

[root@linux ~]# systemctl status mssql-server
() mssql-server.service - Microsoft SQL Server Database Engine
   Loaded: loaded (/usr/lib/systemd/system/mssql-server.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2019-11-05 12:44:49 -03; 11s ago
     Docs: https://docs.microsoft.com/en-us/sql/linux
 Main PID: 3523 (sqlservr)
   CGroup: /system.slice/mssql-server.service
           |--3523 /opt/mssql/bin/sqlservr
           |--3526 /opt/mssql/bin/sqlservr

Nov 5 12:44:59 linux.local.net sqlservr[3523]: 2019-11-05 12:44:59.70 Server      InitializeExternalUserGroupSid failed. Implied authentication will be disabled.
Nov 5 12:44:59 linux.local.net sqlservr[3523]: 2019-11-05 12:44:59.70 Server      Implied authentication manager initialization failed. Implied authentication will be disabled.
Nov 5 12:44:59 linux.local.net sqlservr[3523]: 2019-11-05 12:44:59.75 Server      Successfully initialized the TLS configuration. Allowed TLS protocol versions are ['1.0 1.1 1.2']. Allowed TLS ciphers are ['ECDHE-ECDS...CDHE-ECDSA-AES12
Nov 5 12:44:59 linux.local.net sqlservr[3523]: 2019-11-05 12:44:59.87 Server      The maximum number of dedicated administrator connections for this instance is '1'
Nov 5 12:44:59 linux.local.net sqlservr[3523]: 2019-11-05 12:44:59.87 Server      Node configuration: node 0: CPU mask: 0x0000000000000003:0 Active CPU mask: 0x0000000000000003:0. This message provides a description o...ion is required.
Nov 5 12:44:59 linux.local.net sqlservr[3523]: 2019-11-05 12:44:59.90 Server      Using dynamic lock allocation.  Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node.  This is an informational m...ion is required.
Nov 5 12:44:59 linux.local.net sqlservr[3523]: 2019-11-05 12:44:59.94 Server      In-Memory OLTP initialized on lowend machine.
Nov 5 12:45:00 linux.local.net sqlservr[3523]: 2019-11-05 12:45:00.30 Server      Database Instant File Initialization: enabled. For security and performance considerations see the topic 'Database Instant File Initial...ion is required.
Nov 5 12:45:00 linux.local.net sqlservr[3523]: ForceFlush is enabled for this instance.
Nov 5 12:45:00 linux.local.net sqlservr[3523]: 2019-11-05 12:45:00.33 Server      Query Store settings initialized with enabled = 1,
Hint: Some lines were ellipsized, use -l to show in full.

Com a instância no ar, podemos testar novamente a conexão com a nova senha definida.

[root@linux ~]# sqlcmd -S localhost -U sa -Psenha
1> select @@version
2> GO

--------------------------------------------------------------------
Microsoft SQL Server 2017 (RTM-CU17) (KB4515579) - 14.0.3238.1 (X64)
        Sep 13 2019 15:49:57
        Copyright (C) 2017 Microsoft Corporation
        Enterprise Edition (64-bit) on Linux (CentOS Linux 7 (Core))

(1 rows affected)


sexta-feira, 4 de outubro de 2019

MySQL - Extraindo uma única tabela do dump de um banco de dados

Por Eduardo Legatti

Olá,

Geralmente utilizo uma técnica muito simples quando preciso extrair e importar apenas uma tabela que está dentro de um dump que foi gerado pelo mysqldump. A técnica consiste em gerar um arquivo SQL específico contendo apenas a tabela que eu quero. Como demonstrarei a seguir, utilizarei o comando grep do Linux para extrair uma tabela específica contida no arquivo bd01.sql que contém um dump de todas as tabelas e dados do banco de dados bd01.

[mysql@]# grep -n "Table structure" bd01.sql
24:-- Table structure for table `tb_usuarios`
52:-- Table structure for table `tb_historico`
77:-- Table structure for table `tb_adesao`
110:-- Table structure for table `tb_veiculos`
208:-- Table structure for table `tb_atendimento`
255:-- Table structure for table `tb_atendimento_itens`
310:-- Table structure for table `tb_bairros`
334:-- Table structure for table `tb_boletos`
369:-- Table structure for table `tb_carencia`
400:-- Table structure for table `tb_cliente_pj`
427:-- Table structure for table `tb_clientes`
512:-- Table structure for table `tb_parametros`
536:-- Table structure for table `tb_consultores`
582:-- Table structure for table `tb_corretores`
638:-- Table structure for table `tb_credenciados`
710:-- Table structure for table `tb_decl`
737:-- Table structure for table `tb_desbloqueio`
761:-- Table structure for table `tb_desbloqueio_cli`
786:-- Table structure for table `tb_pecas`
815:-- Table structure for table `tb_manutencao_controle`
847:-- Table structure for table `tb_excecao`
872:-- Table structure for table `tb_forma_pgto`
896:-- Table structure for table `tb_tarefas`
935:-- Table structure for table `tb_gastos`
996:-- Table structure for table `tb_liberacao`
1031:-- Table structure for table `tb_lote`
1056:-- Table structure for table `tb_plano_tabela`
1080:-- Table structure for table `tb_mensalidades`
1147:-- Table structure for table `tb_nfse`
1188:-- Table structure for table `tb_obs_cliente`
1222:-- Table structure for table `tb_pagamentos`
1307:-- Table structure for table `tb_parceiros`
1374:-- Table structure for table `tb_veiculos_controle`
1407:-- Table structure for table `tb_orcamentos`
1435:-- Table structure for table `tb_uf`
1464:-- Table structure for table `tb_carroceria_controle`
1497:-- Table structure for table `tb_plano_veiculo`
1534:-- Table structure for table `tb_plano_procedimento`
1564:-- Table structure for table `tb_planos`
1592:-- Table structure for table `tb_portes`
1621:-- Table structure for table `tb_precos`
1647:-- Table structure for table `tb_procedimentos`
1687:-- Table structure for table `tb_procedimentos_diario`
1714:-- Table structure for table `tb_procedimentos_mensal`
1741:-- Table structure for table `tb_profissional`
1770:-- Table structure for table `tb_oficinas`
1794:-- Table structure for table `tb_reajuste_mensalidade`
1826:-- Table structure for table `tb_reajuste_procedimentos`
1859:-- Table structure for table `tb_remessa`

Como demonstrado acima, o resultado do comando grep exibe exatamente o número que dará início a importação de cada tabela dentro do arquivo bd01.sql. Para eu importar apenas a tabela tb_planos, verifico que a mesma se inicia na linha 1564 e que termina uma linha antes de iniciar a próxima tabela que está na linha 1592. Portanto, irei gerar um novo arquivo contendo apenas a estrutura e dados da tabela da linha 1564 até 1591 conforme a seguir.

[mysql@]# sed -n '1564,1591 p' bd01.sql > tb_planos.sql

Pronto. Podemos ver abaixo que o arquivo tb_planos.sql contém os comandos necessários para importar a tabela e seus dados.

[mysql@]# cat tb_planos.sql
-- Table structure for table `tb_planos`
--

DROP TABLE IF EXISTS `tb_planos`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tb_planos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome_plano` varchar(50) COLLATE latin1_general_ci DEFAULT NULL,
  `valor` decimal(5,2) NOT NULL,
  `usuario` int(11) DEFAULT NULL,
  `data` date DEFAULT NULL,
  `flag_unico` char(1) COLLATE latin1_general_ci DEFAULT 'N',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `tb_planos`
--

LOCK TABLES `tb_planos` WRITE;
/*!40000 ALTER TABLE `tb_planos` DISABLE KEYS */;
INSERT INTO `tb_planos` VALUES
(1,'BASIC',10.15,NULL,NULL,'N'),
(2,'MEDIUM',15.20,NULL,NULL,'N'),
(3,'GOLD',25.99,NULL,NULL,'N'),
(4,'PLATINUM',35.45,NULL,NULL,'N'),
(5,'SOFT',22.10,NULL,NULL,'N'),
(6,'STANDARD',40.00,NULL,NULL,'N'),
(7,'SILVER',99.20,NULL,NULL,'N'),
(8,'MASTER',113.40,NULL,NULL,'N'),
(9,'BLUE',5.15,NULL,NULL,'N'),
(10,'ESSENTIAL',20.15,NULL,NULL,'N'),
(11,'MAX',50.00,NULL,NULL,'N'),
(100,'DIAMOND',60.00,NULL,'2019-11-01','N');
/*!40000 ALTER TABLE `tb_planos` ENABLE KEYS */;
UNLOCK TABLES;

--

Para realizar a importação da tabela para o meu banco de dados, irei realizar a operação a seguir.

[mysql@]$ mysql -uroot -psenha -D bd01 < tb_planos.sql

Pronto. Após a importação podemos ver abaixo que a tabela foi carregada para dentro do banco de dados bd01.

[mysql@]$ mysql -uroot -psenha

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4911066
Server version: 5.6.13 MySQL Community Server (GPL)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use bd01

Database changed

mysql> select * from tb_planos;
+-----+------------+--------+---------+------------+------------+
| id  | nome_plano | valor  | usuario | data       | flag_unico |
+-----+------------+--------+---------+------------+------------+
|   1 | BASIC      |  10.15 |    NULL | NULL       | N          |
|   2 | MEDIUM     |  15.20 |    NULL | NULL       | N          |
|   3 | GOLD       |  25.99 |    NULL | NULL       | N          |
|   4 | PLATINUM   |  35.45 |    NULL | NULL       | N          |
|   5 | SOFT       |  22.10 |    NULL | NULL       | N          |
|   6 | STANDARD   |  40.00 |    NULL | NULL       | N          |
|   7 | SILVER     |  99.20 |    NULL | NULL       | N          |
|   8 | MASTER     | 113.40 |    NULL | NULL       | N          |
|   9 | BLUE       |   5.15 |    NULL | NULL       | N          |
|  10 | ESSENTIAL  |  20.15 |    NULL | NULL       | N          |
|  11 | MAX        |  50.00 |    NULL | NULL       | N          |
| 100 | DIAMOND    |  60.00 |    NULL | 2019-11-01 | N          |
+-----+------------+--------+---------+------------+------------+
12 rows in set (0.00 sec)

sexta-feira, 6 de setembro de 2019

SQL Server - Restore de backup trará os dados como eles estavam no início ou no término do backup?

Por Eduardo Legatti

Olá,

No SQL Server, suponha que um backup FULL do banco de dados XYZ se inicia às 00:00 e termina às 04:00. Vale a pena salientar que o banco de dados está aberto e recebendo transações normalmente durante a execução do backup. Agora vem a pergunta: Se precisarmos realizar uma restauração desse backup, os dados do banco de dados XYZ serão restaurados como eles estavam às 00:00 ou como eles estavam às 04:00?
 
Fazendo uma comparação com outros bancos de dados teremos o seguinte:
  • Oracle RMAN: O backup feito devidamente em conjunto com os archivelogs restaurará o banco de dados como ele estava ás 04:00.
  • Oracle Datapummp: Se for utilizado a cláusula flashback_time=systimestamp do comando expdp, o dump será consistente a partir do início do backup, ou seja, o dump restaurado trará os dados como eles estavam ás 00:00.
  • MySQL: Se for utilizado a cláusula --single-transaction do comando mysqldump, os bancos dedados não serão lockados durante o backup e o dump será consistente a partir do início do backup, ou seja, o dump restaurado trará os dados como eles estavam ás 00:00.
  • MongoDB: Se for utilizado a cláusula --oplog do comando mongodump, ao final do backup, será realizado um backup também da collection oplog que poderá ser utilizada para aplicar as transações realizadas durante o backup e restaurar os dados como eles estavam ás 04:00. Caso seja utilizado a tecnologia de snapshot como por exemplo no disco EBS da AWS, o snapshot restaurado trará os dados como eles estavam ás 00:00. Vale a pena salientar que o MongoDB precisaria ter sido inicializado com a opção --journal.
E no caso do SQL Server, a restauração do backup trará os dados como eles estavam ás 04:00. Algumas evidências como esta e essa, comprovam esta afirmação.      
               
"A full database backup provides a complete copy of the database and provides a single point-in-time to which the database can be restored. Even though it may take many hours for the backup process to run, you can still only restore the backup to a single point (effectively at the end of the backup, but I'll discuss exactly what that point is later in this article). A full backup does not allow recovery to any point in time while the backup was running. Another misconception about full backups is that they only contain data. Both full backups and differential backups also contain some transaction log records so that the restored component (database, file, or filegroup) can be made transactionally consistent."
               
"Consider an example transaction that inserts a record into a table with a single nonclustered index. The pages of the table and index are spread through the data file. The transaction is split into two parts internally: a record insertion into a data page in the table and then the insertion of the required record in an index page in the nonclustered index. If the backup process just happens to read the nonclustered index page before the record insertion, but reads the table data page after the record insertion, then the database represented by just the data in the backup is transactionally inconsistent. This is where the transaction log comes into play. By also including some transaction log records in the backup, recovery can be run on the restored copy of the database, making it transactionally consistent. For this example transaction, depending on when it commits, the recovery part of restore may roll it forward (meaning it will appear as committed in the restored copy of the database) or roll it back (meaning it will not appear at all in the restored copy of the database). In either case, transactional consistency is maintained, which is crucial."
 
 

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';

Postagens populares