コード例 #1
0
ファイル: Program.cs プロジェクト: xdansmith/elastic-db-tools
        public static void Main(string[] args)
        {
            try
            {
                // Parse command line arguments
                s_commandLine = new CommandLine(args);
                if (!s_commandLine.IsValid)
                {
                    s_commandLine.WriteUsage();
                    return;
                }

                // Get Shard Map Manager
                ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager(
                    GetConnectionString(), ShardMapManagerLoadPolicy.Eager);
                Console.WriteLine("Connected to Shard Map Manager");

                // Get Shard Map
                ShardMap map = smm.GetShardMap(s_commandLine.ShardMap);
                Console.WriteLine("Found {0} shards", map.GetShards().Count());

                // Create connection string for MultiShardConnection
                string connectionString = GetCredentialsConnectionString();

                // REPL
                Console.WriteLine();
                while (true)
                {
                    // Read command from console
                    string commandText = GetCommand();
                    if (commandText == null)
                    {
                        // Exit requested
                        break;
                    }

                    // Evaluate command
                    string output;
                    using (MultiShardConnection conn = new MultiShardConnection(map.GetShards(), connectionString))
                    {
                        output = ExecuteCommand(conn, commandText);
                    }

                    // Print output
                    Console.WriteLine(output);
                }
            }
            catch (Exception e)
            {
                // Print exception and exit
                Console.WriteLine(e);
                return;
            }
        }
        public void TestMultiShardConnectionConstructorEvaluatesShards()
        {
            MultiShardTestUtils.DropAndCreateDatabases();
            ShardMap shardMap = MultiShardTestUtils.CreateAndGetTestShardMap();

            List <Shard> shards = shardMap.GetShards().ToList();

            MultiShardConnection conn = new MultiShardConnection(shards.ToConsumable(), dummyConnectionString);

            AssertExtensions.AssertSequenceEqual(shards, conn.Shards);
        }
コード例 #3
0
        /// <summary>
        /// Helper function to select a random shard for specified shard map.
        /// </summary>
        /// <param name="sm">Shard map to get shard.</param>
        /// <returns>Shard from specified shard map.</returns>
        private Shard GetRandomOnlineShardFromShardMap(ShardMap sm)
        {
            List <Shard> shardList = sm.GetShards().Where(s => s.Status == ShardStatus.Online).ToList();

            if (shardList.Count > 0)
            {
                return(shardList[_r.Next(shardList.Count)]);
            }
            else
            {
                return(null);
            }
        }
コード例 #4
0
        /// <summary>
        /// Helper function to add a new shard to given shard map.
        /// </summary>
        /// <param name="sm"></param>
        private void AddShardToShardMap(ShardMap sm)
        {
            IEnumerable <Shard> existingShards = sm.GetShards();

            // get list of shard locations that are not already added to this shard map.
            List <string> availableLocationList = (from dbName in ShardMapManagerLoadTests.s_shardedDBs
                                                   where !existingShards.Select(s => s.Location.Database).ToList().Contains(dbName)
                                                   select dbName).ToList();

            if (availableLocationList.Count > 0)
            {
                ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, availableLocationList[_r.Next(availableLocationList.Count)]);

                Debug.WriteLine("Trying to add shard at location {0} to shard map {1}", sl, sm);

                ShardCreationInfo si = new ShardCreationInfo(sl, ShardStatus.Online);

                Shard newShard = sm.CreateShard(si);
            }
        }
コード例 #5
0
        /// <summary>
        /// Helper function to clean default shard map.
        /// </summary>
        private static void CleanShardMapsHelper()
        {
            ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager(
                Globals.ShardMapManagerConnectionString,
                ShardMapManagerLoadPolicy.Lazy);

            // Remove all existing mappings from the list shard map.
            ShardMap sm = smm.GetShardMap(ShardMapTests.s_defaultShardMapName);

            Assert.IsNotNull(sm);

            // Remove all shards from list shard map
            IEnumerable <Shard> s = sm.GetShards();

            using (IEnumerator <Shard> sEnum = s.GetEnumerator())
            {
                while (sEnum.MoveNext())
                {
                    sm.DeleteShard(sEnum.Current);
                }
            }
        }
コード例 #6
0
        public void DeleteShardAbortGSMDoAndLSMUndo()
        {
            bool shouldThrow = true;

            IStoreOperationFactory sof = new StubStoreOperationFactory()
            {
                CallBase = true,
                CreateRemoveShardOperationShardMapManagerIStoreShardMapIStoreShard =
                    (_smm, _sm, _s) =>
                {
                    StubRemoveShardOperation op = new StubRemoveShardOperation(_smm, _sm, _s);
                    op.CallBase = true;
                    op.DoGlobalPostLocalExecuteIStoreTransactionScope = (ts) =>
                    {
                        if (shouldThrow)
                        {
                            throw new StoreException("", ShardMapFaultHandlingTests.TransientSqlException);
                        }
                        else
                        {
                            // Call the base function, hack for this behavior is to save current operation, set current to null, restore current operation.
                            var original = op.DoGlobalPostLocalExecuteIStoreTransactionScope;

                            op.DoGlobalPostLocalExecuteIStoreTransactionScope = null;
                            try
                            {
                                return(op.DoGlobalPostLocalExecute(ts));
                            }
                            finally
                            {
                                op.DoGlobalPostLocalExecuteIStoreTransactionScope = original;
                            }
                        }
                    };

                    op.UndoLocalSourceExecuteIStoreTransactionScope = (ts) =>
                    {
                        if (shouldThrow)
                        {
                            throw new StoreException("", ShardMapFaultHandlingTests.TransientSqlException);
                        }
                        else
                        {
                            // Call the base function, hack for this behavior is to save current operation, set current to null, restore current operation.
                            var original = op.UndoLocalSourceExecuteIStoreTransactionScope;

                            op.UndoLocalSourceExecuteIStoreTransactionScope = null;
                            try
                            {
                                return(op.UndoLocalSourceExecute(ts));
                            }
                            finally
                            {
                                op.UndoLocalSourceExecuteIStoreTransactionScope = original;
                            }
                        }
                    };

                    return(op);
                }
            };

            ShardMapManager smm = new ShardMapManager(
                new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString),
                new SqlStoreConnectionFactory(),
                sof,
                new CacheStore(),
                ShardMapManagerLoadPolicy.Lazy,
                new RetryPolicy(1, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero),
                RetryBehavior.DefaultRetryBehavior);

            ShardMap sm = smm.GetShardMap(ShardMapTests.s_defaultShardMapName);

            Assert.IsNotNull(sm);

            ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapTests.s_shardedDBs[0]);

            Shard sNew = sm.CreateShard(sl);

            Assert.IsNotNull(sNew);

            bool storeOperationFailed = false;

            try
            {
                sm.DeleteShard(sNew);
            }
            catch (ShardManagementException sme)
            {
                Assert.AreEqual(ShardManagementErrorCategory.ShardMap, sme.ErrorCategory);
                Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode);
                storeOperationFailed = true;
            }

            Assert.IsTrue(storeOperationFailed);

            // verify that the shard exists in store.
            Shard sValidate = sm.GetShard(sl);

            Assert.IsNotNull(sValidate);

            // Obtain the pending operations.
            var pendingOperations = ShardMapperTests.GetPendingStoreOperations();

            Assert.AreEqual(pendingOperations.Count(), 1);

            shouldThrow          = false;
            storeOperationFailed = false;
            try
            {
                sm.DeleteShard(sNew);
            }
            catch (ShardManagementException)
            {
                storeOperationFailed = true;
            }

            Assert.IsFalse(storeOperationFailed);
            Assert.AreEqual(0, sm.GetShards().Count());
        }
コード例 #7
0
        public void CreateShardAbortGSM()
        {
            int retryCount = 0;

            EventHandler <RetryingEventArgs> eventHandler = (sender, arg) =>
            {
                retryCount++;
            };

            ShardMapManager smm = new ShardMapManager(
                new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString),
                new SqlStoreConnectionFactory(),
                new StubStoreOperationFactory()
            {
                CallBase = true,
                CreateAddShardOperationShardMapManagerIStoreShardMapIStoreShard =
                    (_smm, _sm, _s) => new NTimeFailingAddShardOperation(10, _smm, _sm, _s)
            },
                new CacheStore(),
                ShardMapManagerLoadPolicy.Lazy,
                new RetryPolicy(5, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero),
                RetryBehavior.DefaultRetryBehavior);

            ShardMap sm = smm.GetShardMap(ShardMapTests.s_defaultShardMapName);

            Assert.IsNotNull(sm);

            ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapTests.s_shardedDBs[0]);

            bool storeOperationFailed = false;

            smm.ShardMapManagerRetrying += eventHandler;

            try
            {
                Shard sNew = sm.CreateShard(sl);
                Assert.IsNotNull(sNew);
            }
            catch (ShardManagementException sme)
            {
                Assert.AreEqual(ShardManagementErrorCategory.ShardMap, sme.ErrorCategory);
                Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode);
                storeOperationFailed = true;
            }

            smm.ShardMapManagerRetrying -= eventHandler;

            Assert.AreEqual(5, retryCount);

            Assert.IsTrue(storeOperationFailed);

            // verify that shard map does not have any shards.
            int count = 0;
            IEnumerable <Shard> sList = sm.GetShards();

            using (IEnumerator <Shard> sEnum = sList.GetEnumerator())
            {
                while (sEnum.MoveNext())
                {
                    count++;
                }
            }
            Assert.AreEqual(0, count);
        }
コード例 #8
0
        public void BasicScenarioDefaultShardMaps()
        {
            bool success = true;

            try
            {
                #region DeployShardMapManager

                // Deploy shard map manager.
                ShardMapManagerFactory.CreateSqlShardMapManager(
                    Globals.ShardMapManagerConnectionString,
                    ShardMapManagerCreateMode.ReplaceExisting);

                #endregion DeployShardMapManager

                #region GetShardMapManager

                // Obtain shard map manager.
                ShardMapManager shardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(
                    Globals.ShardMapManagerConnectionString,
                    ShardMapManagerLoadPolicy.Lazy);

                #endregion GetShardMapManager

                #region CreateDefaultShardMap

                // Create a single user per-tenant shard map.
                ShardMap defaultShardMap = shardMapManager.CreateListShardMap <int>("DefaultShardMap");

                #endregion CreateDefaultShardMap

                #region CreateShard

                for (int i = 0; i < ScenarioTests.s_perTenantDBs.Length; i++)
                {
                    // Create the shard.
                    defaultShardMap.CreateShard(
                        new ShardLocation(
                            Globals.ShardMapManagerTestsDatasourceName,
                            ScenarioTests.s_perTenantDBs[i]));
                }

                #endregion CreateShard

                #region UpdateShard

                // Find the shard by location.
                Shard shardToUpdate = defaultShardMap.GetShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, "PerTenantDB1"));

                // Perform the actual update. Mark offline.
                Shard updatedShard = defaultShardMap.UpdateShard(
                    shardToUpdate,
                    new ShardUpdate
                {
                    Status = ShardStatus.Offline
                });

                // Verify that update succeeded.
                Assert.AreEqual(ShardStatus.Offline, updatedShard.Status);

                #endregion UpdateShard

                #region DeleteShard

                // Find the shard by location.
                Shard shardToDelete = defaultShardMap.GetShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, "PerTenantDB4"));

                defaultShardMap.DeleteShard(shardToDelete);

                // Verify that delete succeeded.
                Shard deletedShard;

                defaultShardMap.TryGetShard(shardToDelete.Location, out deletedShard);

                Assert.IsNull(deletedShard);

                // Now add the shard back for further tests.
                // Create the shard.
                defaultShardMap.CreateShard(shardToDelete.Location);

                #endregion DeleteShard

                #region OpenConnection without Validation

                // Find the shard by location.
                Shard shardForConnection = defaultShardMap.GetShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, "PerTenantDB1"));

                using (SqlConnection conn = shardForConnection.OpenConnection(
                           Globals.ShardUserConnectionString,
                           ConnectionOptions.None)) // validate = false
                {
                }

                #endregion OpenConnection without Validation

                #region OpenConnection with Validation

                // Use the stale state of "shardToUpdate" shard & see if validation works.
                bool validationFailed = false;
                try
                {
                    using (SqlConnection conn = shardToDelete.OpenConnection(
                               Globals.ShardUserConnectionString,
                               ConnectionOptions.Validate)) // validate = true
                    {
                    }
                }
                catch (ShardManagementException smme)
                {
                    validationFailed = true;
                    Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.ShardDoesNotExist);
                }

                Assert.AreEqual(validationFailed, true);

                #endregion OpenConnection with Validation

                #region OpenConnectionAsync without Validation

                // Find the shard by location.
                shardForConnection = defaultShardMap.GetShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, "PerTenantDB1"));

                using (SqlConnection conn = shardForConnection.OpenConnectionAsync(
                           Globals.ShardUserConnectionString,
                           ConnectionOptions.None).Result) // validate = false
                {
                }

                #endregion OpenConnectionAsync without Validation

                #region OpenConnectionAsync with Validation

                // Use the stale state of "shardToUpdate" shard & see if validation works.
                validationFailed = false;
                try
                {
                    using (SqlConnection conn = shardToDelete.OpenConnectionAsync(
                               Globals.ShardUserConnectionString,
                               ConnectionOptions.Validate).Result) // validate = true
                    {
                    }
                }
                catch (AggregateException ex)
                {
                    ShardManagementException smme = ex.InnerException as ShardManagementException;
                    if (smme != null)
                    {
                        validationFailed = true;
                        Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.ShardDoesNotExist);
                    }
                }

                Assert.AreEqual(validationFailed, true);

                #endregion OpenConnectionAsync with Validation

#if FUTUREWORK
                #region GetAllOnlineShards

                // Get all online shards.
                foreach (Shard s in defaultShardMap.GetShards(Int32.MaxValue, 1))
                {
                    Trace.WriteLine(s.Location);
                }

                #endregion GetAllOnlineShards
#endif
            }
            catch (ShardManagementException smme)
            {
                success = false;

                Trace.WriteLine(String.Format("Error Category: {0}", smme.ErrorCategory));
                Trace.WriteLine(String.Format("Error Code    : {0}", smme.ErrorCode));
                Trace.WriteLine(String.Format("Error Message : {0}", smme.Message));

                if (smme.InnerException != null)
                {
                    Trace.WriteLine(String.Format("Storage Error Message : {0}", smme.InnerException.Message));

                    if (smme.InnerException.InnerException != null)
                    {
                        Trace.WriteLine(String.Format("SqlClient Error Message : {0}", smme.InnerException.InnerException.Message));
                    }
                }
            }

            Assert.IsTrue(success);
        }
コード例 #9
0
        public void TestSimpleSelect(MultiShardExecutionPolicy policy)
        {
            // What we're doing:
            // Grab all rows from each test database.
            // Load them into a MultiShardDataReader.
            // Iterate through the rows and make sure that we have 9 total.
            //
            using (MultiShardConnection conn = new MultiShardConnection(_shardMap.GetShards(), MultiShardTestUtils.ShardConnectionString))
            {
                using (MultiShardCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText      = "SELECT dbNameField, Test_int_Field, Test_bigint_Field FROM ConsistentShardedTable";
                    cmd.ExecutionOptions = MultiShardExecutionOptions.IncludeShardNameColumn;
                    cmd.ExecutionPolicy  = policy;

                    using (MultiShardDataReader sdr = cmd.ExecuteReader())
                    {
                        int recordsRetrieved = 0;
                        Logger.Log("Starting to get records");
                        while (sdr.Read())
                        {
                            recordsRetrieved++;
                            string dbNameField         = sdr.GetString(0);
                            int    testIntField        = sdr.GetFieldValue <int>(1);
                            Int64  testBigIntField     = sdr.GetFieldValue <Int64>(2);
                            string shardIdPseudoColumn = sdr.GetFieldValue <string>(3);
                            string logRecord           =
                                string.Format(
                                    "RecordRetrieved: dbNameField: {0}, TestIntField: {1}, TestBigIntField: {2}, shardIdPseudoColumnField: {3}, RecordCount: {4}",
                                    dbNameField, testIntField, testBigIntField, shardIdPseudoColumn, recordsRetrieved);
                            Logger.Log(logRecord);
                            Debug.WriteLine(logRecord);
                        }

                        sdr.Close();

                        Assert.AreEqual(recordsRetrieved, 9);
                    }
                }
            }
        }
コード例 #10
0
        public void MyTestInitialize()
        {
            _shardMap = MultiShardTestUtils.CreateAndGetTestShardMap();

            _shardConnection = new MultiShardConnection(_shardMap.GetShards(), MultiShardTestUtils.ShardConnectionString);
        }
コード例 #11
0
        public void MyTestInitialize()
        {
            _shardMap = MultiShardTestUtils.CreateAndGetTestShardMap();

            _shardConnection = new MultiShardConnection(_shardMap.GetShards(), MultiShardTestUtils.ShardConnectionString);
        }
コード例 #12
0
        /// <summary>
        /// Helper function to add a new shard to given shard map.
        /// </summary>
        /// <param name="sm"></param>
        private void AddShardToShardMap(ShardMap sm)
        {
            IEnumerable<Shard> existingShards = sm.GetShards();

            // get list of shard locations that are not already added to this shard map.
            List<string> availableLocationList = (from dbName in ShardMapManagerLoadTests.s_shardedDBs
                                                  where !existingShards.Select(s => s.Location.Database).ToList().Contains(dbName)
                                                  select dbName).ToList();

            if (availableLocationList.Count > 0)
            {
                ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, availableLocationList[_r.Next(availableLocationList.Count)]);

                Debug.WriteLine("Trying to add shard at location {0} to shard map {1}", sl, sm);

                ShardCreationInfo si = new ShardCreationInfo(sl, ShardStatus.Online);

                Shard newShard = sm.CreateShard(si);
            }
        }
コード例 #13
0
        /// <summary>
        /// Helper function to select a random shard for specified shard map.
        /// </summary>
        /// <param name="sm">Shard map to get shard.</param>
        /// <returns>Shard from specified shard map.</returns>
        private Shard GetRandomOnlineShardFromShardMap(ShardMap sm)
        {
            List<Shard> shardList = sm.GetShards().Where(s => s.Status == ShardStatus.Online).ToList();

            if (shardList.Count > 0)
                return shardList[_r.Next(shardList.Count)];
            else
                return null;
        }