public void PrepareComputeTableStatistics(Context context, TableReference tr, out string connectionString, out string sql) { // Assign a database server to the query // TODO: maybe make this function generic // TODO: check this part to use appropriate server and database var sm = GetSchemaManager(false); var ds = sm.Datasets[tr.DatasetName]; if (ds is GraywulfDataset && !((GraywulfDataset)ds).IsSpecificInstanceRequired) { var gds = (GraywulfDataset)ds; var dd = new DatabaseDefinition(context); dd.Guid = gds.DatabaseDefinition.Guid; dd.Load(); // Get a server from the scheduler var si = new ServerInstance(Context); si.Guid = Scheduler.GetNextServerInstance(new Guid[] { dd.Guid }, StatDatabaseVersionName, null); si.Load(); connectionString = si.GetConnectionString().ConnectionString; SubstituteDatabaseName(tr, si.Guid, StatDatabaseVersionName); tr.DatabaseObject = null; } else { // Run it on the specific database connectionString = ds.ConnectionString; } // Generate statistics query sql = CodeGenerator.GenerateTableStatisticsQuery(tr); }
public void DeterminePartitionCount(Context context, IScheduler scheduler, out int partitionCount, out Guid assignedServerInstanceGuid) { partitionCount = 1; assignedServerInstanceGuid = Guid.Empty; // Single server mode will run on one partition by definition, // Graywulf mode has to look at the registry for available machines switch (ExecutionMode) { case ExecutionMode.SingleServer: InitializeQueryObject(null); break; case ExecutionMode.Graywulf: InitializeQueryObject(context, scheduler); // If query is partitioned, statistics must be gathered if (IsPartitioned) { // Assign a server that will run the statistics queries // Try to find a server that contains all required datasets. This is true right now for // SkyQuery where all databases are mirrored but will have to be updated later // Collect all datasets that are required to answer the query var dss = FindRequiredDatasets(); // Datasets that are mirrored and can be on any server var reqds = (from ds in dss.Values where !ds.IsSpecificInstanceRequired select ds.DatabaseDefinition.Guid).ToArray(); // Datasets that are only available at a specific server instance var spds = (from ds in dss.Values where ds.IsSpecificInstanceRequired && !ds.DatabaseInstance.IsEmpty select ds.DatabaseInstance.Guid).ToArray(); var si = new ServerInstance(context); si.Guid = scheduler.GetNextServerInstance(reqds, StatDatabaseVersionName, spds); si.Load(); AssignedServerInstance = si; assignedServerInstanceGuid = si.Guid; // *** TODO: find optimal number of partitions // TODO: replace "2" with a value from settings partitionCount = 2 * scheduler.GetServerInstances(reqds, SourceDatabaseVersionName, spds).Length; // Now have to reinitialize to load the assigned server instances InitializeQueryObject(context, scheduler, true); } break; default: throw new NotImplementedException(); } }
protected override void Execute(CodeActivityContext activityContext) { QueryPartitionBase queryPartition = QueryPartition.Get(activityContext); switch (queryPartition.Query.ExecutionMode) { case ExecutionMode.SingleServer: queryPartition.InitializeQueryObject(null, null, true); break; case ExecutionMode.Graywulf: using (var context = ContextManager.Instance.CreateContext(this, activityContext, ConnectionMode.AutoOpen, TransactionMode.AutoCommit)) { var scheduler = activityContext.GetExtension <IScheduler>(); //queryPartition.DatabaseVersionName = queryPartition.Query.SourceDatabaseVersionName; TODO: delete queryPartition.InitializeQueryObject(context, scheduler, false); var dss = queryPartition.FindRequiredDatasets(); // Check if there are any Graywulf datasets referenced in the query var assignmydb = (dss.Values.FirstOrDefault(ds => !ds.IsSpecificInstanceRequired) == null); // *** TODO: replace this whole thing to use JOIN graphs // If no graywulf datasets are used, use the server containing myDB, // otherwise ask the scheduler for an appropriate server if (dss.Count == 0 || assignmydb) { // use MyDB's server var ef = new EntityFactory(context); var federation = queryPartition.FederationReference.Value; var user = ef.LoadEntity <User>(context.UserGuid); var di = federation.MyDBDatabaseVersion.GetUserDatabaseInstance(user); queryPartition.AssignedServerInstance = di.ServerInstance; } else { // Assign new server instance var si = new ServerInstance(context); si.Guid = scheduler.GetNextServerInstance( dss.Values.Where(x => !x.IsSpecificInstanceRequired).Select(x => x.DatabaseDefinition.Guid).ToArray(), queryPartition.Query.SourceDatabaseVersionName, null); si.Load(); queryPartition.AssignedServerInstance = si; } queryPartition.InitializeQueryObject(context, scheduler, true); EntityGuid.Set(activityContext, queryPartition.AssignedServerInstance.Guid); } break; } }