Bug #3751 Out of memory error using ByteFX provider
Submitted: 13 May 2004 22:20 Modified: 8 Jul 2004 17:11
Reporter: Craig Hunt Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S1 (Critical)
Version:Version 0.76 OS:Microsoft Windows (Windows 2000/Debian Test rel)
Assigned to: Reggie Burnett CPU Architecture:Any

[13 May 2004 22:20] Craig Hunt
Description:
I'm using ASP.NET 2003 to develop a colaboration site that will allow registered users to upload files destined for a mysql 4.0.018 database running on a debian server.  The web site runs on a windows 2000 advanced server, sp4 (all current security patches applied), .NET Framework v1.1, and ByteFX Version 0.76 installed.

While testing the application, I encountered an error - "Exception of type System.OutOfMemoryException was thrown." - when executing the ExecuteNonQuery method of the MySqlCommand class attempting to insert a record containing a 73MB file.  I have successfully inserted a record using the driver for a 68.45 MB file, but my users may have the need to upload files as large as 100mb.

Here is the VB.NET routine that fails:

    Public Function SaveDoc(ByVal Action As RecordAction, Optional ByVal Userid As Integer = -1, Optional ByVal Description As String = NS, _
                      Optional ByVal Caption As String = NS, Optional ByVal CategoryID As Integer = -1, Optional ByVal Status As Integer = 1, _
                      Optional ByVal FileSize As Long = 0, Optional ByVal FileName As String = NS, Optional ByVal DocTypeID As Integer = -1, _
                      Optional ByVal Doc As Byte() = Nothing) As Boolean

        Dim bConn As MySqlConnection = New MySqlConnection("Database=marketing;Data Source=192.168.250.83;User Id=myid;Password=mypwd")
        bConn.Open()

        Dim strSQL As String = "INSERT INTO tblDocs (userid, descrip, caption, doc, modtime, categoryid, status, filesize, filename, doctypeid) " + _
                 "VALUES (@userid, @descrip, @caption, @doc, @modtime, @categoryid, @status, @filesize, @filename, @doctypeid)"
        Dim cmd As MySqlCommand = New MySqlCommand(strSQL, bConn)

        Dim tx As MySqlTransaction = bConn.BeginTransaction
        Try
            Select Case Action
                Case RecordAction.Insert

                    With cmd
                        .Transaction = tx
                        ' fill the parameters

                        .Parameters.Add("@userid", Userid)
                        .Parameters.Add("@descrip", Description)
                        .Parameters.Add("@caption", Caption)
                        .Parameters.Add("@doc", Doc)
                        .Parameters.Add("@modtime", Now())
                        .Parameters.Add("@categoryid", CategoryID)
                        .Parameters.Add("@status", Status)
                        .Parameters.Add("@filesize", FileSize)
                        .Parameters.Add("@filename", FileName)
                        .Parameters.Add("@doctypeid", DocTypeID)

                        ' send it to the database
                        .ExecuteNonQuery()		'<------- fails on this line
                    End With

                Case RecordAction.Update
                    '    ...
                Case RecordAction.Delete
                    '    ...
            End Select

            ' commit the changes
            tx.Commit()
            Return True

        Catch ex As Exception
            '  roll it back
            tx.Rollback()
            Throw New Exception(OOPS, ex)

        Finally

            cmd.Dispose()
            bConn.Close()
        End Try
End Function

Pertinent settings from my.cnf:

# The skip-networking option will no longer be set via debconf menu.
# You have to manually change it if you want networking i.e. the server
# listening on port 3306. The default is "disable" - for security reasons.
#skip-networking
key_buffer              = 100M
max_allowed_packet      = 100M
thread_stack            = 128K
#
# Query Cache Configuration
#
query_cache_limit       = 1048576
query_cache_size        = 26214400
query_cache_type        = 1

I initially tried using the myODBC driver, but it fails when attempting to upload files larger than 16MB. I've commented on the existing bug there, but it's currently deferred.

How to repeat:
Attempt to insert a blob larger than 68.45 MB using the ExecuteNonQuery method of the MySQLCommand class.
[17 Jun 2004 21:02] Evan Perry
Bugs 3872,3887, and 4120 are duplicates of this bug, as they are all caused by the same issue.  I've been able to track down the source of this problem.

Packet.cs, Line 181:
case 253 : return ReadInteger(intLen);

This line executed when retrieving a blob that was 900KB. intLen is 4 since that's the size of an integer.  However, I observed that the loop inside ReadInteger(), looped one too many times causing the correct file size to be multiplied by a big number.  This error propagates up and the application crashes when it tries to allocate a byte array that is over a gigabyte.  It worked for me to call ReadInteger(3) in this case.  I'm not familiar with all the code, so I don't know if there are other implications to this change.

Reggie, I hope this helps.  You should be able to make a far cleaner fix.
[8 Jul 2004 17:11] Reggie Burnett
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html