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 = user.GetUserDatabaseInstance(federation.MyDBDatabaseVersion);

                            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;
            }
        }
示例#2
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
            var cg = new SqlServerCodeGenerator();
            cg.ResolveNames = true;
            sql = cg.GenerateTableStatisticsQuery(tr);
        }
示例#3
0
        protected override void Execute(CodeActivityContext activityContext)
        {
            QueryBase query = Query.Get(activityContext);

            int pcount = 1;

            // Single server mode will run on one partition by definition,
            // Graywulf mode has to look at the registry for available machines
            switch (query.ExecutionMode)
            {
                case ExecutionMode.SingleServer:
                    query.InitializeQueryObject(null);
                    break;
                case ExecutionMode.Graywulf:
                    using (Context context = ContextManager.Instance.CreateContext(this, activityContext, ConnectionMode.AutoOpen, TransactionMode.AutoCommit))
                    {
                        var scheduler = activityContext.GetExtension<IScheduler>();
                        query.InitializeQueryObject(context, scheduler);

                        // TODO: move this code inside the QueryBase class
                        // If query is partitioned, statistics must be gathered
                        if (query.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 = query.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.DatabaseDefinition.IsEmpty
                                        select ds.DatabaseDefinition.Guid).ToArray();*/
                            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, query.StatDatabaseVersionName, spds);
                            si.Load();

                            query.AssignedServerInstance = si;

                            //query.DatabaseVersionName = query.StatDatabaseVersionName;    //*** TODO: delete

                            // *** TODO: find optimal number of partitions
                            // TODO: replace "2" with a value from settings
                            pcount = 2 * scheduler.GetServerInstances(reqds, query.SourceDatabaseVersionName, spds).Length;

                            // Now have to reinitialize to load the assigned server instances
                            query.InitializeQueryObject(context, scheduler, true);
                            EntityGuid.Set(activityContext, query.AssignedServerInstance.Guid);
                        }
                    }
                    break;
                default:
                    throw new NotImplementedException();
            }

            query.GeneratePartitions(pcount);
        }