Foi um grande prazer ter participado do Data Secrets #38.
Quem tiver a oportunidade de assistir segue o vídeo:
Maratona do SQLPASS 2011
Foi um grande prazer ter participado do Data Secrets #38.
Quem tiver a oportunidade de assistir segue o vídeo:
Caso você contrate uma AMI com SQL e precise da mídia de instalação do SQL para qualquer atividade, na unidade C:\ existe um diretório chamado “SQLServerSetup” com os binários para a instalação do SQL Server.
Isso ajuda caso precise trocar o Collation da instância, adicionar feature, reinstalar usando uma instância, adicionar uma instância, etc..
A instalação padrão vem na instância default, collation SQL_Latin1_General_CP1_CI_AS, tempdb nas configurações NNF, sem IFI, basicamente uma instalação NNF.
Aí vem outra pergunta, por que pegar uma imagem da AWS com SQL? por que não usar um RDS?
Bom, a resposta disso é mais com você do que comigo, porque tudo vai depender da necessidade.
AMI – EC2 com SQL Instalado
RDS
Vou tratar da comparação entre uma AMI e um RDS em outro post.
Como DBA´s estamos sujeitos a jobs, alertas, sistemas, coisas do além, gerentes, desenvolvedores, intervenções místicas, etc. executando ações no banco de dados.
Não da pra ficar olhando de perto o ambiente a todo o momento analisando cada ação, monitorando tudo o que ocorre, se preparando para o pior.
Sendo um bom DBA, você deve ter um monte de Jobs, Alertas, Operadores, Sistemas de Monitoração, aquele estagiário sendo escalpelado, entre outras formas de monitorar seus bancos, a ideia aqui é trazer mais uma opção para atazanar sua vida monótona.
Vamos a receita do desastre,,, Para isso vamos precisar:
Vamos começar,,,
Conta do Telegram
Instale o aplicativo do Telegram no seu Windows
Crie um Bot
Configure o Bot
Crie um canal e adicione esse Bot como administrador a um canal
Mande uma mensagem para esse canal para criar um ID
Acesse uma URL do Telegram com a chave do BOT para pegar o ID do canal
{"ok":true,"result":[{"update_id":129494597, "message":{"message_id":3,"from":{"id":XXXXXX,"is_bot":false,"first_name":"Ricardo","last_name":"Leka"},"chat":{"id":XXXXXX,"first_name":"Ricardo","last_name":"Leka","type":"private"},"date":1614187816,"text":"/start","entities":[{"offset":0,"length":6,"type":"bot_command"}]}},{"update_id":129494598, "message":{"message_id":4,"from":{"id":XXXXXX,"is_bot":false,"first_name":"Ricardo","last_name":"Leka","language_code":"pt-br"},"chat":{"id":XXXXXX,"first_name":"Ricardo","last_name":"Leka","type":"private"},"date":1614187832,"text":"/getchatid","entities":[{"offset":0,"length":10,"type":"bot_command"}]}},{"update_id":129494599, "channel_post":{"message_id":2,"sender_chat":{"id":-XXXX,"title":"MC1_Notify","type":"channel"} ,"chat":{"id":-XXXX,"title":"Nome_Do_Canal","type":"channel"} ,"date":1614187878,"text":"teste"}}]}
O que interessa para nós é um desses últimos “id” que estão com um símbolo de menos na frente “id”:-XXXX
Crie uma função no Powershell
<#
.Synopsis
Sends Telegram text message via Bot API
.DESCRIPTION
Uses Telegram Bot API to send text message to specified Telegram chat. Several options can be specified to adjust message parameters.
.EXAMPLE
$bot = "#########:xxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx"
$chat = "-#########"
Send-TelegramTextMessage -BotToken $bot -ChatID $chat -Message "Hello"
.EXAMPLE
$bot = "#########:xxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx"
$chat = "-#########"
Send-TelegramTextMessage `
-BotToken $bot `
-ChatID $chat `
-Message "Hello *chat* _channel_, check out this link: [TechThoughts](http://techthoughts.info/)" `
-ParseMode Markdown `
-Preview $false `
-Notification $false `
-Verbose
.PARAMETER BotToken
Use this token to access the HTTP API
.PARAMETER ChatID
Unique identifier for the target chat
.PARAMETER Message
Text of the message to be sent
.PARAMETER ParseMode
Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. Default is Markdown.
.PARAMETER Preview
Disables link previews for links in this message. Default is $false
.PARAMETER Notification
Sends the message silently. Users will receive a notification with no sound. Default is $false
.OUTPUTS
System.Boolean
.NOTES
Author: Jake Morrison - @jakemorrison - http://techthoughts.info/
This works with PowerShell Versions 5.1, 6.0, 6.1
For a description of the Bot API, see this page: https://core.telegram.org/bots/api
How do I get my channel ID? Use the getidsbot https://telegram.me/getidsbot
How do I set up a bot and get a token? Use the BotFather https://t.me/BotFather
.COMPONENT
PoshGram - https://github.com/techthoughts2/PoshGram
.FUNCTIONALITY
https://core.telegram.org/bots/api#sendmessage
Parameters Type Required Description
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel (in the format @channelusername)
text String Yes Text of the message to be sent
parse_mode String Optional Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message.
disable_web_page_preview Boolean Optional Disables link previews for links in this message
disable_notification Boolean Optional Sends the message silently. Users will receive a notification with no sound.
reply_to_message_id Integer Optional If the message is a reply, ID of the original message
#>
function Send-TelegramTextMessage {
[CmdletBinding()]
Param
(
[Parameter(Mandatory = $true,
HelpMessage = '#########:xxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx')]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[string]$BotToken, #you could set a token right here if you wanted
[Parameter(Mandatory = $true,
HelpMessage = '-#########')]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[string]$ChatID, #you could set a Chat ID right here if you wanted
[Parameter(Mandatory = $true,
HelpMessage = 'Text of the message to be sent')]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[string]$Message,
[Parameter(Mandatory = $false,
HelpMessage = 'HTML vs Markdown for message formatting')]
[ValidateSet("Markdown", "HTML")]
[string]$ParseMode = "Markdown", #set to Markdown by default
[Parameter(Mandatory = $false,
HelpMessage = 'Disables link previews')]
[bool]$Preview = $false, #set to false by default
[Parameter(Mandatory = $false,
HelpMessage = 'Sends the message silently')]
[bool]$Notification = $false #set to false by default
)
#------------------------------------------------------------------------
$results = $true #assume the best
#------------------------------------------------------------------------
$payload = @{
"chat_id" = $ChatID;
"text" = $Message
"parse_mode" = $ParseMode;
"disable_web_page_preview" = $Preview;
"disable_notification" = $Notification
}#payload
#------------------------------------------------------------------------
try {
Write-Verbose -Message "Sending message..."
$eval = Invoke-RestMethod `
-Uri ("https://api.telegram.org/bot{0}/sendMessage" -f $BotToken) `
-Method Post `
-ContentType "application/json" `
-Body (ConvertTo-Json -Compress -InputObject $payload) `
-ErrorAction Stop
if (!($eval.ok -eq "True")) {
Write-Warning -Message "Message did not send successfully"
$results = $false
}#if_StatusDescription
}#try_messageSend
catch {
Write-Warning "An error was encountered sending the Telegram message:"
Write-Error $_
$results = $false
}#catch_messageSend
return $results
#------------------------------------------------------------------------
}#function_Send-TelegramTextMessage
Declare a variável com o nome do Bot e a chave
$bot = "token"
$chat = "-ID_do_chat"
Mande uma mensagem
$bot = "token"
$chat = "-ID_do_chat"
Send-TelegramTextMessage -BotToken $bot -ChatID $chat -Message "CASA CAIU"
Com isso agora temos um powershell que acessa uma API do Telegram e manda mensagem, junta isso em um JOB que é acionado por um alerta e vc tem o SQL ou outro sistema de monitoração mandando mensagens para seu celular.
Essa apresentação foi feita em setembro/2019 no evento SQL Roots.
Me desculpem por uma ou outra gafe, não é sempre que tenho tanto público nas minas apresentações…
Todos sabemos que o SQL é um consumidor de memória frenético, quanto mais memória disponível mais memória ele vai reservar para ele.
O que é um desenho “by default”, ele sempre fará isso afinal de contas ele precisa alocar as páginas de dados do seu banco em algum lugar.
Para resolver todos os seus problemas, existe uma forma de liberar toda a memória disponível de uma só vez do seu servidor e não é parando o serviço do SQL.
Para isso, você vai precisar o Visual Studio instalado, vamos criar um novo projeto dele…
Importante! Abra o Visual Studio como administrador !
Escreva o nome que quiser para o app
Copie e cole o código abaixo no projeto:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
public class CriticalProcess
{
[DllImport("ntdll.dll", SetLastError = true)]
private static extern int NtSetInformationProcess(IntPtr hProcess, int processInformationClass, ref int processInformation, int processInformationLength);
static void Main(string[] args)
{
int isCritical = 1; // queremos que ele seja um processo crítico
int BreakOnTermination = 0x1D; // valor para BreakOnTermination (flag)
Process.EnterDebugMode(); //acquire Debug Privileges
// configurando o BreakOnTermination = 1 para o processo ativo
NtSetInformationProcess(Process.GetCurrentProcess().Handle, BreakOnTermination, ref isCritical, sizeof(int));
}
}
Se tudo ocorrer como esperado, dependendo da quantidade de memória do seu servidor isso pode demorar de alguns segundos a algumas horas.
Por mais que tenhamos criado uma aplicação de linha de comando a primeira parte do processo é bem gráfica e todos já tiveram o grande prazer de conhecer:
Ele vai gerar um DUMP de toda a memória para o arquivo de paginação e depois que a maquina reiniciar ele vai copiar esse arquivo de paginação para um arquivo chamado memory.dump
É só isso,,, execução e queda,,,
Agora falando sério: NUNCA !!!! JAMAIS !!!!! Simplesmente pegue o código de qualquer coisa que você encontra na internet e saia executando sem antes entender o que ele faz.
Esse exemplo é bem ridículo, mas imagina um script que você leu o por alto achando que vai resolver todos os seus problemas de backup, ou de fragmentação de índice e descobre que no meio tem um sp_msforeach_table com um sp_msforeach_db que trunca as tabelas, ou pior, alguém cria uma chave de criptografia e habilita TDE nas suas bases e depois força a remoção da chave,,,, a culpa é tão e somente sua! Você é o DBA é sua responsabilidade preservar os dados.
Tenha discernimento com o que você copia da internet e de onde copia essas informações.
SEMPRE LEIA e NUNCA EXECUTE DIRETAMENTE EM PRODUÇÃO !!!
Bah! Tchê! Vamos ver se eles realmente fazem um churrasco melhor que o paulista ou é só intriga da oposição.
No dia 23/06/2018 Haverá um novo evento do SQL Saturday, desta vez em Caxias do Sul/RS.
É com um prazer inenarrável em estar presente para mais um evento da comunidade e ainda mais como palestrante.
Só tem uma coisa mais legal que a minha palestra,,, o café,,, esqueça as outras, mantenha o foco,,,
Vamos conversar sobre formas “erradas” de como fazer as coisas no SQL Server.
Todos já devem estar sabendo dessa “novidade”
O link para o blog: https://blogs.microsoft.com/blog/2016/03/07/announcing-sql-server-on-linux
Se você quiser se cadastrar para “testar” o preview o link é: https://www.microsoft.com/en-us/server-cloud/sql-server-on-linux.aspx
Honestamente não sei se isso vai ser bom ou ruim,,, vejo muitas aplicações interessantes, mas também vejo muita dor de cabeça pela frente…
pode ser que eles usem isso para acabar com a versão Enterprise, forçando as empresas a usarem a nuvem caso queiram HA ou features avançadas? ou é uma forma de baratear o produto já que “em teoria” existem versões gratuitas de Linux? ainda mais pensando que ele vai ser distribuído por Docker,,,
Bom,,, de qualquer forma, mais uma coisa para relembrar,,, como faz tempo que não trabalho com linux… 🙁
E aí pessoal !!!
O conteúdo da palesta sobre backup parcial e restauração parcial e online está disponível.
O Slide está disponível para download ou visualização abaixo
[slideshare id=40045338&doc=sqlsaturday325-141008203837-conversion-gate01]
O link para o download dos scripts e da apresentação está aqui.
Quero, novamente, agradecer pela oportunidade de ter palestrado no evento e agradecer a todos que tiveram paciência de assistir minha palestra.
O link para o acesso a agenda do evento é:
https://www.sqlsaturday.com/469/schedule.aspx
A ideia é a evolução contínua, gostaria que vocês avaliassem como foi a apresentação:
[polldaddy poll=9196565]
Algum tempo atras fiz um post sobre Event Notification para monitorar DeadLock o que funciona muito bem,,,
Com um pouco de modificação o mesmo código pode ser utilizado para muitas outras coisas,,, por exemplo: limitar acesso a uma instância bloqueando a conexão do usuário…
Aí você pensa: “posso fazer isso por trigger, por que fazer diferente?”
Eu respondo,,, se você trabalha em ambientes com alto volume de conexões, ou ambientes que as vezes sofrem com falta de recursos como cpu ou memória sabe que a trigger pode ser uma pedra no sapato,,, ao invés de respeitar o filtro e impedir apenas algumas conexões ela bloqueia tudo e todos…
Já com o Event Notification é o contrário,,, no pior cenário ele só para de funcionar…
Os dois pontos que vejo como mais complicados são:
com o código abaixo consegui chegar a 20.000 tentativas de conexão simultâneas e nenhuma conseguiu conectar,,,
--apenas para constatar quais tipos de eventos podemos tratar... o que queremos eh o audit_login select * from sys.event_notification_event_types with (nolock) where type_name like '%login%' use master go alter database BASE_DE_ADMINISTRACAO_DO_DBA set enable_broker with rollback immediate go alter database BASE_DE_ADMINISTRACAO_DO_DBA set TRUSTWORTHY on go use BASE_DE_ADMINISTRACAO_DO_DBA go CREATE QUEUE [Login_Killer_Queue] GO CREATE SERVICE [Login_Killer_Service] AUTHORIZATION [dbo] ON QUEUE [dbo].[Login_Killer_QUEUE] ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]) GO CREATE ROUTE Login_Killer_Route WITH SERVICE_NAME = 'Login_Killer_Service', ADDRESS = 'LOCAL'; GO DECLARE @AuditServiceBrokerGuid [uniqueidentifier] ,@SQL [varchar](max); -- Pega o service broker guid da base de dados SELECT @AuditServiceBrokerGuid = [service_broker_guid] FROM [master].[sys].[databases] WHERE [name] = 'ADM_BDADOS' -- Cria e executa o SQL dinamico para criar o objeto do evento de notificacao SET @SQL = 'IF EXISTS (SELECT * FROM sys.server_event_notifications WHERE name = ''Login_Killer_Notification'') DROP EVENT NOTIFICATION Login_Killer_EventNotification ON SERVER CREATE EVENT NOTIFICATION Login_Killer_EventNotification ON SERVER WITH fan_in FOR AUDIT_LOGIN TO SERVICE ''Login_Killer_Service'', ''' + CAST(@AuditServiceBrokerGuid AS [varchar](50)) + ''';' EXEC (@SQL) GO SELECT * FROM [sys].[server_event_notifications] select * from sys.server_event_session_actions with (nolock) CREATE TABLE [dbo].[DBA_FailedConnectionTracker]( [host_name] [varchar](128) NOT NULL, [login_name] [varchar](128) NOT NULL, [spidu] int, [FailedLoginData] XML ) ; CREATE PROCEDURE dbo.spc_DBA_FailedConnectionTracker AS BEGIN SET NOCOUNT ON; -- looping infinito WHILE (1 = 1) BEGIN DECLARE @messageBody VARBINARY(MAX); DECLARE @messageTypeName NVARCHAR(256); WAITFOR ( RECEIVE TOP(1) @messageTypeName = message_type_name, @messageBody = message_body FROM [Login_Killer_Queue] ), TIMEOUT 500 -- se nao houver mensagens saia IF @@ROWCOUNT = 0 BEGIN BREAK ; END ; -- se o tipo da mensagem for um EventNotification para a fila atual IF (@messageTypeName = 'http://schemas.microsoft.com/SQL/Notifications/EventNotification') BEGIN DECLARE @XML XML, @host_name varchar(128) , @login_name varchar(128) , @SPID varchar(5); SELECT @XML=CONVERT(XML,@messageBody) ,@host_name = '' ,@login_name = '' ,@SPID =''; -- Pega o SPID e as informacoes de login SELECT @SPID = @XML.value('(/EVENT_INSTANCE/SPID)[1]', 'varchar(5)') , @host_name = @XML.value('(/EVENT_INSTANCE/HostName)[1]', 'NVARCHAR(128)') , @login_name = @XML.value('(/EVENT_INSTANCE/LoginName)[1]', 'NVARCHAR(128)') ; DECLARE @kill varchar(8000) = ''; --Caso o hostname e o login entrem no criterio abaixo if ((@host_name like 'SPO%') and (@login_name like '%_user')) SELECT @kill = @kill + 'kill ' + @SPID + ';' EXEC(@kill); --/* esta parte pode ser comentada para não gerar "log" do kill if ((@host_name like 'SPO%') and (@login_name like '%_user')) INSERT INTO [dbo].[DBA_FailedConnectionTracker] ([host_name], [login_name], FailedLoginData,spidu) values ( @host_name, @login_name,@XML,@SPID); --*/ END; END; END; --inicia a matanca ALTER QUEUE [dbo].[Login_Killer_Queue] WITH STATUS = on ,ACTIVATION (PROCEDURE_NAME = [spc_DBA_FailedConnectionTracker] ,STATUS = ON ,MAX_QUEUE_READERS = 1 ,EXECUTE AS OWNER) GO
Esse código mostra o tamanho ocupado por cada pacote de SSIS carregado dentro do MSDB.
Algumas vezes o MSDB começa a ganhar proporções ocupadas que apenas a limpeza de rotina não dá conta e o pessoal esquece que os pacotes também ocupam espaço…
with ChildFolders as ( select PARENT.parentfolderid, PARENT.folderid, PARENT.foldername, cast('' as sysname) as RootFolder, cast(PARENT.foldername as varchar(max)) as FullPath, 0 as Lvl from msdb.dbo.sysssispackagefolders PARENT where PARENT.parentfolderid is null UNION ALL select CHILD.parentfolderid, CHILD.folderid, CHILD.foldername, case ChildFolders.Lvl when 0 then CHILD.foldername else ChildFolders.RootFolder end as RootFolder, cast(ChildFolders.FullPath + '/' + CHILD.foldername as varchar(max)) as FullPath, ChildFolders.Lvl + 1 as Lvl from msdb.dbo.sysssispackagefolders CHILD inner join ChildFolders on ChildFolders.folderid = CHILD.parentfolderid ) select F.RootFolder, F.FullPath, P.name as PackageName, P.description as PackageDescription, P.packageformat, P.packagetype, P.vermajor, P.verminor, P.verbuild, P.vercomments, cast(cast(P.packagedata as varbinary(max)) as xml) as PackageData,datalength(P.packagedata)/1024 AS SpaeceusedKB from ChildFolders F inner join msdb.dbo.sysssispackages P on P.folderid = F.folderid order by F.FullPath asc, P.name asc;