diff -r 7ff5d18dc66d django/db/backends/mysql/base.py
--- a/django/db/backends/mysql/base.py	Mon Jan 23 16:17:47 2012 +0000
+++ b/django/db/backends/mysql/base.py	Mon Jan 23 22:31:29 2012 -0300
@@ -47,6 +47,8 @@
 # It's impossible to import datetime_or_None directly from MySQLdb.times
 datetime_or_None = conversions[FIELD_TYPE.DATETIME]
 
+RETRIES = 1
+
 def datetime_or_None_with_timezone_support(value):
     dt = datetime_or_None(value)
     # Confirm that dt is naive before overwriting its tzinfo.
@@ -92,36 +94,55 @@
     """
     codes_for_integrityerror = (1048,)
 
-    def __init__(self, cursor):
+    def __init__(self, cursor, conn):
         self.cursor = cursor
+        self.django_conn = conn
 
     def execute(self, query, args=None):
-        try:
-            return self.cursor.execute(query, args)
-        except Database.IntegrityError, e:
-            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
-        except Database.OperationalError, e:
-            # Map some error codes to IntegrityError, since they seem to be
-            # misclassified and Django would prefer the more logical place.
-            if e[0] in self.codes_for_integrityerror:
+        attempt = 0
+        while True:
+            try:
+                return self.cursor.execute(query, args)
+            except Database.IntegrityError, e:
                 raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
-            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
-        except Database.DatabaseError, e:
-            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
+            except Database.OperationalError, e:
+                # Map some error codes to IntegrityError, since they seem to be
+                # misclassified and Django would prefer the more logical place.
+                if e[0] in self.codes_for_integrityerror:
+                    raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
+                #raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
+                if attempt < RETRIES:
+                    attempt += 1
+                    self.django_conn.reconnect()
+                else:
+                    raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
+            except Database.DatabaseError, e:
+                raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
+            else:
+                break
 
     def executemany(self, query, args):
-        try:
-            return self.cursor.executemany(query, args)
-        except Database.IntegrityError, e:
-            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
-        except Database.OperationalError, e:
-            # Map some error codes to IntegrityError, since they seem to be
-            # misclassified and Django would prefer the more logical place.
-            if e[0] in self.codes_for_integrityerror:
+        attempt = 0
+        while True:
+            try:
+                return self.cursor.executemany(query, args)
+            except Database.IntegrityError, e:
                 raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
-            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
-        except Database.DatabaseError, e:
-            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
+            except Database.OperationalError, e:
+                # Map some error codes to IntegrityError, since they seem to be
+                # misclassified and Django would prefer the more logical place.
+                if e[0] in self.codes_for_integrityerror:
+                    raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
+                #raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
+                if attempt < RETRIES:
+                    attempt += 1
+                    self.django_conn.reconnect()
+                else:
+                    raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
+            except Database.DatabaseError, e:
+                raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
+            else:
+                break
 
     def __getattr__(self, attr):
         if attr in self.__dict__:
@@ -344,46 +365,56 @@
                 self.connection = None
         return False
 
+    def reconnect(self):
+        """Connects or reconnects to the MySQL server"""
+        kwargs = {
+            'conv': django_conversions,
+            'charset': 'utf8',
+            'use_unicode': True,
+        }
+        settings_dict = self.settings_dict
+        if settings_dict['USER']:
+            kwargs['user'] = settings_dict['USER']
+        if settings_dict['NAME']:
+            kwargs['db'] = settings_dict['NAME']
+        if settings_dict['PASSWORD']:
+            kwargs['passwd'] = settings_dict['PASSWORD']
+        if settings_dict['HOST'].startswith('/'):
+            kwargs['unix_socket'] = settings_dict['HOST']
+        elif settings_dict['HOST']:
+            kwargs['host'] = settings_dict['HOST']
+        if settings_dict['PORT']:
+            kwargs['port'] = int(settings_dict['PORT'])
+        # We need the number of potentially affected rows after an
+        # "UPDATE", not the number of changed rows.
+        kwargs['client_flag'] = CLIENT.FOUND_ROWS
+        kwargs.update(settings_dict['OPTIONS'])
+        self.connection = Database.connect(**kwargs)
+        self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
+        self.connection.encoders[SafeString] = self.connection.encoders[str]
+        self.features.uses_savepoints = \
+            self.get_server_version() >= (5, 0, 3)
+        connection_created.send(sender=self.__class__, connection=self)
+
     def _cursor(self):
-        new_connection = False
-        if not self._valid_connection():
-            new_connection = True
-            kwargs = {
-                'conv': django_conversions,
-                'charset': 'utf8',
-                'use_unicode': True,
-            }
-            settings_dict = self.settings_dict
-            if settings_dict['USER']:
-                kwargs['user'] = settings_dict['USER']
-            if settings_dict['NAME']:
-                kwargs['db'] = settings_dict['NAME']
-            if settings_dict['PASSWORD']:
-                kwargs['passwd'] = settings_dict['PASSWORD']
-            if settings_dict['HOST'].startswith('/'):
-                kwargs['unix_socket'] = settings_dict['HOST']
-            elif settings_dict['HOST']:
-                kwargs['host'] = settings_dict['HOST']
-            if settings_dict['PORT']:
-                kwargs['port'] = int(settings_dict['PORT'])
-            # We need the number of potentially affected rows after an
-            # "UPDATE", not the number of changed rows.
-            kwargs['client_flag'] = CLIENT.FOUND_ROWS
-            kwargs.update(settings_dict['OPTIONS'])
-            self.connection = Database.connect(**kwargs)
-            self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
-            self.connection.encoders[SafeString] = self.connection.encoders[str]
-            self.features.uses_savepoints = \
-                self.get_server_version() >= (5, 0, 3)
-            connection_created.send(sender=self.__class__, connection=self)
-        cursor = self.connection.cursor()
-        if new_connection:
-            # SQL_AUTO_IS_NULL in MySQL controls whether an AUTO_INCREMENT column
-            # on a recently-inserted row will return when the field is tested for
-            # NULL.  Disabling this value brings this aspect of MySQL in line with
-            # SQL standards.
-            cursor.execute('SET SQL_AUTO_IS_NULL = 0')
-        return CursorWrapper(cursor)
+        attempt = 0
+        while True:
+            try:
+                cursor = self.connection.cursor()
+            except (AttributeError, Database.OperationalError), e:
+                if attempt < RETRIES:
+                    attempt += 1
+                    self.reconnect()
+                else:
+                    raise e
+            else:
+                # SQL_AUTO_IS_NULL in MySQL controls whether an AUTO_INCREMENT column
+                # on a recently-inserted row will return when the field is tested for
+                # NULL.  Disabling this value brings this aspect of MySQL in line with
+                # SQL standards.
+                cursor.execute('SET SQL_AUTO_IS_NULL = 0')
+                break
+        return CursorWrapper(cursor, self)
 
     def _rollback(self):
         try:
