List:Commits« Previous MessageNext Message »
From:Dmitry Shulga Date:September 16 2010 10:38am
Subject:bzr commit into mysql-5.5-merge branch (Dmitry.Shulga:3206) Bug#42503
View as plain text  
#At file:///Users/shulga/projects/mysql/mysql-5.5-merge/ based on revid:mikael@dator8-20100916080410-9pd2sv3zreil1wy6

 3206 Dmitry Shulga	2010-09-16 [merge]
      Auto-merge from mysql-5.1-bugteam for bug#42503.

    modified:
      sql/net_serv.cc
      sql/sql_cache.cc
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc	2010-08-05 12:53:09 +0000
+++ b/sql/net_serv.cc	2010-09-16 10:38:13 +0000
@@ -164,7 +164,17 @@ my_bool net_realloc(NET *net, size_t len
   DBUG_ENTER("net_realloc");
   DBUG_PRINT("enter",("length: %lu", (ulong) length));
 
-  if (length >= net->max_packet_size)
+  /*
+    When compression is off, net->where_b is always 0.
+    With compression turned on, net->where_b may indicate
+    that we still have a piece of the previous logical
+    packet in the buffer, unprocessed. Take it into account
+    when checking that max_allowed_packet is not exceeded.
+    This ensures that the client treats max_allowed_packet
+    limit identically, regardless of compression being on
+    or off.
+  */
+  if (length >= (net->max_packet_size + net->where_b))
   {
     DBUG_PRINT("error", ("Packet too large. Max size: %lu",
                          net->max_packet_size));

=== modified file 'sql/sql_cache.cc'
--- a/sql/sql_cache.cc	2010-07-24 01:36:21 +0000
+++ b/sql/sql_cache.cc	2010-09-16 10:38:13 +0000
@@ -1346,6 +1346,55 @@ end:
 }
 
 
+/**
+  Send a single memory block from the query cache.
+
+  Respects the client/server protocol limits for the
+  size of the network packet, and splits a large block
+  in pieces to ensure that individual piece doesn't exceed
+  the maximal allowed size of the network packet (16M).
+
+  @param[in] net NET handler
+  @param[in] packet packet to send
+  @param[in] len packet length
+
+  @return Operation status
+    @retval FALSE On success
+    @retval TRUE On error
+*/
+static bool
+send_data_in_chunks(NET *net, const uchar *packet, ulong len)
+{
+  /*
+    On the client we may require more memory than max_allowed_packet
+    to keep, both, the truncated last logical packet, and the
+    compressed next packet.  This never (or in practice never)
+    happens without compression, since without compression it's very
+    unlikely that a) a truncated logical packet would remain on the
+    client when it's time to read the next packet b) a subsequent
+    logical packet that is being read would be so large that
+    size-of-new-packet + size-of-old-packet-tail >
+    max_allowed_packet.  To remedy this issue, we send data in 1MB
+    sized packets, that's below the current client default of 16MB
+    for max_allowed_packet, but large enough to ensure there is no
+    unnecessary overhead from too many syscalls per result set.
+  */
+  static const ulong MAX_CHUNK_LENGTH= 1024*1024;
+
+  while (len > MAX_CHUNK_LENGTH)
+  {
+    if (net_real_write(net, packet, MAX_CHUNK_LENGTH))
+      return TRUE;
+    packet+= MAX_CHUNK_LENGTH;
+    len-= MAX_CHUNK_LENGTH;
+  }
+  if (len && net_real_write(net, packet, len))
+    return TRUE;
+
+  return FALSE;
+}
+
+
 /*
   Check if the query is in the cache. If it was cached, send it
   to the user.
@@ -1655,11 +1704,11 @@ def_week_frmt: %lu, in_trans: %d, autoco
                                    ALIGN_SIZE(sizeof(Query_cache_result)))));
     
     Query_cache_result *result = result_block->result();
-    if (net_real_write(&thd->net, result->data(),
-		       result_block->used -
-		       result_block->headers_len() -
-		       ALIGN_SIZE(sizeof(Query_cache_result))))
-      break;					// Client aborted
+    if (send_data_in_chunks(&thd->net, result->data(),
+                            result_block->used -
+                            result_block->headers_len() -
+                            ALIGN_SIZE(sizeof(Query_cache_result))))
+      break;                                    // Client aborted
     result_block = result_block->next;
     thd->net.pkt_nr= query->last_pkt_nr; // Keep packet number updated
   } while (result_block != first_result_block);


Attachment: [text/bzr-bundle] bzr/dmitry.shulga@sun.com-20100916103813-fqtankzn3assllpk.bundle
Thread
bzr commit into mysql-5.5-merge branch (Dmitry.Shulga:3206) Bug#42503Dmitry Shulga16 Sep