summaryrefslogtreecommitdiff
path: root/sql/log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log.cc')
-rw-r--r--sql/log.cc73
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 */