• Most numeric fields use fixed-length encoding with little-endian byte order.

    • When you see 7a000000 in a hex dump, you read it as 0x0000007a = 122 in decimal.
  • All binary logs start with a magic fe62 696e. The first event starts at position 4.

$ xxd -l 4 binlog.000002
00000000: fe62 696e            .bin	

Common Header

  • Every event in the binary log (version 4+) shares a common 19-byte header structure.
    • Timestamp, 4 bytes, Unix epoch seconds when the event was created
    • Event Type, 1 byte, Identifies how to interpret the payload
    • Server ID, 4 bytes, The server that originated this event (prevents circular replication)
    • Event Size, 4 bytes, Total size of this event in bytes (header + payload)
    • Next Position, 4 bytes, File offset where the next event begins
    • Flags, 2 bytes, Event-specific flags (bit field)
offlenfield
04timestamp
41type (0x0f = FDE, 0x23 = prev_gtids, 0x22 = gtid, 0x02 = query, 0x13 = table_map, 0x1e/1f/20 = write/update/delete_rows v2, 0x04 = rotate, 0x10 = xid, 0x28 = tx_payload)
54server_id
94event_len (incl. header + 4-byte crc)
134next_pos (end_log_pos)
172flags ← bit 0 = IN_USE_F
$ xxd -s 4 -l 19 binlog.000002
00000004: 1a60 886a 0f6b 22c7 017b 0000 007f 0000  .`.j.k"..{......
00000014: 0001 00                                  ...

byte stream:

1a 60 88 6a | 0f | 6b 22 c7 01 | 7b 00 00 00 | 7f 00 00 00 | 01 00
fieldbytesLE value
timestamp1a 60 88 6a0x6a88601a = 1786732570 → 2026-08-10-ish utc
type0f15 = FORMAT_DESCRIPTION_EVENT
server_id6b 22 c7 010x01c7226b = 29893227
event_len7b 00 00 00123
next_pos7f 00 00 00127 (= 4 + 123, checks out)
flags01 000x0001 → IN_USE_F set

or using od:

od -An -tu4 -j 4  -N4 binlog.000002   # timestamp
od -An -tu1 -j 8  -N1 binlog.000002   # type
od -An -tu4 -j 9  -N4 binlog.000002   # server_id
od -An -tu4 -j 13 -N4 binlog.000002   # event_len
od -An -tu4 -j 17 -N4 binlog.000002   # next_pos
od -An -tu2 -j 21 -N2 binlog.000002   # flags

LOG_EVENT_BINLOG_IN_USE_F

This flag only makes sense for Format_description_event. It is set when the event is written, and reset when a binlog file is closed (yes, it’s the only case when MySQL modifies an already written part of the binlog). Thus it is a reliable indicator that the binlog was closed correctly. (Stop_event is not enough, there’s always a small chance that mysqld crashes in the middle of insert and end of the binlog would look like a Stop_event).

This flag is used to detect a restart after a crash, and to provide “unbreakable” binlog. The problem is that on a crash storage engines rollback automatically, while binlog does not. To solve this we use this flag and automatically append ROLLBACK to every non-closed binlog (append virtually, on reading, file itself is not changed). If this flag is found, mysqlbinlog simply prints “ROLLBACK”. Replication master does not abort on binlog corruption, but takes it as EOF, and replication slave forces a rollback in this case.

Source

If flag is set, mysqlbinlog will print this after Format_description_event:

#260821 17:26:34 server id 29827691  end_log_pos 127 CRC32 0x2201f07d   Start: binlog v 4, server v 8.4.10-10 created 260821 17:26:34 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
GmCIag9rIscBewAAAH8AAAABAAQAOC40LjEwLTEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAaYIhqEwANAAgAAAAABAAEAAAAYwAEGggAAAAAAAACAAAACgoKKioAEjQA
CigAAAF98AEi
'/*!*/;
# at 127

You can also check it with xxd:

$ xxd -s 21 -l 2 binlog.000002
00000015: 0100

Binlog_sender::send_format_description_event clears this flag before sending the event.

This flag makes the checksum of FD event invalid, the flag needs to be cleared before calculating the checksum:

In case this is a Format_description_log_event, we need to clear the LOG_EVENT_BINLOG_IN_USE_F flag before computing the checksum, since the flag will be cleared when the binlog is closed. On verification, the flag is dropped before computing the checksum too.

Source

HEARTBEAT_EVENT

MySQL Source Code Documentation

An artificial event generated by the master. It isn’t written to the relay logs.

It is added by the master after the replication connection was idle for x seconds to update the slave’s Seconds_behind_source timestamp in the SHOW REPLICA STATUS output.

It has no payload nor post-header.