Handling of large packets

- added int8_t MySQL_Protocol::generate_pkt_row2()
- fixed a memory leak

Bug fix on query cache
pull/317/head
René Cannaò 11 years ago
parent 9ca3bdf7e6
commit 00c906de1d

@ -69,6 +69,7 @@ class MySQL_Protocol {
// bool generate_pkt_field(MySQL_Data_Stream *myds, bool send, void **ptr, unsigned int *len, uint8_t sequence_id, char *schema, char *table, char *org_table, char *name, char *org_name, uint16_t charset, uint32_t column_length, uint8_t type, uint16_t flags, uint8_t decimals, bool field_list, uint64_t defvalue_length, char *defvalue);
bool generate_pkt_field(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, char *schema, char *table, char *org_table, char *name, char *org_name, uint16_t charset, uint32_t column_length, uint8_t type, uint16_t flags, uint8_t decimals, bool field_list, uint64_t defvalue_length, char *defvalue);
bool generate_pkt_row(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, int colnums, unsigned long *fieldslen, char **fieldstxt);
uint8_t generate_pkt_row2(unsigned int *len, uint8_t sequence_id, int colnums, unsigned long *fieldslen, char **fieldstxt);
// bool generate_pkt_initial_handshake(MySQL_Data_Stream *myds, bool send, void **ptr, unsigned int *len);
bool generate_pkt_initial_handshake(bool send, void **ptr, unsigned int *len, uint32_t *thread_id);
// bool generate_pkt_handshake_response(MySQL_Data_Stream *myds, bool send, void **ptr, unsigned int *len);

@ -1138,6 +1138,69 @@ bool MySQL_Protocol::generate_pkt_row(bool send, void **ptr, unsigned int *len,
return true;
}
uint8_t MySQL_Protocol::generate_pkt_row2(unsigned int *len, uint8_t sequence_id, int colnums, unsigned long *fieldslen, char **fieldstxt) {
int col=0;
unsigned int rowlen=0;
uint8_t pkt_sid=sequence_id;
for (col=0; col<colnums; col++) {
rowlen+=( fieldstxt[col] ? fieldslen[col]+mysql_encode_length(fieldslen[col],NULL) : 1 );
}
PtrSize_t pkt;
pkt.size=rowlen+sizeof(mysql_hdr);
pkt.ptr=l_alloc(pkt.size);
int l=sizeof(mysql_hdr);
for (col=0; col<colnums; col++) {
if (fieldstxt[col]) {
char length_prefix;
uint8_t length_len=mysql_encode_length(fieldslen[col], &length_prefix);
l+=write_encoded_length_and_string((unsigned char *)pkt.ptr+l,fieldslen[col],length_len, length_prefix, fieldstxt[col]);
} else {
char *_ptr=(char *)pkt.ptr;
_ptr[l]=0xfb;
l++;
}
}
if (pkt.size < (0xFFFFFF+sizeof(mysql_hdr))) {
mysql_hdr myhdr;
myhdr.pkt_id=pkt_sid;
myhdr.pkt_length=rowlen;
memcpy(pkt.ptr, &myhdr, sizeof(mysql_hdr));
(*myds)->PSarrayOUT->add(pkt.ptr,pkt.size);
} else {
unsigned int left=pkt.size;
unsigned int copied=0;
while (left>=(0xFFFFFF+sizeof(mysql_hdr))) {
PtrSize_t pkt2;
pkt2.size=0xFFFFFF+sizeof(mysql_hdr);
pkt2.ptr=l_alloc(pkt2.size);
memcpy((char *)pkt2.ptr+sizeof(mysql_hdr), (char *)pkt.ptr+sizeof(mysql_hdr)+copied, 0xFFFFFF);
mysql_hdr myhdr;
myhdr.pkt_id=pkt_sid;
pkt_sid++;
myhdr.pkt_length=0xFFFFFF;
memcpy(pkt2.ptr, &myhdr, sizeof(mysql_hdr));
(*myds)->PSarrayOUT->add(pkt2.ptr,pkt2.size);
copied+=0xFFFFFF;
left-=0xFFFFFF;
}
PtrSize_t pkt2;
pkt2.size=left;
pkt2.ptr=l_alloc(pkt2.size);
memcpy((char *)pkt2.ptr+sizeof(mysql_hdr), (char *)pkt.ptr+sizeof(mysql_hdr)+copied, left-sizeof(mysql_hdr));
mysql_hdr myhdr;
myhdr.pkt_id=pkt_sid;
myhdr.pkt_length=left-sizeof(mysql_hdr);
memcpy(pkt2.ptr, &myhdr, sizeof(mysql_hdr));
(*myds)->PSarrayOUT->add(pkt2.ptr,pkt2.size);
}
if (len) { *len=pkt.size+(pkt_sid-sequence_id)*sizeof(mysql_hdr); }
if (pkt.size >= (0xFFFFFF+sizeof(mysql_hdr))) {
l_free(pkt.size,pkt.ptr);
}
return pkt_sid;
}
//bool MySQL_Protocol::generate_pkt_handshake_response(MySQL_Data_Stream *myds, bool send, void **ptr, unsigned int *len) {
bool MySQL_Protocol::generate_pkt_handshake_response(bool send, void **ptr, unsigned int *len) {
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 7, "Generating response handshake pkt\n");

@ -333,6 +333,7 @@ __get_pkts_from_client:
memcpy(client_myds->multi_pkt.ptr, tmp_pkt.ptr, tmp_pkt.size);
memcpy((char *)client_myds->multi_pkt.ptr + tmp_pkt.size , (char *)pkt.ptr+sizeof(mysql_hdr) , pkt.size-sizeof(mysql_hdr)); // the header is not copied
l_free(tmp_pkt.size , tmp_pkt.ptr);
l_free(pkt.size , pkt.ptr);
}
if (pkt.size==(0xFFFFFF+sizeof(mysql_hdr))) { // there are more packets
goto __get_pkts_from_client;
@ -2077,13 +2078,13 @@ void MySQL_Session::MySQL_Result_to_MySQL_wire(MYSQL *mysql, MYSQL_RES *result,
// l[i]=result->rows[r]->sizes[i];
// p[i]=result->rows[r]->fields[i];
// }
myprot->generate_pkt_row(true,NULL,&pkt_length,sid,num_fields,lengths,row); sid++;
sid=myprot->generate_pkt_row2(&pkt_length,sid,num_fields,lengths,row); sid++;
client_myds->resultset_length+=pkt_length;
}
myds->DSS=STATE_ROW;
myprot->generate_pkt_EOF(true,NULL,&pkt_length,sid,0,2); sid++;
client_myds->resultset_length+=pkt_length;
if (qpo && qpo->cache_ttl>0 && mysql_error(mysql)==0) {
if (qpo && qpo->cache_ttl>0 && mysql_errno(mysql)==0) {
client_myds->resultset->copy_add(client_myds->PSarrayOUT,0,client_myds->PSarrayOUT->len);
unsigned char *aa=client_myds->resultset2buffer(false);
while (client_myds->resultset->len) client_myds->resultset->remove_index(client_myds->resultset->len-1,NULL);

@ -1252,7 +1252,6 @@ void MySQL_Thread::run() {
exit(EXIT_FAILURE);
}
if (__sync_add_and_fetch(&__global_MySQL_Thread_Variables_version,0) > __thread_MySQL_Thread_Variables_version) {
refresh_variables();
}

Loading…
Cancel
Save