MySQL

MySql connector/net 6.0 alpha has been released

MySQL Connector/Net 6.0.0, a new version of the all-managed .NET driver for MySQL has been released.  This is an alpha release and is intended to introduce you to the new features and enhancements we are planning.  This release should not be used in a production environment.

We had three major goals with this release.  Speed, Entity Framework support, and a better Visual Studio experience.  I’m happy to report that we have met all three.  Please see the complete list of changes below.

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/6.0.html] and mirror sites (note that not all mirror sites may be up to date at this point of time – if you can’t find this version on some mirror, please try again later or choose another download site.)

  • Massive speedups.  We have increased the speed of the provider.  In many situations it now matches or exceeds the speed of the native C connector.
  • SQL tokenizing has been improved dramatically.  Not only is it substantially faster (approx 40%) it also now uses a completely rewritten tokenizer that supports all types of stored procedure comments.
  • Added UDF schema collection
  • Implement initial Entity Framework support (see below)
  • Improved Visual Studio integration (see below)

Entity Framework support
Yes, we are late to the party but we are here.  I apologize for the delays related to this release and I hope that those of you looking to use MySQL with the entity framework will still want to give us a look.  This releases uses a entity framework engine that was completely developed in-house and is, therefore, licensed in exactly the same way as our core provider.  Please remember that this is an alpha release and we are certain that you will find databases that will not reverse-engineer correctly or you will build models or queries that will not generate correctly. Please file those as bug reports and include all the information you can.  We’ll quickly get to those as we are going to move as quickly as possible to GA.

Visual Studio improvements
Even though these improvements did not make the cutoff for this alpha, you will see them in the next drop.  We have completely rewritten our Visual Studio integration bits and are delivering several exciting features with it.  Here’s a look at some of those features:
1.  Now uses the same toolbars and commands as SQL Server so the integration is much more seamless.
2.  Uses the native code editor which means code splitting and syntax highlighting.
3.  Change script generation
4.  And many more smaller features…..

Please take this version for a test drive and let us know what works and what doesn’t.

MySQL connector/net 5.2.4 has been released

MySQL Connector/Net 5.2.4, a new version of the all-managed .NET driver for MySQL has been released.  This release is of GA quality and is suitable for  use in production environments.  We strongly urge you to  review the change log that is shipped with the product for a thorough review of the changes.

We have a ton of fixes in this release so please review the changelog and see if your favorite bug has been fixed.  Version 5.2.4 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1, and the MySQL-6.0 beta.

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/5.2.html] and mirror sites (note that not all mirror sites may be up to date at this point of time – if you can’t find this version on some mirror, please try again later or choose another download site.)

Changes since 5.2.3

  • fixed web providers autogenerateschema option where it would fail if no schema is   present at all (bug #39072)
  • backported fix for lingering problem related to bug #37239.  If two columns had the same name but different case then an exception would be thrown.
  • fixed stored procedure parameter parsing when used inside server explorer.  (bug #39252)
  • fixed time data type so that negative values are handled properly (bug #39275)
  • added runtime check for the mono platform to our Membership provider.  The mono runtime as of 1.9.1 did not support the methods needed for hashed passwords (bug #38895)
  • fixed problem where negative time values with a zero hour would return as positive values (bug #39294)
  • fixed problem where using a stored procedure with parameters with a table adapter was no longer working after our parameter schema changes (bug #39252)
  • fixed problem with profile provider where INSERT .. ON DUPLICATE UPDATE syntax would not work correctly with some older server versions (bug #39330)
  • Defaulting max allowed packet to 1024 to account for the possible case where the value doesn’t come in as a server variable
  • fixed bug #39728 by making MySqlConnectionStringBuilder.GetConnectionString an internal method.   It should not have been publicly available anyway.  It is used internally by the MySqlConnection.ConnectionString property
  • implemented Disposable pattern on MySqlTransaction class so including one in a using statement and then not calling commit will cause a rollback when the using exits (bug #39817)
  • fixed MySqlScript object so that it handles scripts with user variables
  • fixed bug where specifying ‘functions return string=yes’ would cause strings to be returned using the ‘binary’ charset which would not properly render some characters.  Now the connection character set is used. (bug #40076)
  • fixed problem that caused in use connection strings to be modified when a pooled connection timed out and was cancelled.  (bug #40091)
  • fixed problem where using respect binary flags would not use the connection char set and therefore return strings with a bad encoding.
  • fixed bug where provider was attempting to use the new parameters I_S view on servers that didn’t have it (bug #40382)
  • fixed problem where CharSetMap.GetDefaultCollation and CharSetMap.GetMaxLengths might have a thread sync issue on high load systems.  They were not locking the static collections there were initializing. (bug #40231)
  • added GetSByte to the reader for returning tinyint columns (bug #40571)

Thanks for using MySQL Connector/Net!

Using mysql with entity framework webinar

This past Tuesday I was doing more than just voting.  I was giving a live webinar on using MySQL with the Entity Framework.  We had a terrific time (demo machine crash included!) and had a great turnout.  I have been informed that we set records for most number of registrations and attendees.  I’m truly honored and hope that at least some of you got something out of it.

I’ve had a lot of people ask me for the materials from the session so I’ve made them available from my personal server.  You can get the slides, sample projects, and db script here.  The webinar was also recorded and will appear on this page eventually.

Thanks again to all who attended.  I’m hoping to give an expanded version of this session at our users conference in April.  I hope to see some of you there!

am I the last to figure this out?

In my role with Sun I do quite a bit with the Visual Studio SDK.  I develop our ADO.NET provider and the integration code that allows the provider to work inside of Visual Studio.  We support VS 2005 and 2008 with a single binary and, up until now, I’ve used the VS 2005 SDK.  But I’ve had this nagging feeling that I should be able to use the 2008 SDK and the new VSCT format for producing the CTO files.

After some research I discovered that VS 2008 ships with some binding redirects that allows it to use binaries built with the 2005 SDK.  Of course you can always count on Microsoft to make this as hard as possible.  They could keep in mind that out here in the real world we have to support older VS versions and ship the SDK with all necessary tools and assemblies.  But this is Microsoft we are talking about so the regpkg tool that ships with the SDK and helps with assembly registration is tightly bound to the SDK version. 

But the stupidity doesn’t end there.  With some hacking you can get around the regpkg issue (and you can’t ship that tool anyway) but they don’t provide attributes to handle all the registration tasks that are necessary.  Need to register your assembly as a DDEX data provider?  Out of luck.  Need to specify the technology parameter so your DDEX provider works with the proper wizards?  Out of luck.  So, I don’t really give a flip about regpkg and the attributes.

With all that said, I tested building an integration project with the 2008 SDK after making the following changes.  The resources worked great originating as VSCT files. 

   1: <RegisterOutputPackage>false</RegisterOutputPackage>
   2: <RegisterWithCodebase>true</RegisterWithCodebase>
   3: <!-- Make sure we are 2005 compatible, and don't rely on RegPkg.exe 
   4:      of VS2008 which uses Microsoft.VisualStudio.Shell.9.0 -->
   5: <UseVS2005MPF>true</UseVS2005MPF>
   6: <!-- Don't try to run as a normal user (RANA), 
   7:      create experimental hive in HKEY_LOCAL_MACHINE -->
   8: <RegisterWithRanu>false</RegisterWithRanu>

MySQL Connector/Net 5.1.7 has been released

MySQL Connector/Net 5.1.7 a new version of the all-managed .NET driver for MySQL has been released. This is a minor release involving mainly bug fixes.

Version 5.1.7 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 beta releases.

It is now available in source and binary form from [

Connector/Net 5.2.3 GA has been released

MySQL Connector/Net 5.2.3, a new version of the all-managed .NET driver for MySQL has been released.  This release is of GA quality and is suitable for  use in production environments.  We strongly urge you to  review the change log that is shipped with the product for a thorough review of the changes.

Version 5.2.3 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 Falcon “Preview”.

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/5.2.html] and mirror sites (note that not all mirror sites may be up to date at this point of time – if you can’t find this version on some mirror, please try again later or choose another download site.)

Changes since 5.2.2

  • Increased the speed of MySqlDataReader.GetOrdinal dramatically by using a couple of hashes for lookups
  • Fixed problem where some tables that support the web providers used the latin1 character set instead of the database default.  (bug #36444)
  • Changed how the procedure schema collection is retrieved.  If ‘use procedure bodies=true’ then we select on the mysql.proc table directly as this is up to 50x faster than our current IS implementation.  If ‘use procedure bodies=false’, then the IS collection is queried.  (bug #36694)
  • Fixed problem with our GetOrdinal speedup where we would attempt to add an already existing key to a hash when a resultset had more than 1 column with the same name. (bug #37239)
  • small fix to how we were allowing in/out and out parameters to slide through parameter serialization.  Before we were setting the AllowUserVariables connection setting but that had the unfortunate side effect of setting the value for all connections that shared that connection string.  This way we isolate it just to our particular command.  This may fix bug #37104
  • Fixed documentation surrounding use of ? vs @ for parameters (bug #37349)
  • Reduced network traffic for the normal case where the web provider schema is up to date (bug #37469)
  • Improved error reporting when a timeout occurs.  It no longer uses a message like ‘reading from stream failed’.  (bug #38119)
  • fixed problem where adding a non-existent user to a role would not auto-create the user record (bug #38243)
  • moved string escaping routine from the MySqlString class to the MySqlHelper class and made it public and static.  (bug #36205)
  • Fixed problem where column metadata was not being read with the correct character set  (bug #38721)
  • Fixed problem where the uninstall was not cleaning up the state files (bug #38534)
  • Added ‘Functions Return String’ connection string option
  • Several other fixes merged in from 5.0 and 5.1

Racing a jet engine

I've spent the last few days working on a support case where a customer was comparing the speed of Connector/Net with an application that uses our native C api.  His test was using a server side prepared statement to insert 3 sets of values in a loop that executed 600,000 times.  The table is a simple 3 column table and the SQL looks like this:

INSERT INTO test VALUES (@p1, @p2, @p3), (@p4, @p5, @p6), (@p7, @p8, @p9)

He was seeing 34,529 records / second using libmysql.dll but only about 24,000 records / second using Connector/Net.  He  understandably wanted to know why there was such a difference and if we could do something about it.  Absolutely!

We solved this problem through a combination of optimizations made to our code and some changes made to the testing application.  I won't say much about the optimizations.  We made some obvious changes like moving a lot more of the prepared statement work to the prepare phase and out of the execute phase.  We also discovered that BitConverter.ToBytes() is a lot slower than our hand-coded methods for reading and writing integer values.  We replaced usages of ArrayList with generic equivalents (it's pretty amazing how much faster generics are actually).

One of the bigger changes we made was to use a second hash for parameter name lookups.  When you are talking about loops with lots of iterations even the smallest inefficiencies can kill you.  Since .NET supports name lookup for parameters we use a hashtable to map parameter names to indices (we made this change when one of our customer was complaining that parameter lookup was slow on one of his commands that had > 30,000 parameters.  Yeah.).  Name lookup should be case-insensitive so we use a case-insensitive comparer with our hashtable.  So the optimization we made this time is to use two hash tables.  The first is case sensitive and is checked first.  If that fails then we check the second and return failure only if both fail.

That's what we did in our code.  We also made some changes to the testing app to make sure the comparison is truly apples to apples.  Let's first look at the loop code in each case.

C API

Connector/Net

			while (count < 600000)
			
			{
			
			    for (int row = 0; row < 3; ++row)
			
			    {
			
			        *(p1 + row) = count;
			
			        *(p2 + row) = count;
			
			        *(p3 + row) = count;
			
			        ++count;
			
			    }
			
			    mysql_stmt_execute(stmt);
			
			}
			

			while (count < numberOfRows)
			
			{
			
			    for (int row = 0; row < 3; ++row)
			
			    {
			
			        cmd.Parameters[row].Value = count;
			
			        cmd.Parameters[row+3].Value = count;
			
			        cmd.Parameters[row+6].Value = count++;
			
			    }
			
			    cmd.ExecuteNonQuery();
			
			}
			

Don't get hung up on the output of these being slightly different.  The point here is that the C code is using simple pointer arithmetic during each loop where the C# code is doing array lookup.  The array lookup code is quite a bit slower because the get accessor for the parameter collection does some bounds checking so that a nicer exception will be thrown in the event of an out-of-bounds index.
Another change that was made to the testing app was to disable the command timeout in the C# code.  This is a small point but when the command timeout is greater than zero then a timer is constructed and started during each execution.  In this case that is 600,000 timers!  Again, since the C code doesn't provide any type of command timeout it's not a true apples-to-apples comparison.

So, in a nutshell, benchmarking against libmysql is sort of like racing a jet engine.  Very fast but not a great deal of "safety features".  Still, after many hours with dotTrace the results speak for themselves.     
C app = 35,294 records per second.
C# app = 35,321 records per second.

How I found out that mixed mode is cool

We ship a DDEX provider with Connector/Net.  This provider plugs into Visual Studio and integrates into server explorer allowing a user to create data connections to MySQL from within the IDE.  This integration is handled, in large part, by a lengthy series of registry entries.  Until 5.2.2, these entries were made by my installer which is written in WiX.  Having the registry changes made in the installer has two problems.  First, I often need to register the provider during debugging and I don’t want to do a full install of the product so I end up hand editing a registry file and manually merging that file.  This a awkward at best.  Second I plan to ship a stand-alone configuration utility in 5.3 that will allow the user to configure which installed version of Connector/Net should be used for VS integration. Currently you can only have one instance installed at a time.

My approach to solving this was to write an installer class that made the registry changes for me and just use installutil to register the assembly.  I was already doing this with my core and web assemblies so this is nothing new.  The problem is that installutil will scan the assembly and all referenced assemblies for types looking for installer classes.  This fails when some of the Microsoft assemblies are scanned.  After much effort I gave up and decided to write my own installutil that I would ship with my installer. 

I had no trouble creating this application and then set about executing it from within my installer.  I attempted to use the CAQuietExec custom action available with WiX v3 but just couldn’t make it work right.  So I gave up and decided to write my own execute custom action.

So I cracked open Visual Studio 2008 and read a couple of blogs about custom action writing.  One of them mentioned mixing managed and unmanaged code, the unmanaged code being necessary for the proper DLL exports.  I decided I had to see this work.

Within minutes I had a DLL project setup with the /clr option and had hacked out the following code:

   1: extern "C" __declspec(dllexport) UINT InstallAssembly(MSIHANDLE hMSI)
   2: {
   3:     System::Windows::Forms::MessageBox::Show("boo");
   4:     TCHAR name[261]={0};
   5:     DWORD len=261;
   6:  
   7:     UINT result = ::MsiGetProperty(hMSI, TEXT("CustomActionData"), name, &len);
   8:     InstallVSAssembly(name, true);
   9:     return ERROR_SUCCESS;
  10: }
  11:  
  12: bool InstallVSAssembly(char *assemblyName)
  13: {
  14:     String^ str = gcnew String(assemblyName);
  15:     bool uninstalling = false;
  16:     IDictionary mySavedState = new Hashtable();
  17:     int arg = 0;
  18:  
  19:     InstallContext context = new InstallContext();
  20:     while (arg < args.Length)
  21:     {
  22:         string[] parts = args[arg++].Split('=');
  23:         context.Parameters.Add(parts[0], parts[1]);
  24:     }
  25:  
  26:     Installer installer = null;
  27:     try
  28:     {
  29:         Assembly assem = Assembly.LoadFrom(file);
  30:         installer = (Installer)assem.CreateInstance("MySql.Data.VisualStudio.MyInstaller");
  31:         if (installer == null)
  32:         {
  33:             Console.WriteLine("Unable to find an installer in that assembly.");
  34:             return;
  35:         }
  36:         installer.Context = context;
  37:         if (uninstalling)
  38:             installer.Uninstall(mySavedState);
  39:         else
  40:             installer.Install(mySavedState);
  41:     }
  42:     catch (Exception e)
  43:     {
  44:         Console.WriteLine(e.Message);
  45:     }
  46:     return true;

  47: }

Yes, that is managed code and unmanaged code *in the same function*!  Now this code might not compile as it is not what I wound up using and I just grabbed it out of an old folder but you get the idea (and yes I did test a version of this so I know the concept works).  I didn’t use this approach because the /clr switch requires the dynamic CRT and I didn’t feel like bundling that up.

And, in case you were wondering about the "boo" messagebox on line 3, that is my debugging trap.  You run the installer until that pops up, attach to the proper msiexec using Visual Studio, set a break point, and go.  Yup, that’s cool.

MySQL Connector/Net 5.1.6 has been released

Hi,
MySQL Connector/Net 5.1.6 a new version of the all-managed .NET driver for MySQL has been released. This is a minor release involving mainly bug fixes.
Version 5.1.6 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 Falcon "Preview".

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/5.1.html] and mirror sites (note that not all mirror sites may be up to date at this point of time – if you can’t find this version on some mirror, please try again later or choose another download site.)

Bugs fixed

  • Fixed problem where parameters lists were not showing when you tried to alter a routine in server explorer.  (bug #34359)
  • Fixed a problem in procedure cache where it was possible to get into a race condition and cause a memory leak (bug #34338)
  • Fixed problem where attempting to use an isolation level other than the default with a transaction scope would use the default instead (bug #34448)
  • Fixed problem that causes the TableAdapter wizard to only generate insert statements.  The problem was that our code to retrieve index columns was broken. (bug #31338)
  • Fixed problem with connections staying open after being used with SqlDataSource.  The problem was that we were not returning an enumerator for our reader with the  closeReader option set to true when we were supposed to.  (Bug #34460)
  • Fixed problem where the bit data type would continue to return null values once it saw a null value in a previous row (bug #36313)     
  • Fixed problem with MembershipUser.GetPassword where attempting to retrieve a  password on a user where password Q&A is not required would throw an exception (bug #36159)     
  • Fixed a problem with MembershipUser.GetNumberOfUsersOnline.  It actually works now  :) (bug #36157)
  • Fixed documentation that still stated that setting port to -1 was necessary for a named pipe connection (bug #35356)     
  • Fixed data type processing so that geometry fields are returned as binary.  (bug #36081)     
  • Fixed problem that kept our provider from showing up in the provider list when configuring a new connection from a SqlDataSource     
  • Fixed problem where setting the ConnectionString property of MySqlConnection to null would throw an exception (bug #35619)

Enjoy and thanks for the support!

MySQL Connector/Net 5.0.9 has been released

MySQL Connector/Net 5.0.9, a new version of the all-managed .NET driver for MySQL has been released. This release is an update to the existing production-quality 5.0 series.

We plan for this to be the last release in the 5.0 series. We will only be updating the 5.0 product in the event a "data-loss" type bug is discovered. We encourage all new products to use the new 5.1 product.

Version 5.0.9 works with all versions of MySQL including MySQL-4.1, MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 Alpha.

It is now available in source and binary form from here and mirror sites (note that not all mirror sites may be up to date at this point of time – if you can’t find this version on some mirror, please try again later or choose another download site.) 

Features or behavior changes

  • added implementation of MySqlCommandBuilder methods QuoteIdentifier and UnquoteIdentifier (bug #35492)

Bugs fixed

  • Fixed problem where fields that were blobs but did not include the BLOB flag were treated as binary when they should have been treated as text. (Bug #30233)

  • Changed from using Array.Copy to Buffer.BlockCopy in MySqlDataReader.GetBytes. This helps with memory usage as we expect the source and destination arrays to not be overlapping. (Bug #31090)
  • Fixed problem that prevented commands from being executed from the state change handler. Not sure why you would want to do this but… (bug #30964)
  • Fixed issue where column name metadata was not using the charset given on the connection string (Bug #31185)
  • Fixed problem with installer where the installation might report a failure to remove the performance counters if the performance counter category had already been removed for some reason
  • Fixed problem with installer where attempting to install over a failed uninstall could leave multiple clients registered in machine.config. (Bug #31731)
  • Fixed problem with connection string caching where our collection class was using case insensitive semantics and this causes cases where a user originally used the wrong case for a user id and then fixed it to still get access denied errors. (Bug #31433)
  • improved the speed of load data local infile significantly
  • fixed MySqlDateTime.ToString() to properly return the date value (Bug #32010)
  • fixed problem where string parameters who have their size set after their value could cause exceptions (Bug #32094)
  • fixed problem where old code was preventing creating parameter objects with non-input direction using just a constructor (Bug #32093)
  • fixed problem where a syntax error in a set of batch statements could leave the data adapter in a state that appears hung (bug #31930)
  • fixed the MySqlException class to set the server error code in the Data[] hash so that DbProviderFactory users can access the server error code (Bug #27436)
  • fixed problem where changing the connection string of a connection to one that changes the parameter marker after the connection had been assigned to a command but before the connection is opened can cause parameters to not be found (bug #13991)
  • some fixes to cancel and timeout operations so that they are more dependable
  • fixed problem where cloning a parameter that has not yet had its type set would yield a cloned parameter that would no longer infer it’s type from the value set
  • Go to Top