diff options
Diffstat (limited to 'sql/log.cc')
-rw-r--r-- | sql/log.cc | 73 |
1 files changed, 38 insertions, 35 deletions
diff --git a/sql/log.cc b/sql/log.cc index af8168c6a46..289d98e63d3 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1918,58 +1918,61 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry); /* next event header at ... */ - hdr_offs = LOG_EVENT_HEADER_LEN - carry + - uint4korr(&header[EVENT_LEN_OFFSET]); + hdr_offs = uint4korr(&header[EVENT_LEN_OFFSET]) - carry; carry= 0; } /* if there is anything to write, process it. */ - if(likely(length > 0)) + if (likely(length > 0)) { /* - next header beyond current read-buffer? we'll get it later - (though not necessarily in the very next iteration). + process all event-headers in this (partial) cache. + if next header is beyond current read-buffer, + we'll get it later (though not necessarily in the + very next iteration, just "eventually"). */ - if (hdr_offs >= length) - hdr_offs -= length; - else + while (hdr_offs < length) { + /* + partial header only? save what we can get, process once + we get the rest. + */ - /* process all event-headers in this (partial) cache. */ - - do { - - /* - partial header only? save what we can get, process once - we get the rest. - */ - - if (hdr_offs + LOG_EVENT_HEADER_LEN > length) - { - carry= length - hdr_offs; - memcpy(header, (char *)cache->read_pos + hdr_offs, carry); - length= hdr_offs; - } - else - { - /* we've got a full event-header, and it came in one piece */ + if (hdr_offs + LOG_EVENT_HEADER_LEN > length) + { + carry= length - hdr_offs; + memcpy(header, (char *)cache->read_pos + hdr_offs, carry); + length= hdr_offs; + } + else + { + /* we've got a full event-header, and it came in one piece */ - char *log_pos= (char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET; + char *log_pos= (char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET; - /* fix end_log_pos */ - val= uint4korr(log_pos) + group; - int4store(log_pos, val); + /* fix end_log_pos */ + val= uint4korr(log_pos) + group; + int4store(log_pos, val); - /* next event header at ... */ - log_pos= (char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET; - hdr_offs += uint4korr(log_pos); + /* next event header at ... */ + log_pos= (char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET; + hdr_offs += uint4korr(log_pos); - } - } while (hdr_offs < length); + } } + + /* + Adjust hdr_offs. Note that this doesn't mean it will necessarily + be valid in the next iteration; if the current event is very long, + it may take a couple of read-iterations (and subsequent fixings + of hdr_offs) for it to become valid again. + if we had a split header, hdr_offs was already fixed above. + */ + if (carry == 0) + hdr_offs -= length; } /* Write data to the binary log file */ |