From: Date: May 18 2006 8:46am Subject: bk commit into 5.0 tree (stewart:1.2125) BUG#13987 List-Archive: http://lists.mysql.com/commits/6549 X-Bug: 13987 Message-Id: <20060518064654.B66861410E2A@localhost.localdomain> Below is the list of changes that have just been committed into a local 5.0 repository of stewart. When stewart does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2125 06/05/18 16:46:48 stewart@stripped +1 -0 BUG#13987 Cluster: Loss of data nodes can cause high CPU usage from ndb_mgmd A further reduction in CPU usage by ndb_mgmd with failed data nodes. ndb/src/common/util/socket_io.cpp 1.8 06/05/18 16:46:40 stewart@stripped +39 -31 Use a nonblocking socket to peek at the buffer to know how much to read for socket_readln. This saves us a lot of syscalls. By a lot, I've observed about halving the CPU usage of ndb_mgmd with 1 failed node on a 6 node cluster. # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: stewart # Host: willster.(none) # Root: /home/stewart/Documents/MySQL/5.0/bug13987 --- 1.7/ndb/src/common/util/socket_io.cpp 2004-11-02 00:55:38 +11:00 +++ 1.8/ndb/src/common/util/socket_io.cpp 2006-05-18 16:46:40 +10:00 @@ -48,58 +48,66 @@ extern "C" int -readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, +readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, char * buf, int buflen){ if(buflen <= 1) return 0; + int sock_flags= fcntl(socket, F_GETFL); + if(fcntl(socket, F_SETFL, sock_flags | O_NONBLOCK) == -1) + return -1; + fd_set readset; FD_ZERO(&readset); FD_SET(socket, &readset); - + struct timeval timeout; timeout.tv_sec = (timeout_millis / 1000); timeout.tv_usec = (timeout_millis % 1000) * 1000; const int selectRes = select(socket + 1, &readset, 0, 0, &timeout); - if(selectRes == 0) + if(selectRes == 0){ return 0; - + } + if(selectRes == -1){ + fcntl(socket, F_SETFL, sock_flags); + return -1; + } + + buf[0] = 0; + const int t = recv(socket, buf, buflen, MSG_PEEK); + + if(t < 1) + { + fcntl(socket, F_SETFL, sock_flags); return -1; } - - int pos = 0; buf[pos] = 0; - while(true){ - const int t = recv(socket, &buf[pos], 1, 0); - if(t != 1){ - return -1; - } - if(buf[pos] == '\n'){ - buf[pos] = 0; - if(pos > 0 && buf[pos-1] == '\r'){ - pos--; - buf[pos] = 0; + for(int i=0; i< t;i++) + { + if(buf[i] == '\n'){ + recv(socket, buf, i+1, 0); + buf[i] = 0; + + if(i > 0 && buf[i-1] == '\r'){ + i--; + buf[i] = 0; } - return pos; - } - pos++; - if(pos == (buflen - 1)){ - buf[pos] = 0; - return buflen; - } - - FD_ZERO(&readset); - FD_SET(socket, &readset); - timeout.tv_sec = (timeout_millis / 1000); - timeout.tv_usec = (timeout_millis % 1000) * 1000; - const int selectRes = select(socket + 1, &readset, 0, 0, &timeout); - if(selectRes != 1){ - return -1; + fcntl(socket, F_SETFL, sock_flags); + return t; } } + + if(t == (buflen - 1)){ + recv(socket, buf, t, 0); + buf[t] = 0; + fcntl(socket, F_SETFL, sock_flags); + return buflen; + } + + return 0; } extern "C"