Beispiel #1
0
        static MySqlXConnectionStringBuilder()
        {
            // Server options.
            Options.Add(new MySqlConnectionStringOption("connect-timeout", "connecttimeout", typeof(uint), (uint)10000, false,
                                                        delegate(MySqlXConnectionStringBuilder msb, MySqlConnectionStringOption sender, object Value)
            {
                sender.ValidateValue(ref Value, sender.Keyword);
                uint value = (uint)Convert.ChangeType(Value, sender.BaseType);
                // Timeout in milliseconds should not exceed maximum for 32 bit
                // signed integer (~24 days). We truncate the value if it exceeds
                // maximum (MySqlCommand.CommandTimeout uses the same technique)
                uint timeout = Math.Min(value, Int32.MaxValue);
                if (timeout != value)
                {
                    MySqlTrace.LogWarning(-1, "Connection timeout value too large ("
                                          + value + " milliseconds). Changed to max. possible value " +
                                          +timeout + " milliseconds)");
                }
                msb.SetValue("connect-timeout", timeout);
            },
                                                        (msb, sender) => (uint)msb.values["connect-timeout"]
                                                        ));
            Options.Add(new MySqlConnectionStringOption("connection-attributes", "connectionattributes", typeof(string), "true", false));

            // Authentication options.
            Options.Add(new MySqlConnectionStringOption("auth", null, typeof(MySqlAuthenticationMode), MySqlAuthenticationMode.Default, false));
            Options.Add(new MySqlConnectionStringOption("sslcrl", "ssl-crl", typeof(string), null, false,
                                                        (msb, sender, value) => { msb.SslCrl = value as string; }, ((msb, sender) => { return(msb.SslCrl); })));
        }
        /// <summary>
        /// Loads the libzstd.dll assembly.
        /// </summary>
        internal static void LoadLibzstdLibrary()
        {
            // If the library has already been loaded, there is no need to load it again.
            if (LibZstdLoaded != null)
            {
                return;
            }

            // Attempt to load the library from an embedded resource.
            LibZstdLoaded = UnmanagedLibraryLoader.LoadUnmanagedLibraryFromEmbeddedResources("MySql.Data", "libzstd.dll");

            // If loading from an embedded resource fails, attempt to load it from a file in the output folder.
            if (LibZstdLoaded == false)
            {
                ZstandardInterop.LoadLibzstdLibrary(string.Empty);
                try
                {
                    // Creating this temporary stream to check if the library was loaded succesfully.
                    using (var testStream = new ZstandardStream(new MemoryStream(), CompressionMode.Compress))
                    { }

                    LibZstdLoaded = true;
                }
                catch {}
            }

            // If all attempts fail, log a warning and update the client supported compression algorithms.
            if (LibZstdLoaded == false)
            {
                MySqlTrace.LogWarning(-1, ResourcesX.CompressionFailedToLoadLibzstdAssembly);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Negotiates compression capabilities with the server.
        /// </summary>
        /// <param name="serverSupportedAlgorithms">An array containing the compression algorithms supported by the server.</param>
        /// <param name="clientAgainstUserAlgorithms">An array containing the compression algorithms given by user/client.</param>
        private Dictionary <string, object> NegotiateCompression(string[] serverSupportedAlgorithms, string[] clientAgainstUserAlgorithms)
        {
            if (serverSupportedAlgorithms == null || serverSupportedAlgorithms.Length == 0)
            {
                if (Settings.Compression == CompressionType.Required && clientAgainstUserAlgorithms.Length > 0)
                {
                    throw new NotSupportedException(ResourcesX.CompressionAlgorithmNegotiationFailed);
                }
                return(null);
            }

            // If server and client don't have matching compression algorithms either log a warning message
            // or raise an exception based on the selected compression type.
            XCompressionController.LoadLibzstdLibrary();
            if (!clientAgainstUserAlgorithms.Any(element => serverSupportedAlgorithms.Contains(element)))
            {
                if (Settings.Compression == CompressionType.Preferred)
                {
                    MySqlTrace.LogWarning(-1, ResourcesX.CompressionAlgorithmNegotiationFailed);
                    return(null);
                }
                else if (Settings.Compression == CompressionType.Required)
                {
                    throw new NotSupportedException(ResourcesX.CompressionAlgorithmNegotiationFailed);
                }
            }

            string negotiatedAlgorithm = null;

            for (int index = 0; index < clientAgainstUserAlgorithms.Length; index++)
            {
                if (!serverSupportedAlgorithms.Contains(clientAgainstUserAlgorithms[index]))
                {
                    continue;
                }

                negotiatedAlgorithm = clientAgainstUserAlgorithms[index];
                break;
            }

            if (negotiatedAlgorithm == null)
            {
                return(null);
            }

            // Create the compression capability object.
            var compressionCapabilities = new Dictionary <string, object>();

            compressionCapabilities.Add(XCompressionController.ALGORITHMS_SUBKEY, negotiatedAlgorithm);
            compressionCapabilities.Add(XCompressionController.SERVER_COMBINE_MIXED_MESSAGES_SUBKEY, XCompressionController.DEFAULT_SERVER_COMBINE_MIXED_MESSAGES_VALUE);

            // TODO: For future use.
            //compressionCapabilities.Add(XCompressionController.SERVER_MAX_COMBINE_MESSAGES_SUBKEY, XCompressionController.DEFAULT_SERVER_MAX_COMBINE_MESSAGES_VALUE);

            return(compressionCapabilities);
        }
Beispiel #4
0
        /// <summary>
        /// Handles a failed connection to a server.
        /// </summary>
        /// <param name="server">The failed server.</param>
        /// <remarks>This method can be overrided to implement a custom failover handling.</remarks>
        internal protected virtual void HandleFailover(ReplicationServer server)
        {
            BackgroundWorker worker = new BackgroundWorker();

            worker.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
                bool isRunning = false;
                ReplicationServer   server1 = e.Argument as ReplicationServer;
                System.Timers.Timer timer   = new System.Timers.Timer(RetryTime * 1000.0);

                System.Timers.ElapsedEventHandler elapsedEvent = delegate(object sender1, System.Timers.ElapsedEventArgs e1)
                {
                    if (isRunning)
                    {
                        return;
                    }
                    try
                    {
                        isRunning = true;
                        using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString))
                        {
                            connectionFailed.Open();
                            server1.IsAvailable = true;
                            timer.Stop();
                        }
                    }
                    catch
                    {
                        MySqlTrace.LogWarning(0,
                                              string.Format(Resources.Replication_ConnectionAttemptFailed, server1.Name));
                    }
                    finally
                    {
                        isRunning = false;
                    }
                };
                timer.Elapsed += elapsedEvent;
                timer.Start();
                elapsedEvent(sender, null);
            };

            worker.RunWorkerAsync(server);
        }
Beispiel #5
0
        /// <summary>
        /// Assigns a new server driver to the connection object
        /// </summary>
        /// <param name="groupName">Group name</param>
        /// <param name="master">True if the server connection to assign must be a master</param>
        /// <param name="connection">MySqlConnection object where the new driver will be assigned</param>
        public static void GetNewConnection(string groupName, bool master, MySqlConnection connection)
        {
            do
            {
                if (!IsReplicationGroup(groupName))
                {
                    return;
                }

                ReplicationServerGroup group  = GetGroup(groupName);
                ReplicationServer      server = group.GetServer(master);

                if (server == null)
                {
                    throw new MySqlException(Properties.Resources.Replication_NoAvailableServer);
                }

                Driver driver = Driver.Create(new MySqlConnectionStringBuilder(server.ConnectionString));
                if (connection.driver == null ||
                    driver.Settings.ConnectionString != connection.driver.Settings.ConnectionString)
                {
                    connection.Close();
                    connection.hasBeenOpen = false;
                    try
                    {
                        connection.driver = driver;
                        connection.Open();
                        return;
                    }
                    catch (Exception)
                    {
                        // retry to open a failed connection and update its status
                        connection.driver  = null;
                        server.IsAvailable = false;

                        BackgroundWorker worker = new BackgroundWorker();
                        worker.DoWork += delegate(object sender, DoWorkEventArgs e)
                        {
                            bool isRunning            = false;
                            ReplicationServer server1 = e.Argument as ReplicationServer;
                            int retryTime             = ReplicationManager.GetGroup(groupName).RetryTime;
#if !RT
                            System.Timers.Timer timer = new System.Timers.Timer(retryTime * 1000.0);


                            System.Timers.ElapsedEventHandler elapsedEvent = delegate(object sender1, System.Timers.ElapsedEventArgs e1)
                            {
                                if (isRunning)
                                {
                                    return;
                                }
                                try
                                {
                                    isRunning = true;
                                    using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString))
                                    {
                                        connectionFailed.Open();
                                        server1.IsAvailable = true;
                                        timer.Stop();
                                    }
                                }
                                catch
                                {
                                    MySqlTrace.LogWarning(0,
                                                          string.Format(Properties.Resources.Replication_ConnectionAttemptFailed, server1.Name));
                                }
                                finally
                                {
                                    isRunning = false;
                                }
                            };
                            timer.Elapsed += elapsedEvent;
                            timer.Start();
                            elapsedEvent(sender, null);
#else
                            Windows.UI.Xaml.DispatcherTimer timer = new Windows.UI.Xaml.DispatcherTimer();
                            TimeSpan ts = new TimeSpan(retryTime * 1000);
                            System.EventHandler <object> elapsedEvent = (TickSender, TickEventArgs) =>
                            {
                                if (isRunning)
                                {
                                    return;
                                }
                                try
                                {
                                    isRunning = true;
                                    using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString))
                                    {
                                        connectionFailed.Open();
                                        server1.IsAvailable = true;
                                        timer.Stop();
                                    }
                                }
                                catch
                                {
                                    MySqlTrace.LogWarning(0,
                                                          string.Format(Properties.Resources.Replication_ConnectionAttemptFailed, server1.Name));
                                }
                                finally
                                {
                                    isRunning = false;
                                }
                            };
                            timer.Tick += elapsedEvent;
                            elapsedEvent(sender, null);
                            timer.Start();
#endif
                        };

                        worker.RunWorkerAsync(server);
                    }
                }
                else
                {
                    return;
                }
            } while (true);
        }
        public static void GetNewConnection(string groupName, bool master, MySqlConnection connection)
        {
            while (true)
            {
                if (!ReplicationManager.IsReplicationGroup(groupName))
                {
                    break;
                }
                ReplicationServerGroup group  = ReplicationManager.GetGroup(groupName);
                ReplicationServer      server = group.GetServer(master);
                if (server == null)
                {
                    goto Block_2;
                }
                Driver driver = Driver.Create(new MySqlConnectionStringBuilder(server.ConnectionString));
                if (connection.driver == null || driver.Settings.ConnectionString != connection.driver.Settings.ConnectionString)
                {
                    connection.Close();
                    connection.hasBeenOpen = false;
                    try
                    {
                        connection.driver = driver;
                        connection.Open();
                    }
                    catch (Exception)
                    {
                        connection.driver  = null;
                        server.IsAvailable = false;
                        BackgroundWorker backgroundWorker = new BackgroundWorker();
                        backgroundWorker.DoWork += delegate(object sender, DoWorkEventArgs e)
                        {
                            bool isRunning            = false;
                            ReplicationServer server1 = e.Argument as ReplicationServer;
                            int   retryTime           = ReplicationManager.GetGroup(groupName).RetryTime;
                            Timer timer = new Timer((double)retryTime * 1000.0);
                            ElapsedEventHandler elapsedEventHandler = delegate(object sender1, ElapsedEventArgs e1)
                            {
                                if (isRunning)
                                {
                                    return;
                                }
                                try
                                {
                                    isRunning = true;
                                    using (MySqlConnection mySqlConnection = new MySqlConnection(server.ConnectionString))
                                    {
                                        mySqlConnection.Open();
                                        server1.IsAvailable = true;
                                        timer.Stop();
                                    }
                                }
                                catch
                                {
                                    MySqlTrace.LogWarning(0, string.Format(Resources.Replication_ConnectionAttemptFailed, server1.Name));
                                }
                                finally
                                {
                                    isRunning = false;
                                }
                            };
                            timer.Elapsed += elapsedEventHandler;
                            timer.Start();
                            elapsedEventHandler(sender, null);
                        };
                        backgroundWorker.RunWorkerAsync(server);
                        continue;
                    }
                    return;
                }
                return;
            }
            return;

Block_2:
            throw new MySqlException(Resources.Replication_NoAvailableServer);
        }
Beispiel #7
0
        /// <summary>
        /// Handles a failed connection to a server.
        /// </summary>
        /// <param name="server">The failed server.</param>
        /// <remarks>This method can be overrided to implement a custom failover handling.</remarks>
        internal protected virtual void HandleFailover(ReplicationServer server)
        {
            BackgroundWorker worker = new BackgroundWorker();

            worker.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
                bool isRunning            = false;
                ReplicationServer server1 = e.Argument as ReplicationServer;
#if !NETSTANDARD1_3
                System.Timers.Timer timer = new System.Timers.Timer(RetryTime * 1000.0);

                System.Timers.ElapsedEventHandler elapsedEvent = delegate(object sender1, System.Timers.ElapsedEventArgs e1)
                {
                    if (isRunning)
                    {
                        return;
                    }
                    try
                    {
                        isRunning = true;
                        using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString))
                        {
                            connectionFailed.Open();
                            server1.IsAvailable = true;
                            timer.Stop();
                        }
                    }
                    catch
                    {
                        MySqlTrace.LogWarning(0,
                                              string.Format(Resources.Replication_ConnectionAttemptFailed, server1.Name));
                    }
                    finally
                    {
                        isRunning = false;
                    }
                };
                timer.Elapsed += elapsedEvent;
                timer.Start();
                elapsedEvent(sender, null);
#else
                Windows.UI.Xaml.DispatcherTimer timer = new Windows.UI.Xaml.DispatcherTimer();
                TimeSpan ts = new TimeSpan(RetryTime * 1000);
                System.EventHandler <object> elapsedEvent = (TickSender, TickEventArgs) =>
                {
                    if (isRunning)
                    {
                        return;
                    }
                    try
                    {
                        isRunning = true;
                        using (MySqlConnection connectionFailed = new MySqlConnection(server.ConnectionString))
                        {
                            connectionFailed.Open();
                            server1.IsAvailable = true;
                            timer.Stop();
                        }
                    }
                    catch
                    {
                        MySqlTrace.LogWarning(0,
                                              string.Format(Properties.Resources.Replication_ConnectionAttemptFailed, server1.Name));
                    }
                    finally
                    {
                        isRunning = false;
                    }
                };
                timer.Tick += elapsedEvent;
                elapsedEvent(sender, null);
                timer.Start();
#endif
            };

            worker.RunWorkerAsync(server);
        }