diff --git a/client/mysql.cc b/client/mysql.cc
index d46f18332ab3fcb3a992eefa325d72091d4a9cb4..b76a3d624abc5e8f616b527fcf23104221a4d029 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1280,21 +1280,35 @@ sig_handler handle_sigint(int sig)
   MYSQL *kill_mysql= NULL;
 
   /* terminate if no query being executed, or we already tried interrupting */
-  if (!executing_query || interrupted_query)
+  /* terminate if no query being executed, or we already tried interrupting */
+  if (!executing_query || (interrupted_query == 2))
+  {
+    tee_fprintf(stdout, "Ctrl-C -- exit!\n");
     goto err;
+  }
 
   kill_mysql= mysql_init(kill_mysql);
   if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
                           "", opt_mysql_port, opt_mysql_unix_port,0))
+  {
+    tee_fprintf(stdout, "Ctrl-C -- sorry, cannot connect to server to kill query, giving up ...\n");
     goto err;
+  }
+
+  interrupted_query++;
+
+  /* mysqld < 5 does not understand KILL QUERY, skip to KILL CONNECTION */
+  if ((interrupted_query == 1) && (mysql_get_server_version(&mysql) < 50000))
+    interrupted_query= 2;
 
   /* kill_buffer is always big enough because max length of %lu is 15 */
-  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql));
-  mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer));
+  sprintf(kill_buffer, "KILL %s%lu",
+          (interrupted_query == 1) ? "QUERY " : "",
+          mysql_thread_id(&mysql));
+  tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", kill_buffer);
+  mysql_real_query(kill_mysql, kill_buffer, (uint) strlen(kill_buffer));
   mysql_close(kill_mysql);
-  tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
-
-  interrupted_query= 1;
+  tee_fprintf(stdout, "Ctrl-C -- query aborted.\n");
 
   return;
 
diff --git a/mysql-test/extra/rpl_tests/rpl_stm_000001.test b/mysql-test/extra/rpl_tests/rpl_stm_000001.test
index 1f5eb5786dd2e25d16e27cb7f3032712164a363c..869a9e3b07c1ee841accee2e1d0a67f85503adf7 100644
--- a/mysql-test/extra/rpl_tests/rpl_stm_000001.test
+++ b/mysql-test/extra/rpl_tests/rpl_stm_000001.test
@@ -93,7 +93,7 @@ kill @id;
 # We don't drop t3 as this is a temporary table
 drop table t2;
 connection master;
---error 1053,2013
+--error 1317,2013
 reap;
 connection slave;
 # The SQL slave thread should now have stopped because the query was killed on
diff --git a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
index b9ab66165cc5701d07e32592760cf4aa82070098..e77cd308f39a85552ef823eef939652fe520a6a1 100644
--- a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
+++ b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
@@ -50,7 +50,7 @@ kill @id;
 drop table t2,t3;
 insert into t4 values (3),(4);
 connection master;
---error 0,1053,2013
+--error 0,1317,2013
 reap;
 connection master1;
 save_master_pos;
diff --git a/mysql-test/t/flush_read_lock_kill.test b/mysql-test/t/flush_read_lock_kill.test
index aeb09d524608d8f3841d83ff64a0aebfda5e5a8b..2d359383949d45a3dbade0d803af0b401fa89624 100644
--- a/mysql-test/t/flush_read_lock_kill.test
+++ b/mysql-test/t/flush_read_lock_kill.test
@@ -57,7 +57,7 @@ connection con1;
 # debug build running without our --debug=make_global..., will be
 # error 0 (no error). The only important thing to test is that on
 # debug builds with our --debug=make_global... we don't hang forever.
---error 0,1053,2013
+--error 0,1317,2013
 reap;
 
 connection con2;
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index 8ef668f542b24f9a04b879d54ef58b9ba01dd009..02b033df2e5c90dc3f124b69a23bcb3110642c1c 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -97,7 +97,7 @@ select ((@id := kill_id) - kill_id) from t3;
 kill @id;
 
 connection conn1;
--- error 1053,2013
+-- error 1317,2013
 reap;
 
 connection default;
diff --git a/sql/records.cc b/sql/records.cc
index 9e040de3fdae8e551e430f86a9956504f9203dfa..398dad42c4f661349235ba22c19aab432afe3d89 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -57,6 +57,7 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
 {
   empty_record(table);
   bzero((char*) info,sizeof(*info));
+  info->thd= thd;
   info->table= table;
   info->file=  table->file;
   info->record= table->record[0];
@@ -292,6 +293,12 @@ void end_read_record(READ_RECORD *info)
 
 static int rr_handle_error(READ_RECORD *info, int error)
 {
+  if (info->thd->killed)
+  {
+    info->thd->send_kill_message();
+    return 1;
+  }
+
   if (error == HA_ERR_END_OF_FILE)
     error= -1;
   else
@@ -312,12 +319,7 @@ static int rr_quick(READ_RECORD *info)
   int tmp;
   while ((tmp= info->select->quick->get_next()))
   {
-    if (info->thd->killed)
-    {
-      my_error(ER_SERVER_SHUTDOWN, MYF(0));
-      return 1;
-    }
-    if (tmp != HA_ERR_RECORD_DELETED)
+    if (info->thd->killed || (tmp != HA_ERR_RECORD_DELETED))
     {
       tmp= rr_handle_error(info, tmp);
       break;
@@ -380,16 +382,11 @@ int rr_sequential(READ_RECORD *info)
   int tmp;
   while ((tmp=info->file->rnd_next(info->record)))
   {
-    if (info->thd->killed)
-    {
-      info->thd->send_kill_message();
-      return 1;
-    }
     /*
       rnd_next can return RECORD_DELETED for MyISAM when one thread is
       reading and another deleting without locks.
     */
-    if (tmp != HA_ERR_RECORD_DELETED)
+    if (info->thd->killed || (tmp != HA_ERR_RECORD_DELETED))
     {
       tmp= rr_handle_error(info, tmp);
       break;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 865fc834c6876a3c33372c49c70be69dbc593897..f74524de60ec75177a72fa4b9127e718f3ae80d1 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -93,6 +93,8 @@ extern char internal_table_name[2];
 extern char empty_c_string[1];
 extern MYSQL_PLUGIN_IMPORT const char **errmesg;
 
+extern bool volatile shutdown_in_progress;
+
 #define TC_LOG_PAGE_SIZE   8192
 #define TC_LOG_MIN_SIZE    (3*TC_LOG_PAGE_SIZE)
 
@@ -2140,7 +2142,11 @@ public:
   {
     int err= killed_errno();
     if (err)
+    {
+      if ((err == KILL_CONNECTION) && !shutdown_in_progress)
+        err = KILL_QUERY;
       my_message(err, ER(err), MYF(0));
+    }
   }
   /* return TRUE if we will abort query if we make a warning now */
   inline bool really_abort_on_warning()