示例#1
0
        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);
        }
示例#2
0
        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;
            }
        }