Wprowadzenie
Analysis Services, jak już zostało to omówione w poście “Metody monitorowania i optymalizacji SQL Server Analysis Services” (https://pl.seequality.net/monitorowanie-optymalizacja-ssas/), dostarcza wielu różnych opcji za pomocą których możemy monitorować oraz analizować stan serwera, baz danych analitycznych, a nawet poszczególnych obiektów. Czasami zdarza się jednak, że dostępne metody nie dostarczają informacji, których szukamy lub dostarczają informację na temat poszczególnego obiektu bez możliwości wygenerowania raportu dla zbioru takich elementów. Może się wówczas okazać, że takie informacje można pobrać samemu wykorzystując w tym celu język C# lub PowerShell. W niniejszym poście zaprezentuję prostą bibliotekę C# oraz skrypty PowerShell, które według mnie mogą okazać się przydatne podczas pracy z Analysis Services. W szczególności jeżeli pracujemy z dużymi bazami lub z dużą ilością baz analitycznych. Wszystkie kody źródłowe dla projektów, które zostaną tutaj omówione dostępne są na GitHub: https://github.com/seequality/seequality_ssas/tree/master/ssas_tollbox
Zaprezentowane skrypty powinny ułatwić zdobycie informacji o tym, które elementy zostały przeprocesowane i kiedy oraz szczegółowych informacji o rolach i ich konfiguracji. W przypadku małych baz analitycznych nawet ręczne sprawdzenie wszystkich obiektów – wliczając w to partycje – może być rzeczą prostą i szybką. W sytuacji gdy w bazie analitycznej znajduje się duża ilość grup miar, które dodatkowo są partycjonowane miesięcznie lub tygodniowo w chwili, kiedy chcemy sprawdzić, który obiekt nie został jeszcze przeprocesowany takie zadanie może okazać się praco- i czasochłonne. Podobny problem może wystąpić w przypadku pracy z rolami. W chwili, kiedy z bazy danych korzysta setki użytkowników, a w kostce zdefiniowane są dziesiątki ról ewentualne sprawdzenie dostępu dla jednego użytkownika staje się poważnym kłopotem. Warto również zauważyć, że w przypadku sprawdzania staniu przeprocesowania obiektu przydatnym może okazać się projekt “Analysis Services Stored Procedure Project” https://asstoredprocedures.codeplex.com/, natomiast niestety nie zawsze istnieje możliwość instalacji dodatkowych bibliotek na serwerze SSAS – szczególnie serwerze produkcyjnym. Biorąc pod uwagę powyższe zaprezentuje skrypty i prosty program napisany w języku C#, który może ułatwić i przyspieszyć niektóre zadania związane z pracą z Analysis Services i z których sam korzystam.
Opis metod w projektach
Solucja składa się z trzech projektów:
- Projekt:ssas_toolbox_library – biblioteka, która pozwala na połączenie się do serwera Analysis Services wykorzystując “Analysis Management Objects” oraz zwraca pożądane informacje o obiektach
- Projekt ssas_toolbox_console – aplikacja konsolowa, która pozwala na skorzystanie z metod zdefiniowanych w bibliotece
- Projekt ssas_toolbox_powershell – projekt zawierający skrypty PowerShell. Oba skrypty wykonują dokładnie to samo co biblioteka napisana w języku C#. W przypadku pierwszego z nich: SSASDiscover.ps1 cała logika została przepisana do PowerShell. Drugi wykorzystuje natomiast tę bibliotekę odwołując się bezpośrednio do jej metod
Ideą każdej metody jest pobranie informacji z serwera SSAS oraz zapisanie logu do pliku. Plik wynikowy będzie oddzielny dla każdej metody i może zostać nadpisany lub utworzony z bieżącą datą w celu zachowania historii.
Dostępne są następujące metody (poniżej metody znajduje się przykładowa zawartość z pliku wynikowego):
- “1. Discover databases processing states” – zwraca informacje o stanie przeprocesowania baz analitycznych
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, state: PartiallyProcessed, last processed: 2017-06-25 1:30:15 PM
- “2. Discover dimensions processing states” – zwraca informacje o stanie przeprocesowania wymiarów
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Account, state: Processed, last processed: 2017-06-25 1:29:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Clustered Customers, state: Processed, last processed: 2017-06-25 1:30:07 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Customer, state: Processed, last processed: 2017-06-25 3:29:42 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Date, state: Processed, last processed: 2017-06-25 1:29:43 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Department, state: Processed, last processed: 2017-06-25 1:29:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Destination Currency, state: Processed, last processed: 2017-06-25 1:29:38 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Employee, state: Processed, last processed: 2017-06-25 1:29:38 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Geography, state: Processed, last processed: 2017-06-25 1:29:38 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Internet Sales Order Details, state: Processed, last processed: 2017-06-25 1:29:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Organization, state: Processed, last processed: 2017-06-25 1:29:31 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Product, state: Processed, last processed: 2017-06-25 1:29:39 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Promotion, state: Processed, last processed: 2017-06-25 1:29:31 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Reseller Sales Order Details, state: Processed, last processed: 2017-06-25 1:29:37 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Reseller, state: Processed, last processed: 2017-06-25 1:29:31 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Sales Channel, state: Processed, last processed: 2017-06-25 1:29:38 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Sales Reason, state: Processed, last processed: 2017-06-25 1:29:37 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Sales Summary Order Details, state: Processed, last processed: 2017-06-25 1:29:38 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Sales Territory, state: Processed, last processed: 2017-06-25 3:30:38 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Scenario, state: Processed, last processed: 2017-06-25 1:29:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Source Currency, state: Processed, last processed: 2017-06-25 1:29:38 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Subcategory Basket Analysis, state: Processed, last processed: 2017-06-25 1:30:07 PM
- “3. Discover cubes processing states” – zwraca informacje o stanie przeprocesowania kostek
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Mined Customers, state: Unprocessed, last processed: 2017-06-27 11:43:31 PM
- “4. Discover measure groups processing states” – zwraca informacje o stanie przeprocesowania grup miar
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Orders, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Customers, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Reasons, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Sales, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Orders, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Summary, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Orders, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Targets, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Financial Reporting, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Exchange Rates, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Mined Customers, measure group: Internet Sales, state: Unprocessed, last processed: 2017-06-25 1:31:26 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Mined Customers, measure group: Internet Orders, state: Unprocessed, last processed: 2017-06-25 1:31:26 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Mined Customers, measure group: Internet Customers, state: Unprocessed, last processed: 2017-06-25 1:31:26 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Mined Customers, measure group: Sales Reasons, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Mined Customers, measure group: Exchange Rates, state: Processed, last processed: 2017-06-27 11:43:30 PM
- “5a. Discover partitions processing states” – zwraca informacje o stanie przeprocesowania poszczególnych partycji
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2011, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2012, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2013, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2014, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Orders, partition: Internet_Orders_2011, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Orders, partition: Internet_Orders_2012, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Orders, partition: Internet_Orders_2013, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Orders, partition: Internet_Orders_2014, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Customers, partition: Customers_2011, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Customers, partition: Customers_2012, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Customers, partition: Customers_2013, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Customers, partition: Customers_2014, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Reasons, partition: Internet_Sales_Reasons, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Sales, partition: Reseller_Sales_2011, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Sales, partition: Reseller_Sales_2012, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Sales, partition: Reseller_Sales_2013, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Sales, partition: Reseller_Sales_2014, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Orders, partition: Reseller_Orders_2011, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Orders, partition: Reseller_Orders_2012, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Orders, partition: Reseller_Orders_2013, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Reseller Orders, partition: Reseller_Orders_2014, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Summary, partition: Total_Sales_2011, state: Processed, last processed: 2017-06-27 11:43:29 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Summary, partition: Total_Sales_2012, state: Processed, last processed: 2017-06-27 11:43:29 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Summary, partition: Total_Sales_2013, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Summary, partition: Total_Sales_2014, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Orders, partition: Total_Orders_2011, state: Processed, last processed: 2017-06-27 11:43:29 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Orders, partition: Total_Orders_2012, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Orders, partition: Total_Orders_2013, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Orders, partition: Total_Orders_2008, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Sales Targets, partition: Sales_Quotas, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Financial Reporting, partition: Finance, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Exchange Rates, partition: Currency_Rates, state: Processed, last processed: 2017-06-27 11:43:28 PM
- “5b. Discover partitions processing states – unprocessed only” – zwraca informacje o stanie przeprocesowania poszczególnych partycji. Zwraca informacje tylko o nieprzeprocesowanych partycjach
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2011, state: Unprocessed, last processed: 2017-06-27 11:43:28 PM
- “5c. Discover partitions processing states – specify database, cube and measure group name” – zwraca informacje o stanie przeprocesowania poszczególnych partycji. Możliwość podania konkretnej bazy danych, kostki oraz grupy miar.
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2011, state: Processed, last processed: 2017-06-27 11:43:28 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2012, state: Processed, last processed: 2017-06-27 11:43:27 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2013, state: Processed, last processed: 2017-06-27 11:43:30 PM Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, cube: Adventure Works, measure group: Internet Sales, partition: Internet_Sales_2014, state: Processed, last processed: 2017-06-27 11:43:28 PM
- “6a. Discover users in roles” – zwraca listę użytkowników w poszczególnych rolach
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, role: Role1, member: DOMAIN\Administrator Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, role: Role1, member: DOMAIN\slawomirdrzymala Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, role: Role2, member: DOMAIN\slawomirdrzymala
- “6b. Discover users in roles – specify database and role name” – zwraca listę użytkowników w poszczególnych rolach. Możliwość podania konkretnej bazy danych oraz konkretnej roli
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, role: Role1, member: DOMAIN\Administrator Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, role: Role1, member: DOMAIN\slawomirdrzymala
- “7a. Discover roles permissions” – zwraca listę poszczególnych elementów, które zostały zdefiniowane jako dozwolone dla użytkowników na poziomie wymiaru dla poszczególnych ról
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Department, role: Role1, attribute: Departments, allowed member set: [Department].[Departments].&[2] Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Department, role: Role1, attribute: Departments, allowed member set: [Department].[Departments].&[4] Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Department, role: Role1, attribute: Departments, allowed member set: [Department].[Departments].&[6] Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Geography, role: Role2, attribute: Country, allowed member set: [Geography].[Country].&[United States]
- “7b. Discover roles permissions – specify database and role name” – zwraca listę poszczególnych elementów, które zostały zdefiniowane jako dozwolone dla użytkowników na poziomie wymiaru dla poszczególnych ról. Możliwość podania konkretnej bazy danych oraz konkretnej roli.
Discover server: Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE, database: AdventureWorksDW2014Multidimensional-EE, dimension: Geography, role: Role2, attribute: Country, allowed member set: [Geography].[Country].&[United States]
Jak już wspomniano wyżej, zarówno biblioteka C# jak i skrypty PowerShell, realizuje dokładnie te same zadania i zwraca takie same dane. Warto tylko dodać, ze zarówno do skryptów PowerShell jak i aplikacji konsolowej zostało dodane menu oraz pętla, która ułatwia korzystanie z projektu.
Szczegóły techniczne
SSAS dostarcza kilku bibliotek dzięki, którym można komunikować się do niego z poziomu kodu. W tym przypadku wykorzystano bibliotekę “Analysis Management Objects”, która służy głównie do zarządzania obiektami w Analysis Services. Kod każdej z metod jest stosunkowy prosty:
public void MeasureGroupState() { StringBuilder output = new StringBuilder(); string currentFileName = ""; if (!OverwriteOutputFile) { currentFileName = OutputFolderPath + "ssas_toolset_" + System.Reflection.MethodBase.GetCurrentMethod().Name + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt"; } else { currentFileName = OutputFolderPath + "ssas_toolset_" + System.Reflection.MethodBase.GetCurrentMethod().Name + ".txt"; } Server server; try { server = new Server(); server.Connect(SSASConnectionString); foreach (Database database in server.Databases) { foreach (Cube cube in database.Cubes) { foreach (MeasureGroup measureGroup in cube.MeasureGroups) { output.AppendLine("Discover server: " + SSASConnectionString + ", database: " + database.Name + ", cube: " + cube.Name + ", measure group: " + measureGroup.Name + ", state: " + measureGroup.State + ", last processed: " + measureGroup.LastProcessed); } } } } catch (Exception ex) { Console.WriteLine("There was an error: " + ex.Message); } File.WriteAllText(currentFileName, output.ToString()); }
Zaczynając od samej góry na początku utworzony jest StringBuilder, który będzie służył do przechowywania logów. Następnie tworzona jest dynamicznie nazwa pliku w którym zostaną te logi zapisane. Jeżeli zdefiniujemy, ze chcemy nadpisać wcześniejszy plik nazwa pliku będzie miała charakter ogólny: np: “ssas_toolset_MeasureGroupState.txt”, jeżeli nie chcemy nadpisywać poprzedniego pliku to do nazwy pliku zostanie dodana data i czas wygenerowania pliku np “ssas_toolset_MeasureGroupState_20170802031458.txt”. Następnie próbujemy połączyć się do serwera Analysis Services i za pomocą pętli foreach iterujemy po strukturze serwera: począwszy od serwera, przez bazę danych i kostki oraz skończywszy na grupach miar w tym przypadku.W sytuacji błędu zwracamy wyjątek, a jeżeli wszystko przebiegnie prawidłowo log zapisywany jest do pliku. Wszystkie metody wyglądają bardzo podobnie i działają na tej samej zasadzie.
Funkcja PowerShell, która będzie zwracać identyczne dane może wyglądać następująco:
function MeasureGroupState() { $server = new-Object Microsoft.AnalysisServices.Server $currentFileName = "" if (!$OverwriteOutputFile -ieq "true") { $currentFileName = $OutputFolderPath + "ssas_toolset_" + $MyInvocation.MyCommand.Name.Split('_')[0] + ((Get-Date -format s) -replace "-", "" -replace "T", "" -replace ":","") + ".txt"; } else { $currentFileName = $OutputFolderPath + "ssas_toolset_" + $MyInvocation.MyCommand.Name.Split('_')[0] + ".txt"; } $server.Connect($SSASConnectionString) $output = New-Object -TypeName "System.Text.StringBuilder"; foreach ($database in $server.Databases) { foreach ($cube in $database.Cubes) { foreach ($measureGroup in $cube.MeasureGroups) { $output.AppendLine("Discover server: " + $SSASConnectionString + ", database: " + $database.Name + ", cube: " + $cube.Name + ", measure group: " + $measureGroup.Name + ", state: " + $measureGroup.State + ", last processed: " + $measureGroup.LastProcessed); } } } $output.ToString() | Out-File -filepath $currentFileName }
Jak widać różnice są naprawdę niewielkie i zasada działania pozostaje niezmienna. W przypadku skrypu PowerShell można również odwołać się bezpośrednio do biblioteki C#. Wówczas skrpyt może wyglądać następująco:
[Reflection.Assembly]::LoadFile("(LIBRARY_DIRECTORY)\ssas_toolbox_library.dll") $OutputFolderPath = "C:\test\" $SSASConnectionString = "Data source=localhost\sql2016;Database=AdventureWorksDW2014Multidimensional-EE" $OverwriteOutputFile = "true" $ssasDiscover = new-object ssas_toolbox_library.SSASDiscover $ssasDiscover.OutputFolderPath = $OutputFolderPath $ssasDiscover.SSASConnectionString = $SSASConnectionString $ssasDiscover.OverwriteOutputFile = $OverwriteOutputFile $ssasDiscover.MeasureGroupState()
W tym przypadku wystarczy dołączyć bibliotekę podając jej ścieżkę, następnie ustawić pożądane parametry, zainicjować obiekt i wywołać metody.
Zakończenie
Mimo, że SSAS dostarcza naprawdę mnóstwo metod do monitorowania oraz zbierania informacji o serwerze i jego obiektach czasami dobrą drogą może okazać się jednak napisanie krótkiego skryptu w PowerShell lub prostego programu w C#. Dzięki dostępnym bibliotekom pisanie własnych rozszerzeń nie jest skomplikowane, a oczywiście może ułatwić naszą pracę i zautomatyzować niektóre zadania. Jak już zostało to zaznaczone wyżej pełny kod źródłowy dostępny jest na GitHub: https://github.com/seequality/seequality_ssas/tree/master/ssas_tollbox Warto również dodać, że to oczywiście nie koniec możliwości zarówno C# jak i PowerShell w kontekście pracy z bazą analityczną i poszerzenie wiedzy w tym obszarze może przynieść wiele korzyści w kwestii monitorowania oraz analizy SQL Server Analyis Services.
- Docker dla amatora danych – Tworzenie środowiska (VM) w Azure i VirtualBox (skrypt) - April 20, 2020
- Power-up your BI project with PowerApps – materiały - February 5, 2020
- Docker dla “amatora” danych – kod źródłowy do prezentacji - November 18, 2019
Last comments