Quantcast
Channel: MSDN Blogs
Viewing all 12366 articles
Browse latest View live

DBCC INDEXDEFRAG

$
0
0

Esse é mais um artigo da série “Saga da otimização com comandos antigos”

No último artigo, falei sobre a forma mais rápida de executar um scan. Nesse artigo vou falar sobre o INDEX SCAN.

Seria ele mais rápido que o HEAP SCAN do artigo anterior?

Vamos começar colocando ordem na heap!

Heap é Desorganizada

Heap scan é uma técnica muito rápida porque favorece o uso das operações de read-ahead.

Entretanto, imagine o que acontece quando sabemos que a query retorna apenas um registro:

SELECT * FROM produtos WHERE id = 1234

Isso poderia ser reescrito assim:

SELECT TOP(1) * FROM produtos WHERE id = 1234

A primeira query realiza a leitura da tabela inteira para retornar todos os produtos com ID = 1234 e o comando faz a leitura de todos os registros para se certificar que, de fato, existe apenas um registro. Por outro lado, a segunda query usa TOP(1) para notificar que é necessário apenas um registro. Assim, o comando realiza o scan de tabela e finaliza logo que encontrar o primeiro registro. Estatisticamente, podemos dizer que a segunda query executa na metade do tempo da primeira.

Concluímos que a heap é um conjunto desorganizado de página de dados, ou seja, a única forma de acesso é através do Heap Scan. Uma das formas de tornar o acesso mais rápido é usando o TOP(n) para encerrar o scan o mais rápido possível.

Heap Organizada

Existe uma forma de tornar a Heap mais eficiente: ordenando os registros nas páginas de dados.

Heap: dados desorganizados – será que existe o ID = 1234? onde?

image

Heap Organizada: é fácil de encontrar o ID = 1234.

image

Tornar a heap organizada é fácil! Basta transformar a Heap em uma Tabela com Clustered Index.

Clustered Index

Clustered Index. Sim, esse é o nome de uma Heap Organizada.

Infelizmente não gosto desse nome porque muita gente considera o Clustered Index mais como índice ao invés de Tabela. Índice é uma estrutura para ajudar o desempenho do banco de dados e você pode criar vários na mesma tabela (10, 20, 30..). Entretanto, o Clustered Index é especial e você só pode criar um porque ele é a própria tabela! Não há como organizar a Heap de duas formas diferentes ao mesmo tempo.

Clustered index organiza as páginas da tabela. A forma mais fácil de enxergar isso é através do comando DBCC IND. Vamos investigar o index_id = 1, que corresponde ao índice clustered.

image

A página 1:549 aponta para a próxima página next_id = 1:548 e anterior prev_id = 1:550. Podemos investigar a página anterior 1:550, que aponta para as páginas 1:549 e 1:551. Aqui é possível ver que a primeira página da tabela é a 1:557, pois ela não possui um ponteiro para a página anterior.

 

Desorganizando o Clustered Index

Sempre que realizamos uma operação de Table Scan em uma tabela com índice clustered, dizemos que:

Table Scan = Clustered Index Scan

Em geral o desempenho do Clustered index scan é comparável com o Heap scan. O motivo é que as páginas estão organizadas e fica fácil de encontrar as informações. Entretanto, existe uma forma de bagunçar o local onde os dados estão fisicamente armazenados: basta fragmentar a tabela e começar a distribuir os dados em diferentes páginas.

Primeiro vamos criar uma tabela e adicionar a ordenação com índice clustered:

image

Em seguida, adicionamos os produtos sem uma ordem específica.

image

O resultado do DBCC IND mostra claramente que as páginas anteriores e posteriores estão completamente fora de ordem.

image

Como as páginas estão desordenadas, Clustered Index Scan não consegue executar transformar as operações de leitura em operações de read-ahead.

Isso torna o acesso ao índice mais lento. Como resolver? Basta desfragmentar o índice. No passado, usava-se bastante o comando DBCC INDEXDEFRAG. Hoje não há motivo para usar o INDEXDEFRAG, pois se tornou obsoleto. Ao invés disso, procure usar a sintaxe do ALTER INDEX REORGANIZE que possui mais flexibilidade e suporte a partições.

ALTER INDEX nome_indice ON produtos REORGANIZE

image

Pronto! Agora o clustered index scan é praticamente tão rápido quanto heap scan e deixa a tabela organizada.

Conclusão

É recomendado organizar os dados da tabela usando um índice clustered.

Nesse artigo comentei que o desempenho Clustered Index scan é igual ao Heap scan ou inferior (quando o índice se encontra fragmentado). Portanto, criar um índice clustered sem qualquer estudo pode causar degradação de performance.

Criar um clustered index incorreto é pior do que não te-lo.

No próximo artigo vamos explorar um pouco mais a estrutura do índice, também conhecida por BTree+.


Microsoft Account

$
0
0

El primer componente a utilizar en mi reto es un Microsoft Account, anteriormente conocido como Passport o simplemente una cuenta de “Hotmail” o “Outlook”. Este es uno de los recursos más importantes a la hora de tomar ventaja de la plataforma Microsoft, muchos piensan que simplemente se trata de una cuenta de correo pero no es así, este elemento brinda acceso a muchos otros servicios, el rol principal de un Microsot Account es brindar una identidad a la cual se pueden asociar servicios y beneficios, el correo asociado es solamente una conveniencia (más adelante escribiré un poco sobre las cosas interesantes que pueden hacerse con Outlook.com)

Para acceder a los beneficios es necesario ir a http://login.live.com; si ya se tiene una cuenta basta con ingresar las credenciales, si no se tiene es posible crear una partir de esta página.

Sign In

Luego deben proporcionarse algunos datos para establecer la identidad, es importante mencionar que puede utilizarse una dirección de correo existente, no necesariamente debe ser Outlook o Hotmail, si utilizas por ejemplo una dirección de correo de GMail, puedes convertirla en tu Microsoft Account sin ningún problema.

Create an Account

Una vez finalizados estos pasos nuestra cuenta de Microsoft estará lista y podremos empezar a hacer uso de muchas características, yo aproveché para crear una nueva cuenta en Outlook.com que me brindará acceso adicional a características de productividad como Office Online y OneDrive.

Outlook

Mi primer paso está terminado, es hora de empezar a instalar herramientas y conectar servicios!

Using Clone, Export and Import an existing release definition for TFS2015 Update2

$
0
0

Summary:- A ReleaseManagement extension for Cloning, Importing and Exporting an existing release definition is released in the VisualStudio marketplace at https://marketplace.visualstudio.com/items?itemName=ms-devlabs.rm-clone-rd . But as it uses some improvement done post release of TFS2015U2 hence it doesn't allow to be installed for TFS2015U2. I have tried to write another extension with slight variation of experience (explained below).

How it's different from one released to VisualStudio marketplace :- Extension published at VisualStudio marketplace open the release definition to be saved after clicking the clone (from context menu) or import (from toolbar). Where as extension for TFS2015U2 makes direct REST call and creates a clone or import of an existing release definition. Following are TFS2015U2 behaviour difference:-

 - Environment owner will be same as original release definition

 - In case of Import, Approver needs to be updated

Code is sharedhttps://github.com/openalm/vsts-rm-extensions/tree/master/rd-export-import-clone-TFS2015U2

How to Install it for TFS2015U2 :-

Step1:- Download above mentioned repo which contains already build ms-devlabs.rm-import-export-0.0.1.vsix

Step2: open http://<tfsserverurl>/tfs/_gallery/manage

Step3:- Click on 'Upload new extension'

Step4: Give path to ms-devlabs.rm-import-export-0.0.1.vsix (as downloaded in step#1 above)

Step5: Click on the 'Install' button for the referred extension

Step6:- You should be able to see the Clone, Export in the release definition context menu and Import the new definition toolbar.

Step7: Done

Writing a ReleaseManagement extension for cloning an existing release definition

$
0
0

Code shared :- https://github.com/openalm/vsts-rm-extensions/tree/master/rd-export-import-clone-TFS2015U2

How to make Changes:-

Step1: Clone the repository using the link https://github.com/openalm/vsts-rm-extensions.git

Step2: Open a command prompt and go till folder 'rd-export-import-clone-TFS2015U2'

Step3: Run 'bower install' [ pre-requsite for running 'bower' can be referred https://github.com/Microsoft/vsts-extension-samples] which will download 1.95.2 version of VSS.SDK.js

Step4: Make your changes

Step5:  Run 'tfx extension create' to generate .vsix package in the current directory.  [Refer 'Try the extension in Visual Studio Team Services' section https://github.com/Microsoft/vsts-extension-samples]

Step6: Done!!!!

How to add 'Clone' as contextmenu item for ReleaseDefinition

[A generic how to add item in context menu is explained https://www.visualstudio.com/en-us/integrate/extensions/develop/add-action, below steps will explain similarly in context of ReleaseManagement]

Changes required  in vss-extension.json [ Refer above shared code]

Step1: Add below as "scopes" in vss-extension.json  [Read more about ReleaseManagement scopes under 'Scopes' section in https://www.visualstudio.com/en-us/integrate/extensions/develop/manifest

           "scopes": ["vso.release_execute"]

Step2: As we wanted to add one more item in the release definition context menu hence we will add one contribution (as below) in the vss-extension.json targeting "ms.vss-releaseManagement-web.release-definition-explorer-toolbar-menu" [ to learn more release management contribution point refer https://www.visualstudio.com/integrate/extensions/reference/targets/overview ]

      {
            "id": "importDefinitionToolbarMenu",
            "type": "ms.vss-web.action",
            "description": "Import definition(s) menu",
            "targets": [
                "ms.vss-releaseManagement-web.release-definition-explorer-toolbar-menu"
            ],
            "properties": {
                "title": "Import release definition",
                "icon": "images/icon-import-16.png",
                "group": "actions",
                "uri": "main.html"
            }
        }

Changes required  in main.js [Refer method cloneDefinitionContextMenu() in above shared code ]

Step1:- Create a rmClient using

var rmClient = VSS_Service.getCollectionClient(RM_WebApi.ReleaseHttpClient);

Step2: Make a getReleaseDefinition() call to get the definition object for the given id

    rmClient.getReleaseDefinition(vsoContext.project.id,sourceItemContext.definition.id)

Step3: Update the definition name

   definition.name = newDefinitionName;

Step4: Create a new definition using updated definition object in Step#3 above

   rmClient.createReleaseDefinition(definition, vsoContext.project.id)

Step5: Refresh the UI to show the newly created definition

    sourceItemContext.view.refresh();

Step6: Done!!!!

 

Complete code for quick reference :-

var cloneDefinitionContextMenu = (function () {"use strict";return {
        execute:function (sourceItemContext) {// Load VSTS controls and REST client
            VSS.require(["VSS/Controls", "VSS/Service", "ReleaseManagement/Core/RestClient"],function (Controls, VSS_Service, RM_WebApi) {var newDefinitionName = prompt("New definition name:", sourceItemContext.definition.name +" - Copy");if (newDefinitionName !=null)
                {
                    sourceItemContext.view.logMessage("Creating "+ newDefinitionName +"...");var vsoContext = VSS.getWebContext();// Get a RM client to make REST callsvar rmClient = VSS_Service.getCollectionClient(RM_WebApi.ReleaseHttpClient);
                    rmClient.getReleaseDefinition(vsoContext.project.id,sourceItemContext.definition.id).then(function(definition){
                        definition.name = newDefinitionName;
						rmClient.createReleaseDefinition(definition, vsoContext.project.id).then(() => {
                            sourceItemContext.view.refresh();
                            sourceItemContext.view.logMessage("Cloned \'"+ sourceItemContext.definition.name +"\' and created \'"+ newDefinitionName +"\'");
                        }, function(error){
                            sourceItemContext.view.logError(error);
                        });
                    }, function(error){
                        sourceItemContext.view.logError(error);
                    });
                }
            });
        }
    }
}());

DBCC DBREINDEX

$
0
0

Esse é mais um artigo da série “Saga da otimização com comandos antigos”

No último artigo, comparamos o INDEX SCAN e HEAP SCAN e mostramos que o Heap Scan tem melhor desempenho.

Impacto do Clustered Index

O exemplo do artigo anterior, criamos uma tabela de produto e adicionamos um índice clustered sobre o campo “nome”.

image

Adicionamos 10.000 registros aleatórios:

image

No final, temos uma tabela com 15MB.

image

O resultado final foram 1828ms e 1.900 leituras em disco.

image

Podemos resolver o problema rodando o comando DBCC DBREINDEX (obsoleto) ou sua nova versão ALTER INDEX REBUILD:

ALTER INDEX nome_indice ON produtos REBUILD

A tabela desfragmentada fica em 10MB e o tempo de execução da query é de 900ms.

Organizando a Tabela

A heap consumia os mesmos 10MB, pois não fragmentava. A query executava em 892ms e realizava 1257 leituras em disco. Então, se o Heap Scan tem melhor desempenho, então por que criar um Clustered Index?

Como vimos no artigo anterior, não vale a pena criar um índice clustered apenas por criar.

É essencial que a escolha da chave para Clustered Index siga as recomendações:

  • Pouca alteração (UPDATE) – mais importante!
  • Campos pequenos (até 8 bytes)
  • Valores sequenciais
  • Valores distintos

No nosso exemplo, há dois problemas em criar um índice clustered usando a chave “nome”: 1) valor não-sequencial, causando a fragmentação natural da tabela. 2) campo longo (800 bytes), que causará futuro problemas com índices non-clustered.

Vou citar 3 motivos para criar um Clustered Index:

1. Evitar problemas da Heap

Embora o heap scan tenha melhor desempenho, a heap esconde alguns problemas:

Por isso, recomendamos criar um clustered index evita esses comportamentos exóticos da Heap.

Campos Identity são boas escolhas porque são campos pequenos (tipo INTEGER), sequenciais e distintos.

2. Período de Dados

Frequentemente encontramos consultas com filtros de data. Quando é necessário ler uma grande quantidade de dados, o índice clustered pode agregar os dados próximos e facilitar as operações de scan.

SELECT * FROM tabela WHERE data_inicio between ‘2016-05-01’ AND ‘2016-05-10’

Campos de data são pequenos e normalmente inseridos sequencialmente. Ao criar um índice clustered, a tabela fica ordenada pela data e facilita as buscas com período de tempo. No exemplo acima, somente os dados do mês de maio serão lidos, sem a necessidade de consultar a tabela inteira e acessar dados dos meses de abril, março, fevereiro, janeiro.

3. Ordenação de Consulta

Quando encontramos consultas usando ORDER BY, podemos sugerir a criação do campo como clustered index.

SELECT * FROM tabela ORDER BY Data

Ao criar um índice clustered, deixamos a tabela pré-ordenada pelo campo chave. Dessa forma, economizamos o recurso de CPU e memória necessário para ordenar os registros em tempo de execução. Entretanto, é importante que a chave tenha pouca (ou nenhuma) alteração.

Exemplos ruins:

SELECT * FROM tabela ORDER BY ultima_modificacao

SELECT * FROM tabela ORDER BY preco DESC

Não adianta criar índices clustered para os campos “ultima_modificacao” e “preco”, pois esses são campos que sofrem UPDATE frequentes.

E as Primary Key?

Geralmente uma Primary Key deve adotar um índice Non-Clustered (NCL).

Entretanto, existem casos para adotar um Clustered Index (CL) em uma Primary Key (PK):

  • Se a Primary Key for um campo IDENTITY, então é uma boa escolha para índice CL.
  • Em banco de dados OLAP, operações de JOIN com grande volume de dados podem se beneficiar de índices CL

Por outro lado, há um incontável número de exemplos onde as Primary Keys são criadas como Clustered Index indevidamente, causando problema de fragmentação e impacto na performance.

Evite fragmentar o Clustered Index

A regra é simples: evite fragmentar o clustered index e tenha o desempenho igual a Heap.

Se essa regra for seguida, eliminamos os três problemas escondidos da heap:

No próximo artigo, vamos explorar um pouco mais sobre os índices. Até o momento, falamos apenas sobre o comparativo do Heap scan e Index scan. Entretanto, a vantagem do índice é usar algo muito mais rápido que o scan.

Kernthemen der Zukunft von SharePoint zusammengefasst (#FutureofSharePoint)

$
0
0
Am 04.05.2016 hat Microsoft mit einem schönen Star-Wars Wortspiel ("May the 4th be with you") die Neuigkeiten und Roadmap Informationen zu Office 365 und SharePoint On-Premiss präsentiert. Ich möchte heute mit diesem Beitrag die vier zentralen Themen sowie die "Randnotizen" zu SharePoint Server 2016 zusammenfassen. Themen in diesem Beitrag: Zahlen und Fakten Aus "Seiten" wird "SharePoint" Simple and powerful file sharing Neuer Seitenerstellungsprozess Dokumente...(read more)

CryptographicException while adding TFS connection to ReleaseManagement Update-4 client

$
0
0

One of our customer reported below error :-

Issue:- While adding a TFS connection, user were getting CryptographicException

Message: Bad Data.
: \r\n\r\n   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle pKeyContext, Byte[] pbEncryptedKey, Int32 cbEncryptedKey, Boolean fOAEP, ObjectHandleOnStack ohRetDecryptedKey)
   at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
   at Microsoft.TeamFoundation.Release.Data.Helpers.CryptoHelper.GetDecryptedValue(String str, String containerName)
   at Microsoft.TeamFoundation.Release.Data.Helpers.CryptoHelper.DecryptString(String str, String cryptoContainerName, String key, Encryption encryption)
   at Microsoft.TeamFoundation.Release.Data.Proxy.LocalProxy.EncryptionServiceLocalProxy.<.ctor>b__1(String x)
   at Microsoft.TeamFoundation.Release.Data.Proxy.LocalProxy.EncryptionServiceLocalProxy.Decrypt(String encryptionLocation)
   at Microsoft.TeamFoundation.Release.Tfs.TfsHelperBase.SecureCredential.ToNetworkCredential()
   at Microsoft.TeamFoundation.Release.Tfs.TfsHelperBase.GetCacheCredentialOfTFSServiceAccount(String tfsUrl)
   at Microsoft.TeamFoundation.Release.Tfs.TfsHelperBase.GetTeamProjectCollectionForServiceUser(String tfsUrl)
   at Microsoft.TeamFoundation.Release.Tfs.TfsHelperBase.GetTfsDetails(String tfsUrl, String userName, String encryptedPassword)
   at Microsoft.TeamFoundation.Release.ServiceProcessor.Processor.TfsServiceProcessor.GetTfsDetails(String tfsUrl, String userName, String encryptedPassword, Int32 tfsVersionId)

 

How it got fixed :-

From above call stack, It seems like the crypto key present on the customer machine were corrupt and hence Decrypt() were failing. Perform following steps to fix it (Note: You might have to re-enter password again at all places in your ReleaseTemplate and all other place) :-

1. Navigate to %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys on the RM server machine and look for the key that looks like this - 918fda7df45a07822a6a453544ec6f66_<SomeGuid>. Take a back-up of the key and delete it.

2. Close ReleaseManagement Client and Server window

3. Re-configure ReleaseManagement server (this will create the give with 918fda7df45a07822a6a453544ec6f66_<SomeGuid> again.

4. Try configuring your TFS again. it should work

5. Done!!!!

sp_detach_db

$
0
0

Esse é mais um artigo da série “Saga da otimização com comandos antigos”

No último artigo, comentei sobre as melhores práticas para escolha da chave do índice clustered. O objetivo é minimizar a fragmentação ao mesmo tempo que tentamos ter algum benefício com a ordenação.

Table Scan

Até agora falamos muito sobre as operação de Table Scan, seja ela usando Heap ou Index scan. Na realidade, vimos que o tempo é proporcional a quantidade de acesso ao disco. Por exemplo, se realizarmos 500 acessos ao disco com latência de 3ms, então teremos uma query demorando por volta de 1.500ms.

Falamos sobre o impacto das leituras read-ahead como otimização de disco. Isso significa que podemos tentar combinar 50 leituras de blocos de 8kb em uma única leitura de 400kb. A latência de disco geralmente varia pouco em relação ao tamanho do bloco.

Agora vamos mostrar o impacto de um disco muito lento sobre um table scan.

Storage

O primeiro passo será movimentar os dados para um disco supostamente mais rápido. Existem duas formas para fazer isso: backup/restore ou detach/attach. A forma mais fácil de copiar banco de dados entre máquinas é através do backup/restore, mas detach/attaché a forma mais simples para movimentar os arquivos para outro disco da mesma máquina.

Começaremos usando o comando sp_detach_db para remover a referência o banco de dados LOJADB sem apagar os arquivos.

image

Em muito casos, é recomendável configurar o banco de dados como SINGLE_USER. Se esse comando demorar muito, então é interessante forçar a desconexão dos demais usuários com WITH ROLLBACK IMMEDIATE.

ALTER DATABASE lojadb SET SINGLE_USER WITH ROLLBACK IMMEDIATE

Agora os arquivos do banco de dados podem ser copiados para outro disco.

image

Copiei os arquivos MDF e LDF para o disco F.

image

Em seguida, rodamos o comando de attach. Muitos podem pensar no sp_attach_db, que faz exatamente o que precisamos, mas prefiro usar o CREATE DATABASE. Eles fazem exatamente a mesma coisa.

image

Podemos fazer o teste e verificar o tempo total da query, que ficou em 395ms:

image

Esse tempo está melhor que o tempo original de 852ms. O tempo de latência desse novo storage foi de apenas 0,3ms!

Problema: Sobrecarga do Storage

Já passei por milhares de clientes e situações, mas a história é sempre igual: o novo storage tem uma performance excelente e resolverá todos os problemas. Essa é a frase que você ouve antes da venda. Depois da venda, o desempenho continua excelente e então conclui-se que a culpa era do storage antigo.

É aqui que nasce um novo problema: sobrecarga do storage.

Com o tempo, é comum que compartilhar os recursos de storage (disco, controladora, switch) entre os servidores da empresa. Não é difícil ver LUN’s alocadas dentro do mesmo Disk Array ou Hosts sobrecarregando os links de comunicação. Assim como é normal encontrar servidores VMWare armazenando imagens em controladoras compartilhadas com servidores de banco de dados. Essas são as situações de sobrecarga do storage.

Vou simular uma sobrecarga no storage fazendo duas coisas ao mesmo tempo:

  • Executando a query no SQL Server
  • Copiando arquivos entre discos do storage

Aqui está meu novo storage:

image

Iniciei a cópia de arquivo:

image

Iniciei a execução da query:

image

A query executou em 1812ms (4 vezes mais lento do que o baseline de 395ms).

image

Vamos supor que a tabela esteja fragmentada e, por isso, as operações de read-ahead estão desligadas:

image

Embora isso pareça uma trapaça, é bem provavel que isso esteja acontecendo no servidor de produção: forwarding records, extent fragmentation, page density, page splits. Então vamos simular qual seria o tempo em uma tabela fragmentada e com a cópia de dados ainda em progresso:

image

Certamente esse é nosso recorde: 58.987ms, ou seja, a query ficou rodando aproximadamente 1 minuto.

Podemos analisar o latência de disco para saber quem é o culpado: foram realizados 1257 I/O em um período de 58.987ms. Isso resulta em uma latência média de 47ms por leitura. Usando o checklist do windows, podemos classificar o tempo como no limite.

  • <1ms : inacreditável
  • <3ms : excelente
  • <5ms : muito bom
  • <10ms : dentro do esperado
  • <20ms : razoável
  • <50ms : limite
  • >100ms : ruim
  • > 1 seg : contenção severa de disco
  • > 15 seg : problemas graves com o storage

Por que houve uma degradação tão grande? Porque saímos de uma latência de 0,3ms (inacreditável) para 47ms (limite). O problema não é exatamente o storage, mas a quantidade de I/O necessário para responder a query.

Conclusão

Nesse artigo chegamos ao limite da query:

SELECT * FROM produtos WHERE id = 1234

Ela pode realizar 1257 acessos ao disco para retornar apenas 1 registro. Existem várias formas de diminuir o impacto desses 1257 I/O:

  • Agregar as operações de I/O usando o Read-ahead e blocos grandes
  • Manter os dados em cache (memória)
  • Atualizar o storage para uma versão mais moderna com maior capacidade de I/O

Essa é a análise de infraestrutura. E qual seria a análise de desenvolvimento? Será que é possível reduzir o número de I/O dessa query? A resposta é sim! Usando um método chamado SEEK ao invés de SCAN.

No próximo artigo vamos introduzir o conceito do Seek.


How to Lead in the Digital Age

$
0
0

Digital leaders bring innovative business models, services, and experiences to life. The digital transformation of your organization requires people-centricity, customer obsession, business acumen, a culture of innovation, and a rapid continuous cycle of value creation. A successful transformation can help you better engage customers and employees, optimize business operations, and transform products.

This thought-piece “How to Lead in the Digital Age" provides an overview on the forces at work and emerging trends, how to formulate a digital transformation strategy using established practices, and you’ll gain insights and know-how from practical examples and true stories that explore the art of the possible that may be additive in helping re-imagine your digital future.

http://download.microsoft.com/download/7/B/2/7B238951-FEC1-4BD7-82B6-8F8DEC7817E5/How-to-Lead-in-the-Digital-Age-from-Microsoft-Services.pdf

Zero-Downtime Patching nur eingeschränkt mit Distributed Cache Service möglich

$
0
0
Mit SharePoint 2016 wurden die MinRoles und damit auch das Zero-Downtime Patching eingeführt. Aber derzeit kursieren widersprüchliche, gar falsche Aussagen in den Technet Artikeln. Die Dinge möchte ich gerade rücken und Ihnen zeigen, wie Sie mit dem Distributed Cache Service umgehen müssen, um das versprochene Zero-Downtime Patching bestmöglich zu realisieren. Generell gibt es schon tolle Beiträge von John Peluso und Stefan Goßner über die Eigenarten...(read more)

Herramientas gratuitas de desarrollo

$
0
0

Después de un poco de inactividad debida a un fallo en mi disco duro, continúo con mi reto, en esta ocasión voy a presentar dos herramientas gratuitas, probablemente muchos ya las conozcan pero nunca está de más hablar de ellas.

La primera herramienta es Visual Studio Code, un editor de texto multiplataforma especializado para programadores, cuenta con una interfaz muy sencilla y fácil de usar, incorpora soporte a múltiples lenguajes, sintaxis coloreada, intellisense, herramientas para desarrollo web como perfiladores, examinadores de código fuente y DOM, extensiones, control de versiones con Git,  y depuración de lenguajes de programación basados en Javascript.

Visual Studio Code

La segunda herramienta es Visual Studio Community, un entorno de desarrollo completo que incluye soporte para aplicaciones web, windows, apps móviles en múltiples plataformas, características avanzadas de depuración, integración con Microsoft Azure, múltiples lenguajes y mucho más.

Visual Studio Community

Visual Studio Community soporta una amplia variedad de proyectos y lenguajes, el cuadro de diálogo de nuevo proyecto muestra la gran cantidad de opciones disponibles:

New Project

Finalmente, una de las mejores características de Visual Studio Community es el soporte de extensiones y actualizaciones que pueden administrarse directamente dentro del IDE, basta con acceder al cuadro de diálogo y buscar por nuevas funcionalidades que nos ayuden en nuestras tareas de programación.

Extensions and Updates

Si aun no han probado estas herramientas les recomiendo descargarlas y probarlas, más adelante les mostraré cómo integrarlas con otros servicios.

SET SHOWPLAN_TEXT

$
0
0

Esse é mais um artigo da série “Saga da otimização com comandos antigos”

No último artigo, falamos do impacto do storage em operações de Table Scan. Agora é hora de resolver rapidamente usando índice.

Criando índices

Primeiro, vamos habilitar um comando antigo chamado SHOWPLAN_TEXT.

image

Embora haja comandos melhores, o SHOWPLAN_TEXT possui um resultado texto fácil para entender.

image

Na primeira linha temos o comando original e na segunda, o plano de execução.

A solução para o problema de desempenho é criar um índice.

image

Agora nosso comando terá um novo plano de execução:

image

Por que esse plano é melhor? Simples. Basta contar o número de I/O em disco.

image

Se tivermos latências de 5ms, então a query demora aproximadamente 15ms. Entretanto, se o storage apresentar lentidão e a latência subir para 100ms (muito ruim), a query executa em apenas 300ms (menos que 1 segundo).

IT Pro Cloud Essentials

$
0
0

En esta ocasión vamos a cubrir una oferta de servicios diseñada para los profesionales de informática en la nube, este es uno de los momentos más importantes en la tecnología de la información, la transición a la computación de la nube está rompiendo todos los paradigmas tanto para los usuarios finales como para las empresas.

Muchos han escuchado de la nube y muchos han asistido a charlas de Microsoft Azure, sin embargo , pocas personas han empezado a experimentar con esta tecnología, Azure tiene muchas ofertas que pueden usarse para probar sus servicios, el Azure Free Trial provee $200 para probar los servicios que se desee, el único detalle es que esto requiere que ingresemos una tarjeta de crédito, algunas personas no cuentan con esto o simplemente no se sienten cómodas brindando esta información (en realidad uno siempre puede administrar los cobros y no hay nada que temer); por eso he pensado en hablar del IT Pro Cloud Essentials, esta oferta les dará acceso a $100 mensuales de crédito en Azure durante 3 meses y lo mejor de todo, no requiere que ustedes ingresen una tarjeta de crédito antes de probar el producto.

Al ingresar al sitio http://www.itprocloudessentials.com ustedes verán la opción de unirse al programa, lo único que requieren es una Cuenta Microsoft para asociar la oferta a su usuario:

ITPro Cloud Essentials

Al unirse al programa, ustedes deberán proporcionar un poco de información adicional para crear su perfil

Profile

Una vez registrados encontrarán la opción de activar ofertas donde podrán generar un código que luego canjearán en el sitio de Azure Pass

Cloud Offers

Azure Pass

Una vez realizado todo el proceso ustedes podrán ingresar al portal de Azure y empezar a utilizar su nueva suscripción!

Azure Portal

Les recomiendo que hagan uso de esta oferta lo antes posible, la demanda es alta y a veces se queda sin pases y toma unos días antes de poderlos entregar nuevamente, una vez que ustedes obtengan el pase asegúrense de canjearlo antes del 30 de septiembre de 2016 que es cuando vence la oferta.

Saludos!

Being Human in the Digital Age - Talk at North West Internet Marketing Association

$
0
0

Being Human in the Digital Age – A talk by Roy Sharples, at the North West Internet Marketing Association, 26th May, 2016

All concepts, writings, photography & graphics (unless otherwise stated – where it has been licensed). All rights reserved @ Roy Sharples 2016. Please do not re-use without permission from the author.

Abstract

Today’s world reflects a new reality: technology is pervasive, with easy access to digital services. This virtually seamless world makes disruption possible, enabling new business models, products, services, and experiences. Capitalizing on this phenomenon is key to innovation and growth. Businesses are connecting products in the real-world to experiences in virtual environments. Examples of today’s new reality are: the convergence of device functionality, today’s ubiquitous access to information, the power to make informed predictions through instant insight, , the ability to generate demand with the right people in the right place. Mix with that our need to be social, curiosity for authentic content and insights, and the human need for balance and you can see we are experiencing a unique time in human history.

This session will provide provocative insights and perspectives about being human in the digital age, the tools, techniques, learnings and keys to success for infusing the design and maker sensibility into the product and service creation process.

Issue with renaming folder while mapping the drive

$
0
0

Here, I have faced an interesting issue which I wanted to share.

I was trying to map my share point site with the mapped drive. I was able to map but every time I was trying to create the folder and then trying to rename it, it was giving me an error

"The file name you specified is not valid or too long. Specify a different file name". I was just having one folder in the site, still this error was occurring. Here I found the solution, and its a tricky one:

 

Example, Rather than mapping to https://test.com/Shared%20Documents, map to 

\\test.com@ssl\Shared Documents\

 

Please make sure to replace %20 with space.

 

Hope this article will help you.


Entity Framework - Row / Column Based Security

$
0
0

Prepared by LC WAIKIKI IT Team (tayfun.esmer@lcwaikiki.com)  and Dr. Alp Asutay

1.    Introduction

The last few years have seen the rise of Entity Framework object-relational mapper. While getting more robust and improved with each version compared to previous ones, we have been introduced to interceptors starting with Entity Framework 6. Those interceptors allow us to intervene the queries executed against SQL, the result sets coming back from SQL and even the exceptions related to the executions. If you have decided to learn more about interceptors, you must have come across a few implementations on the internet like logging and soft delete concepts. But what we aim here is much more complex and advanced scenario which is going to serve for our security policies based on rows and columns of a table.

At the end of the day, Row Based Security will enable us to implement restrictions on data row access. For example ensuring that employees can access only the data pertinent to their department, or a group of accountants can access the orders only with less than $10.000 total price. Column Based Security on the other hand, will enable us to implement restrictions on columns. It's the data will be restricted again as Row Based Security, but the target is all data under specified columns.

2.    Solution & Implementation

We all know that limiting data means filtering it, which is done with the “where” keyword. So basically we will apply predicates to the set of entities when queried, at application tier and independently of developers. There are two interceptor levels for the queries before they go out the gate and get executed in SQL. One is DbCommandInterceptor, which is the SQL level and carries DbCommand object which is the very same object SqlCommand derives from. That is not the field we want to work on by altering the SQL command before it gets executed. The other one is DbCommandTreeInterceptor, which reveals itself from its name and makes it possible to work with expression trees and alter them with the help of visitor objects. That’s the path we will take to achieve our goal more elegantly.

So, first things first. We are going to create policy expressions holding the main data which defines the target for security policy to be applied: environment, server, database, table (entity), column, field (property of the entity) and even the values or the source of them. You can see the data model below.

By holding the environment information along with the server and database, we can apply different policies for a user on different environments such as test, prod, development etc. DbObject and DbObjectField tables are for the entity and its property. These policy securities can be associated with claims, claim groups and users specifically, and the information for that is held in AuthorizationRef and AuthorizationDefinitionRef fields in PolicySecurity table.

The journey of the code written for the implementation of this solution begins as the user steps in our application, which is the Session_Start event for web applications. There we query all the row and column based security policies associated with the incoming user with all the data needed, transform them into DataPolicyExpression objects and store them in distributed cache which happened to be Redis Cache for us.

 

Notice that the PropertyValueSource value is static with a value next to it which is 2 at this example. However, the source could be External meaning the data for the expression is going to be pulled from an object which implements the interface (IExternalPolicySecurityService) this solution exposes with a method returning Dictionary<string, string> typed value, holding the key for that external values and the actual values (probably a set of IDs of other tables) how and wherever they are coming from. So in that case instead of a static value, we hold that key name of that external source.

Once the concrete class implementing that interface is found on the web project, the method of it is invoked and all the data is returned for the security policy to be used most likely with "IN" operator instead of equal (=). That external value source option allows us to define policy with dynamic data which needs to be executed at runtime and involves other tables. Other than these two options, we can store our policies with internal value sources, which refers to endpoints of services. Instead of a concrete class implementing a specific interface, a web service can also be used for the same reason but different technical needs. As in the external value case, that service again will return a Dictionary<string,string> typed value. Again in our case this internal value source working with web services always served us set of IDs of other tables to be used along with the "IN" operator.

We have two separate interceptors for row based policies and column based policies.

These two interceptors are registered and waiting for any query to catch before it is executed in SQL Server.

At that point, when the TreeCreated event is triggered, we pull the data from the cache and see if the executing query holds any matching entity (table).

If so, the policy information stored in DataPolicyExpression object is used to build DbFilterExpression with dynamic filters, to be attached to the query.

Building that expression doesn’t happen for every query hit. Instead, when it is created for the first time, it’s stored in memory for the later hits for the same entity. That process could have done much earlier, like in the Session_Start event for every single user. But that could depend on the number of policies defined for each user, how complex the policies therefore the expression needs to be build are complex, and of course we cannot know for sure if the user is going to hit that table (entity) in that session at all. So the implementation may be different for some technical and performance purposes but at the end of the day with the help of the interceptors, we can apply new filters or replace the existing ones based on our policies.

 

3. Problems & Solutions

Of course we had some troubles making our code work during this implementation. Firstly, the order for the interceptors to work mattered in a case where a column which both column and row based policies are applied for. Because the data was replaced with the default value of that type empty string in our case-instead of the column name, again that default value was used in the where clause which caused the queries to have false conditions all the time. It looked something like this:

SELECT Foo1, Foo2, N’’

FROM tb_Table

WHERE N’’ = ‘UK’

Instead of WHERE Foo3 = ‘UK’, the column name was replaced by the default value which was put there due to a column based security for the user not having rights to see that specific column. We simply solved the problem by registering the interceptors in the right other.

Another problem we faced was the query cache mechanism of Entity Framework. The problem rise when an entity is queried more than once. When a value is set in a filter parameter, that value is cached and reused for the further queries. This happens because the interceptors we use implements IDbCommandTreeInterceptor and the execution of the TreeCreated method happens only once for the query commands, being cached after. Even for a new instance of DbContext won’t make any difference, we’ll be stucked with the cached values for the parameters. This situation might be a problem for almost any kind of interceptor works, unless it is using a hard coded value such as true/false for soft delete purpose implementations.

While there are a few different work arounds (using functions that produce queries with constants or using properties of a non-mapped objects and such) for this problem.

We decided to go with the IEnumerable<TEntity> collection wich is always remain empty.

Entity Framework does not cache queries that involves IEnumerable<T>.Contains<T>(T value) call against an in-memory collection, since the values of the collection are considered volatile.

That method (Contains) call can be executed in a wrapped DbSet object or at a point of base repository like object for it so no matter what entity the query comes for.

Entity Framework won’t replace it with the cached one.

Exchange 2010 sp3 not upgrading.

$
0
0

Recently in support we've noticed an abnormal amount of cases come in regarding upgrading Exchange 2010 sp3.  Now normally with upgrade cases they can be traced back to not having the correct permissions, broken permissions, or another sort of restriction.  Lately we've had several cases come in where the upgrade will start, then after a few minutes it will instantly start rolling back the update, it won't even place a watermark into the registry.  Because of these behaviors I figured I'd throw up a check list for customers to follow when you run into issues like this.  So the one thing that triggered this post was because of the oddity when you have netapp installed on your server, it would appear that netapp has a config file for PowerShell, when Exchange is upgrading it reads this and tries to use a different version of PowerShell, or for some other reason causes the upgrade to fail.  If you have netapp and are running into this issue check the fallowing location\file.

Location: C:\Program Files (x86)\CommonFiles\NetApp\
File: PowerShell.exe.Activation.Config

Example of file we've notice cause some issues:

<configuration>  
<startupuseLegacyV2RuntimeActivationPolicy="true">             
<supportedRuntime version="v4.0.30319"/>           
<supportedRuntime version="v2.0.50727"/>                
<supportedRuntime version="v1.1.4322"/>                   
<supportedRuntime version="v1.0.3705"/>
</startup>
</configuration>

Modified file:

<configuration> 
<startupuseLegacyV2RuntimeActivationPolicy="true">    
<supportedRuntime version="v2.0.50727"/>
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v1.1.4322"/>
<supportedRuntime version="v1.0.3705"/>
</startup>
</configuration> 

So, I've also seen instances where the only information in the config file shows:

<configuration>  
<startupuseLegacyV2RuntimeActivationPolicy="true">             
<supportedRuntime version="v4.0.30319"/>     
</startup>
</configuration>

When\if you notice this I've been able to resolve this by just adding in the 2.0 version.
 
<configuration> 
<startupuseLegacyV2RuntimeActivationPolicy="true">    
<supportedRuntime version="v2.0.50727"/>    
<supportedRuntime version="v4.0.30319"/>
</startup>
</configuration> 

So now the question is, what do I do if I'm having install\upgrade issues and I don't have netapp?  Well for this scenario I always start with any errors that you're getting, if the errors are generic then best option is to start from the beginning with permissions.  Also make sure that the fallowing groups have inheritance enabled, sometimes when inheritance is broken the permissions are not handed down properly.

Permissions required:

Domain Admins
Enterprise Admins
Organization Management

Next would be to run the install\upgrade package from an administrative command prompt.  Also, if permissions have been changed remember to log off the server and log back in.  If that fails you will want to check and make sure you don't have powershell 3.0 installed, we've notice this has caused issues since it's not fully compatible with Exchange 2010.  Also, make sure the OU that the Exchange Servers are in don't have any GPO's that could be causing issues.

https://blogs.technet.microsoft.com/exchange/2012/12/14/windows-management-framework-3-0-on-exchange-2007-and-exchange-2010/

If Permissions look good you can move to changing the execution policy that Exchange is running under, if it is on anything other than unrestricted it can cause upgrade issues.  To modify just run the command below in Exchange Management Shell and it should change the policy.

Set-ExecutionPolicy Unrestricted

If that still doesn't resolve the issue you can clear out the temp directory on the server, located at c:\windows\temp\.

If issues persist it would probably be best to open a case with support.

SQL Server Master Data Services 2016 released!

$
0
0

SQL Server 2016 was released recently. With that, all the new capabilities in Master Data Services are generally available. To check out the list of new capabilities, check out - What's New in Master Data Services (MDS).

To download SQL Server 2016, go to Evaluation Center.

To download Excel Add-in for Master Data Services, go here.  

 We are very excited about the release. We would like for you to try the product and provide us any feedback.

 

SharePoint 2016 Site Collections super schnell erstellen

$
0
0
Microsoft hat uns mit SharePoint 2016 eine kleine aber feine Rafinesse zur Verfügung gestellt, wenn wir Site Collections erstellen möchten. Jeder Farmadministrator, der "mal schnell" eine Site Collection erstellen musste, kennt folgendes Szenario sicher: Nach dem Absenden der Erstellung holen wir uns erst einmal einen Kaffee, so wie wir es früher beim Start langsamer Computer gemacht haben. Denn eine Erstellung dauert ungefähr 40 (+/-) Sekunden, bis die Seite wirklich da ist....(read more)

Run Hue Spark Notebook on Cloudera

$
0
0

When you deploy a CDH cluster using Cloudera Manager, you can use Hue web UI to run, for example, Hive and Impala queries.  But Spark notebook is not configured out of the box.  Turns out installing and configuring Spark notebooks on CDH isn't as straightforward as is described in their existing documentation.  In this blog, we will provide step by step instructions on how to enable Hue Spark notebook with Livy on CDH.  

These steps have been verified in a default deployment of Cloudera CDH cluster on Azure.  At the time of this writing, the deployed CDH is at version 5.7, HUE 3.9, and Livy 0.2.  The steps should be similar for any CDH cluster deployed with Cloudera Manager. 

1. Go to Cloudera Manager, go to Hue and find the host name of the Hue Server.

 

2. In Cloudera Manager, go to Hue->Configurations, search for "safety", in Hue Service Advanced Configuration Snippet (Safety Valve) for hue_safety_valve.ini, add the following configuration, save the changes, and restart Hue:

[desktop]
app_blacklist=

[spark]
server_url=http://<your_hue_server>:8998/

languages='[{"name": "Scala", "type": "scala"},{"name": "Python", "type": "python"},{"name": "Impala SQL", "type": "impala"},{"name": "Hive SQL", "type": "hive"},{"name": "Text", "type": "text"}]'

 

Now if you go to the Hue Web UI, you should be able to see the Spark notebook.  The Spark notebook uses Livy to submit Spark jobs, so without Livy, it's not functioning yet. 

 

3. In the Hue Web UI, go to Configuration, find hadoop_conf_dir and note it down:

 

 

4. SSH to your Hue server, for simplicity, unless specified we'll run the following commands in sudo or as root user:

#download Livy
wget http://archive.cloudera.com/beta/livy/livy-server-0.2.0.zip
unzip livy-server-0.2.0.zip -d /<your_livy_dir>

#set environment variables for Livy
export SPARK_HOME=/opt/cloudera/parcels/CDH/lib/spark
export JAVA_HOME=/usr/java/jdk1.7.0_67-cloudera
export HADOOP_CONF_DIR=<your hadoop_conf_dir found in the previous step in Hue configuration>
export HUE_SECRET_KEY=<your Hue superuser password, this is usually the user you use when you log in to Hue Web UI the first time>

#run Livy. You must run Livy as a user who has access to hdfs, for example, the superuser hdfs.
su hdfs
/<your_livy_dir>/livy-server-0.2.0/bin/livy-server

 

5. Now if you go to Hue Web UI again, the warning about Spark in Step 2 should be gone. Go to the root of your Hue Web UI URL, then add "/notebook" in the URL. You should be able to add a notebook to run code:

 

In the following example, we added a Scala snippet and ran it in the notebook:

 

If you keep your ssh console with Livy running open, you will see when you start to run your code in a notebook, a Spark job is being submitted. If there's any error, you will also see it in the console.

You can also add Impala snippet, and use the various graphing tools:

For more information about Hue Spark notebook, please see gethue.com/spark.

 

Viewing all 12366 articles
Browse latest View live