Defrag and other stuff
This commit is contained in:
parent
5dad63c146
commit
3c5b1a1347
@ -9,13 +9,14 @@ namespace AsPartitionProcessing.SampleClient
|
||||
{
|
||||
InitializeInline,
|
||||
InitializeFromDatabase,
|
||||
MergePartitions
|
||||
MergePartitions,
|
||||
DefragPartitionedTables
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
//Set sample execution mode here:
|
||||
const SampleExecutionMode ExecutionMode = SampleExecutionMode.InitializeInline;
|
||||
const SampleExecutionMode ExecutionMode = SampleExecutionMode.InitializeInline;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
@ -46,6 +47,10 @@ namespace AsPartitionProcessing.SampleClient
|
||||
{
|
||||
PartitionProcessor.MergePartitions(modelConfig, LogMessage, "Internet Sales", Granularity.Yearly, "2012");
|
||||
}
|
||||
else if (ExecutionMode == SampleExecutionMode.DefragPartitionedTables)
|
||||
{
|
||||
PartitionProcessor.DefragPartitionedTables(modelConfig, LogMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
PartitionProcessor.PerformProcessing(modelConfig, LogMessage);
|
||||
@ -57,8 +62,10 @@ namespace AsPartitionProcessing.SampleClient
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(exc.Message, null);
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine("Press any key to exit.");
|
||||
Console.ReadKey();
|
||||
}
|
||||
@ -164,7 +171,10 @@ namespace AsPartitionProcessing.SampleClient
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(exc.Message);
|
||||
Console.WriteLine();
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine("Press any key to exit.");
|
||||
Console.ReadKey();
|
||||
Environment.Exit(0); //Avoid recursion if errored connecting to db
|
||||
|
@ -52,13 +52,12 @@ namespace AsPartitionProcessing
|
||||
List<ModelConfiguration> modelConfigs = new List<ModelConfiguration>();
|
||||
ModelConfiguration modelConfig = null;
|
||||
int currentModelConfigurationID = -1;
|
||||
TableConfiguration tableConfig = null;
|
||||
int currentTableConfigurationID = -1;
|
||||
|
||||
SqlDataReader reader = command.ExecuteReader();
|
||||
while (reader.Read())
|
||||
{
|
||||
TableConfiguration tableConfig = null;
|
||||
int currentTableConfigurationID = -1;
|
||||
|
||||
if (modelConfig == null || currentModelConfigurationID != Convert.ToInt32(reader["ModelConfigurationID"]))
|
||||
{
|
||||
modelConfig = new ModelConfiguration();
|
||||
|
@ -86,13 +86,17 @@ namespace AsPartitionProcessing
|
||||
}
|
||||
else
|
||||
{
|
||||
//Partitioned table. Process based on partitioning configuration(s).
|
||||
//Validate multiple granularity ranges.
|
||||
tableConfiguration.ValidatePartitioningConfigurations();
|
||||
|
||||
//Find template partition.
|
||||
Partition templatePartition = table.Partitions.Find(tableConfiguration.AnalysisServicesTable);
|
||||
if (templatePartition == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Table {tableConfiguration.AnalysisServicesTable} does not contain a partition with the same name to act as the template partition.");
|
||||
}
|
||||
|
||||
//Process based on partitioning configuration(s).
|
||||
foreach (PartitioningConfiguration partitioningConfiguration in tableConfiguration.PartitioningConfigurations)
|
||||
{
|
||||
LogMessage("", false);
|
||||
@ -207,6 +211,7 @@ namespace AsPartitionProcessing
|
||||
{
|
||||
LogMessage($"Inner exception message: {exc.InnerException.Message}", false);
|
||||
}
|
||||
LogMessage("", false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -350,6 +355,79 @@ namespace AsPartitionProcessing
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defragment all partitions tables in a tabular model based on configuration
|
||||
/// </summary>
|
||||
/// <param name="modelConfiguration">Configuration info for the model</param>
|
||||
/// <param name="messageLogger">Pointer to logging method</param>
|
||||
public static void DefragPartitionedTables(ModelConfiguration modelConfiguration, LogMessageDelegate messageLogger)
|
||||
{
|
||||
_modelConfiguration = modelConfiguration;
|
||||
_messageLogger = messageLogger;
|
||||
|
||||
Server server = new Server();
|
||||
try
|
||||
{
|
||||
Database database;
|
||||
Connect(server, out database);
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
LogMessage($"Start: {DateTime.Now.ToString("hh:mm:ss tt")}", false);
|
||||
LogMessage($"Server: {_modelConfiguration.AnalysisServicesServer}", false);
|
||||
LogMessage($"Database: {_modelConfiguration.AnalysisServicesDatabase}", false);
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
|
||||
LogMessage("", false);
|
||||
LogMessage($"Defrag partitioned tables in database {_modelConfiguration.AnalysisServicesDatabase}", false);
|
||||
LogMessage(new String('-', _modelConfiguration.AnalysisServicesDatabase.Length + 38), false);
|
||||
LogMessage("", false);
|
||||
LogMessage("=>Actions & progress:", false);
|
||||
|
||||
foreach (TableConfiguration tableConfiguration in _modelConfiguration.TableConfigurations)
|
||||
{
|
||||
//Only interested in partitoned tables
|
||||
if (tableConfiguration.PartitioningConfigurations.Count > 0)
|
||||
{
|
||||
Table table = database.Model.Tables.Find(tableConfiguration.AnalysisServicesTable);
|
||||
if (table == null)
|
||||
{
|
||||
throw new Microsoft.AnalysisServices.ConnectionException($"Could not connect to table {tableConfiguration.AnalysisServicesTable}.");
|
||||
}
|
||||
|
||||
LogMessage($"Defrag table {tableConfiguration.AnalysisServicesTable} ...", true);
|
||||
table.RequestRefresh(RefreshType.Defragment);
|
||||
database.Model.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
LogMessage("", false);
|
||||
LogMessage("Finish: " + DateTime.Now.ToString("hh:mm:ss tt"), false);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
LogMessage("", false);
|
||||
LogMessage($"Exception occurred: {DateTime.Now.ToString("hh:mm:ss tt")}", false);
|
||||
LogMessage($"Exception message: {exc.Message}", false);
|
||||
if (exc.InnerException != null)
|
||||
{
|
||||
LogMessage($"Inner exception message: {exc.InnerException.Message}", false);
|
||||
}
|
||||
LogMessage("", false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
_modelConfiguration = null;
|
||||
_messageLogger = null;
|
||||
if (server != null) server.Disconnect();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
@ -5,7 +5,7 @@ namespace AsPartitionProcessing
|
||||
/// <summary>
|
||||
/// Configuration information for partitioning of a table within an AS tabular model.
|
||||
/// </summary>
|
||||
public class PartitioningConfiguration
|
||||
public class PartitioningConfiguration : IComparable<PartitioningConfiguration>
|
||||
{
|
||||
/// <summary>
|
||||
/// ID of the PartitioningConfiguration table.
|
||||
@ -101,8 +101,8 @@ namespace AsPartitionProcessing
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
public int CompareTo(PartitioningConfiguration other) => string.Compare(this.LowerBoundary.ToString("yyyy-MM-dd"), other.LowerBoundary.ToString("yyyy-MM-dd"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -47,5 +47,77 @@ namespace AsPartitionProcessing
|
||||
public TableConfiguration()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate multiple granularities to ensure no overlapping ranges, etc.
|
||||
/// </summary>
|
||||
public void ValidatePartitioningConfigurations()
|
||||
{
|
||||
if (this.PartitioningConfigurations.Count > 1)
|
||||
{
|
||||
this.PartitioningConfigurations.Sort(); //Sorts by LowerBoundary value
|
||||
DateTime previousUpperBoundary = DateTime.MinValue;
|
||||
Granularity previousGranularity = Granularity.Daily;
|
||||
bool foundDaily = false, foundMonthly = false, foundYearly = false;
|
||||
|
||||
foreach (PartitioningConfiguration partitioningConfiguration in this.PartitioningConfigurations)
|
||||
{
|
||||
#region Check don't have multiple partitioning configurations with same granularity
|
||||
|
||||
string multiSameGrainErrorMessage = $"Table {this.AnalysisServicesTable} contains multiple {{0}} partitioning configurations, which is not allowed.";
|
||||
switch (partitioningConfiguration.Granularity)
|
||||
{
|
||||
case Granularity.Daily:
|
||||
if (foundDaily)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(multiSameGrainErrorMessage, "daily"));
|
||||
}
|
||||
else
|
||||
{
|
||||
foundDaily = true;
|
||||
}
|
||||
break;
|
||||
case Granularity.Monthly:
|
||||
if (foundMonthly)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(multiSameGrainErrorMessage, "monthly"));
|
||||
}
|
||||
else
|
||||
{
|
||||
foundMonthly = true;
|
||||
}
|
||||
break;
|
||||
case Granularity.Yearly:
|
||||
if (foundYearly)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(multiSameGrainErrorMessage, "yearly"));
|
||||
}
|
||||
else
|
||||
{
|
||||
foundYearly = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Check don't have overlapping date ranges
|
||||
|
||||
if (partitioningConfiguration.LowerBoundary <= previousUpperBoundary)
|
||||
{
|
||||
throw new InvalidOperationException($"Table {this.AnalysisServicesTable} contains partitioning configurations with overlapping date ranges, which is not allowed. {previousGranularity.ToString()} upper boundary is {previousUpperBoundary.ToString("yyyy-MM-dd")}; {partitioningConfiguration.Granularity.ToString()} lower boundary is {partitioningConfiguration.LowerBoundary.ToString("yyyy-MM-dd")}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
previousUpperBoundary = partitioningConfiguration.UpperBoundary;
|
||||
previousGranularity = partitioningConfiguration.Granularity;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user