-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
Copy pathlog_event.h
5420 lines (4639 loc) · 166 KB
/
log_event.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Copyright (c) 2009, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
/**
@addtogroup Replication
@{
@file
@brief Binary log event definitions. This includes generic code
common to all types of log events, as well as specific code for each
type of log event.
*/
#ifndef _log_event_h
#define _log_event_h
#if defined(USE_PRAGMA_INTERFACE) && defined(MYSQL_SERVER)
#pragma interface /* gcc class implementation */
#endif
#include <my_bitmap.h>
#include "rpl_constants.h"
#include <vector>
#include <string>
#include <functional>
#include <memory>
#include <map>
#include <lex_charset.h>
#ifdef MYSQL_CLIENT
#include "sql_const.h"
#include "rpl_utility.h"
#include "hash.h"
#include "rpl_tblmap.h"
#include "sql_string.h"
#endif
#ifdef MYSQL_SERVER
#include "rpl_record.h"
#include "rpl_reporting.h"
#include "sql_class.h" /* THD */
#endif
#include "rpl_gtid.h"
/* Forward declarations */
#ifndef MYSQL_CLIENT
class String;
#endif
#define PREFIX_SQL_LOAD "SQL_LOAD-"
#define LONG_FIND_ROW_THRESHOLD 60 /* seconds */
/**
Either assert or return an error.
In debug build, the condition will be checked, but in non-debug
builds, the error code given will be returned instead.
@param COND Condition to check
@param ERRNO Error number to return in non-debug builds
*/
#ifdef DBUG_OFF
#define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \
do { if (!(COND)) return ERRNO; } while (0)
#else
#define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \
DBUG_ASSERT(COND)
#endif
#define LOG_READ_EOF -1
#define LOG_READ_BOGUS -2
#define LOG_READ_IO -3
#define LOG_READ_MEM -5
#define LOG_READ_TRUNC -6
#define LOG_READ_TOO_LARGE -7
#define LOG_READ_CHECKSUM_FAILURE -8
#define LOG_READ_DECRYPT -9
#define LOG_EVENT_OFFSET 4
/*
3 is MySQL 4.x; 4 is MySQL 5.0.0.
Compared to version 3, version 4 has:
- a different Start_log_event, which includes info about the binary log
(sizes of headers); this info is included for better compatibility if the
master's MySQL version is different from the slave's.
- all events have a unique ID (the triplet (server_id, timestamp at server
start, other) to be sure an event is not executed more than once in a
multimaster setup, example:
M1
/ \
v v
M2 M3
\ /
v v
S
if a query is run on M1, it will arrive twice on S, so we need that S
remembers the last unique ID it has processed, to compare and know if the
event should be skipped or not. Example of ID: we already have the server id
(4 bytes), plus:
timestamp_when_the_master_started (4 bytes), a counter (a sequence number
which increments every time we write an event to the binlog) (3 bytes).
Q: how do we handle when the counter is overflowed and restarts from 0 ?
- Query and Load (Create or Execute) events may have a more precise
timestamp (with microseconds), number of matched/affected/warnings rows
and fields of session variables: SQL_MODE,
FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, SQL_AUTO_IS_NULL, the collations and
charsets, the PASSWORD() version (old/new/...).
*/
#define BINLOG_VERSION 4
/*
We could have used SERVER_VERSION_LENGTH, but this introduces an
obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
this would break the replication protocol
*/
#define ST_SERVER_VER_LEN 50
/*
These are flags and structs to handle all the LOAD DATA INFILE options (LINES
TERMINATED etc).
*/
/*
These are flags and structs to handle all the LOAD DATA INFILE options (LINES
TERMINATED etc).
DUMPFILE_FLAG is probably useless (DUMPFILE is a clause of SELECT, not of LOAD
DATA).
*/
#define DUMPFILE_FLAG 0x1
#define OPT_ENCLOSED_FLAG 0x2
#define REPLACE_FLAG 0x4
#define IGNORE_FLAG 0x8
#define FIELD_TERM_EMPTY 0x1
#define ENCLOSED_EMPTY 0x2
#define LINE_TERM_EMPTY 0x4
#define LINE_START_EMPTY 0x8
#define ESCAPED_EMPTY 0x10
#define NUM_LOAD_DELIM_STRS 5
/*****************************************************************************
MySQL Binary Log
This log consists of events. Each event has a fixed-length header,
possibly followed by a variable length data body.
The data body consists of an optional fixed length segment (post-header)
and an optional variable length segment.
See the #defines below for the format specifics.
The events which really update data are Query_log_event,
Execute_load_query_log_event and Execute_load_log_event events
(Execute_load_query is used together with Begin_load_query and Append_block
events to replicate LOAD DATA INFILE.
****************************************************************************/
#define LOG_EVENT_HEADER_LEN 19 /* the fixed header length */
/*
Fixed header length. That is, some future version may have a longer
header, but at least the first 19 bytes will be the same. So
LOG_EVENT_HEADER_LEN will be something like 26, but
LOG_EVENT_MINIMAL_HEADER_LEN will remain 19.
*/
#define LOG_EVENT_MINIMAL_HEADER_LEN 19
/* event-specific post-header sizes */
// where 3.23, 4.x and 5.0 agree
#define QUERY_HEADER_MINIMAL_LEN (4 + 4 + 1 + 2)
// where 5.0 differs: 2 for len of N-bytes vars.
#define QUERY_HEADER_LEN (QUERY_HEADER_MINIMAL_LEN + 2)
#define STOP_HEADER_LEN 0
#define LOAD_HEADER_LEN (4 + 4 + 4 + 1 +1 + 4)
#define SLAVE_HEADER_LEN 0
#define START_V3_HEADER_LEN (2 + ST_SERVER_VER_LEN + 4)
#define ROTATE_HEADER_LEN 8 // this is FROZEN (the Rotate post-header is frozen)
#define INTVAR_HEADER_LEN 0
#define CREATE_FILE_HEADER_LEN 4
#define APPEND_BLOCK_HEADER_LEN 4
#define EXEC_LOAD_HEADER_LEN 4
#define DELETE_FILE_HEADER_LEN 4
#define NEW_LOAD_HEADER_LEN LOAD_HEADER_LEN
#define RAND_HEADER_LEN 0
#define USER_VAR_HEADER_LEN 0
#define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
#define XID_HEADER_LEN 0
#define BEGIN_LOAD_QUERY_HEADER_LEN APPEND_BLOCK_HEADER_LEN
#define ROWS_HEADER_LEN_V1 8
#define TABLE_MAP_HEADER_LEN 8
#define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
#define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
#define INCIDENT_HEADER_LEN 2
#define HEARTBEAT_HEADER_LEN 0
#define IGNORABLE_HEADER_LEN 0
#define ROWS_HEADER_LEN_V2 10
#define ANNOTATE_ROWS_HEADER_LEN 0
#define BINLOG_CHECKPOINT_HEADER_LEN 4
#define GTID_HEADER_LEN 19
#define GTID_LIST_HEADER_LEN 4
#define START_ENCRYPTION_HEADER_LEN 0
#define XA_PREPARE_HEADER_LEN 0
/*
Max number of possible extra bytes in a replication event compared to a
packet (i.e. a query) sent from client to master;
First, an auxiliary log_event status vars estimation:
*/
#define MAX_SIZE_LOG_EVENT_STATUS (uint) \
(1 + 4 /* type, flags2 */ + \
1 + 8 /* type, sql_mode */ + \
1 + 1 + 255 /* type, length, catalog */ + \
1 + 4 /* type, auto_increment */ + \
1 + 6 /* type, charset */ + \
1 + 1 + 255 /* type, length, time_zone */ + \
1 + 2 /* type, lc_time_names_number */ + \
1 + 2 /* type, charset_database_number */ + \
1 + 8 /* type, table_map_for_update */ + \
1 + 4 /* type, master_data_written */ + \
1 + 3 /* type, sec_part of NOW() */ + \
1 + 16 + 1 + 60/* type, user_len, user, host_len, host */ + \
1 + 2 + 8 /* type, flags3, seq_no */ + \
1 + Charset_collation_map_st::binary_size_max() \
/* type, map */ \
)
#define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \
LOG_EVENT_HEADER_LEN + /* write_header */ \
QUERY_HEADER_LEN + /* write_data */ \
EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN + /*write_post_header_for_derived */ \
MAX_SIZE_LOG_EVENT_STATUS + /* status */ \
NAME_LEN + 1)
/*
The new option is added to handle large packets that are sent from the master
to the slave. It is used to increase the thd(max_allowed) for both the
DUMP thread on the master and the SQL/IO thread on the slave.
*/
#define MAX_MAX_ALLOWED_PACKET (1024*1024*1024)
/*
Event header offsets;
these point to places inside the fixed header.
*/
#define EVENT_TYPE_OFFSET 4
#define SERVER_ID_OFFSET 5
#define EVENT_LEN_OFFSET 9
#define LOG_POS_OFFSET 13
#define FLAGS_OFFSET 17
/* start event post-header (for v3 and v4) */
#define ST_BINLOG_VER_OFFSET 0
#define ST_SERVER_VER_OFFSET 2
#define ST_CREATED_OFFSET (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
#define ST_COMMON_HEADER_LEN_OFFSET (ST_CREATED_OFFSET + 4)
/* slave event post-header (this event is never written) */
#define SL_MASTER_PORT_OFFSET 8
#define SL_MASTER_POS_OFFSET 0
#define SL_MASTER_HOST_OFFSET 10
/* query event post-header */
#define Q_THREAD_ID_OFFSET 0
#define Q_EXEC_TIME_OFFSET 4
#define Q_DB_LEN_OFFSET 8
#define Q_ERR_CODE_OFFSET 9
#define Q_STATUS_VARS_LEN_OFFSET 11
#define Q_DATA_OFFSET QUERY_HEADER_LEN
/* these are codes, not offsets; not more than 256 values (1 byte). */
#define Q_FLAGS2_CODE 0
#define Q_SQL_MODE_CODE 1
/*
Q_CATALOG_CODE is catalog with end zero stored; it is used only by MySQL
5.0.x where 0<=x<=3. We have to keep it to be able to replicate these
old masters.
*/
#define Q_CATALOG_CODE 2
#define Q_AUTO_INCREMENT 3
#define Q_CHARSET_CODE 4
#define Q_TIME_ZONE_CODE 5
/*
Q_CATALOG_NZ_CODE is catalog withOUT end zero stored; it is used by MySQL
5.0.x where x>=4. Saves one byte in every Query_log_event in binlog,
compared to Q_CATALOG_CODE. The reason we didn't simply re-use
Q_CATALOG_CODE is that then a 5.0.3 slave of this 5.0.x (x>=4) master would
crash (segfault etc) because it would expect a 0 when there is none.
*/
#define Q_CATALOG_NZ_CODE 6
#define Q_LC_TIME_NAMES_CODE 7
#define Q_CHARSET_DATABASE_CODE 8
#define Q_TABLE_MAP_FOR_UPDATE_CODE 9
#define Q_MASTER_DATA_WRITTEN_CODE 10
#define Q_INVOKER 11
#define Q_HRNOW 128
#define Q_XID 129
#define Q_GTID_FLAGS3 130
#define Q_CHARACTER_SET_COLLATIONS 131
/* Intvar event post-header */
/* Intvar event data */
#define I_TYPE_OFFSET 0
#define I_VAL_OFFSET 1
/* Rand event data */
#define RAND_SEED1_OFFSET 0
#define RAND_SEED2_OFFSET 8
/* User_var event data */
#define UV_VAL_LEN_SIZE 4
#define UV_VAL_IS_NULL 1
#define UV_VAL_TYPE_SIZE 1
#define UV_NAME_LEN_SIZE 4
#define UV_CHARSET_NUMBER_SIZE 4
/* Load event post-header */
#define L_THREAD_ID_OFFSET 0
#define L_EXEC_TIME_OFFSET 4
#define L_SKIP_LINES_OFFSET 8
#define L_TBL_LEN_OFFSET 12
#define L_DB_LEN_OFFSET 13
#define L_NUM_FIELDS_OFFSET 14
#define L_SQL_EX_OFFSET 18
#define L_DATA_OFFSET LOAD_HEADER_LEN
/* Rotate event post-header */
#define R_POS_OFFSET 0
#define R_IDENT_OFFSET 8
/* CF to DF handle LOAD DATA INFILE */
/* CF = "Create File" */
#define CF_FILE_ID_OFFSET 0
#define CF_DATA_OFFSET CREATE_FILE_HEADER_LEN
/* AB = "Append Block" */
#define AB_FILE_ID_OFFSET 0
#define AB_DATA_OFFSET APPEND_BLOCK_HEADER_LEN
/* EL = "Execute Load" */
#define EL_FILE_ID_OFFSET 0
/* DF = "Delete File" */
#define DF_FILE_ID_OFFSET 0
/* TM = "Table Map" */
#define TM_MAPID_OFFSET 0
#define TM_FLAGS_OFFSET 6
/* RW = "RoWs" */
#define RW_MAPID_OFFSET 0
#define RW_FLAGS_OFFSET 6
#define RW_VHLEN_OFFSET 8
#define RW_V_TAG_LEN 1
#define RW_V_EXTRAINFO_TAG 0
/* ELQ = "Execute Load Query" */
#define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN
#define ELQ_FN_POS_START_OFFSET ELQ_FILE_ID_OFFSET + 4
#define ELQ_FN_POS_END_OFFSET ELQ_FILE_ID_OFFSET + 8
#define ELQ_DUP_HANDLING_OFFSET ELQ_FILE_ID_OFFSET + 12
/* 4 bytes which all binlogs should begin with */
#define BINLOG_MAGIC (const uchar*) "\xfe\x62\x69\x6e"
/*
The 2 flags below were useless :
- the first one was never set
- the second one was set in all Rotate events on the master, but not used for
anything useful.
So they are now removed and their place may later be reused for other
flags. Then one must remember that Rotate events in 4.x have
LOG_EVENT_FORCED_ROTATE_F set, so one should not rely on the value of the
replacing flag when reading a Rotate event.
I keep the defines here just to remember what they were.
*/
#ifdef TO_BE_REMOVED
#define LOG_EVENT_TIME_F 0x1
#define LOG_EVENT_FORCED_ROTATE_F 0x2
#endif
/*
This flag only makes sense for Format_description_log_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 already written
part of binlog). Thus it is a reliable indicator that binlog was
closed correctly. (Stop_log_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_log_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.
Note, that old binlogs does not have this flag set, so we get a
a backward-compatible behaviour.
*/
#define LOG_EVENT_BINLOG_IN_USE_F 0x1
/**
@def LOG_EVENT_THREAD_SPECIFIC_F
If the query depends on the thread (for example: TEMPORARY TABLE).
Currently this is used by mysqlbinlog to know it must print
SET @@PSEUDO_THREAD_ID=xx; before the query (it would not hurt to print it
for every query but this would be slow).
*/
#define LOG_EVENT_THREAD_SPECIFIC_F 0x4
/**
@def LOG_EVENT_SUPPRESS_USE_F
Suppress the generation of 'USE' statements before the actual
statement. This flag should be set for any events that does not need
the current database set to function correctly. Most notable cases
are 'CREATE DATABASE' and 'DROP DATABASE'.
This flags should only be used in exceptional circumstances, since
it introduce a significant change in behaviour regarding the
replication logic together with the flags --binlog-do-db and
--replicated-do-db.
*/
#define LOG_EVENT_SUPPRESS_USE_F 0x8
/*
Note: this is a place holder for the flag
LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F (0x10), which is not used any
more, please do not reused this value for other flags.
*/
/**
@def LOG_EVENT_ARTIFICIAL_F
Artificial events are created arbitrarily and not written to binary
log
These events should not update the master log position when slave
SQL thread executes them.
*/
#define LOG_EVENT_ARTIFICIAL_F 0x20
/**
@def LOG_EVENT_RELAY_LOG_F
Events with this flag set are created by slave IO thread and written
to relay log
*/
#define LOG_EVENT_RELAY_LOG_F 0x40
/**
@def LOG_EVENT_IGNORABLE_F
For an event, 'e', carrying a type code, that a slave,
's', does not recognize, 's' will check 'e' for
LOG_EVENT_IGNORABLE_F, and if the flag is set, then 'e'
is ignored. Otherwise, 's' acknowledges that it has
found an unknown event in the relay log.
*/
#define LOG_EVENT_IGNORABLE_F 0x80
/**
@def LOG_EVENT_ACCEPT_OWN_F
Flag sets by the semisync slave for accepting
the same server_id ("own") events which the slave must not have
in its state. Typically such events were never committed by
their originator (this server) and discared at its semisync-slave recovery.
*/
#define LOG_EVENT_ACCEPT_OWN_F 0x4000
/**
@def LOG_EVENT_SKIP_REPLICATION_F
Flag set by application creating the event (with @@skip_replication); the
slave will skip replication of such events if
--replicate-events-marked-for-skip is not set to REPLICATE.
This is a MariaDB flag; we allocate it from the end of the available
values to reduce risk of conflict with new MySQL flags.
*/
#define LOG_EVENT_SKIP_REPLICATION_F 0x8000
/**
@def OPTIONS_WRITTEN_TO_BIN_LOG
OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must
be written to the binlog. OPTIONS_WRITTEN_TO_BIN_LOG could be
written into the Format_description_log_event, so that if later we
don't want to replicate a variable we did replicate, or the
contrary, it's doable. But it should not be too hard to deduct
the value of OPTIONS_WRITTEN_TO_BIN_LOG from the master's version.
This is done in deduct_options_written_to_bin_log().
You *must* update it, when changing the definition below.
*/
#define OPTIONS_WRITTEN_TO_BIN_LOG (OPTION_EXPLICIT_DEF_TIMESTAMP |\
OPTION_AUTO_IS_NULL | OPTION_NO_FOREIGN_KEY_CHECKS | \
OPTION_RELAXED_UNIQUE_CHECKS | OPTION_NOT_AUTOCOMMIT | OPTION_IF_EXISTS |\
OPTION_INSERT_HISTORY)
#define CHECKSUM_CRC32_SIGNATURE_LEN 4
/**
defined statically while there is just one alg implemented
*/
#define BINLOG_CHECKSUM_LEN CHECKSUM_CRC32_SIGNATURE_LEN
#define BINLOG_CHECKSUM_ALG_DESC_LEN 1 /* 1 byte checksum alg descriptor */
/*
These are capability numbers for MariaDB slave servers.
Newer MariaDB slaves set this to inform the master about their capabilities.
This allows the master to decide which events it can send to the slave
without breaking replication on old slaves that maybe do not understand
all events from newer masters.
As new releases are backwards compatible, a given capability implies also
all capabilities with smaller number.
Older MariaDB slaves and other MySQL slave servers do not set this, so they
are recorded with capability 0.
*/
/* MySQL or old MariaDB slave with no announced capability. */
#define MARIA_SLAVE_CAPABILITY_UNKNOWN 0
/* MariaDB >= 5.3, which understands ANNOTATE_ROWS_EVENT. */
#define MARIA_SLAVE_CAPABILITY_ANNOTATE 1
/*
MariaDB >= 5.5. This version has the capability to tolerate events omitted
from the binlog stream without breaking replication (MySQL slaves fail
because they mis-compute the offsets into the master's binlog).
*/
#define MARIA_SLAVE_CAPABILITY_TOLERATE_HOLES 2
/* MariaDB >= 10.0, which knows about binlog_checkpoint_log_event. */
#define MARIA_SLAVE_CAPABILITY_BINLOG_CHECKPOINT 3
/* MariaDB >= 10.0.1, which knows about global transaction id events. */
#define MARIA_SLAVE_CAPABILITY_GTID 4
/* Our capability. */
#define MARIA_SLAVE_CAPABILITY_MINE MARIA_SLAVE_CAPABILITY_GTID
/*
When the size of 'log_pos' within Heartbeat_log_event exceeds UINT32_MAX it
cannot be accommodated in common_header, as 'log_pos' is of 4 bytes size. In
such cases, sub_header, of size 8 bytes will hold larger 'log_pos' value.
*/
#define HB_SUB_HEADER_LEN 8
/**
@enum Log_event_type
Enumeration type for the different types of log events.
*/
enum Log_event_type
{
/*
Every time you update this enum (when you add a type), you have to
fix Format_description_log_event::Format_description_log_event().
*/
UNKNOWN_EVENT= 0,
START_EVENT_V3= 1,
QUERY_EVENT= 2,
STOP_EVENT= 3,
ROTATE_EVENT= 4,
INTVAR_EVENT= 5,
LOAD_EVENT= 6,
SLAVE_EVENT= 7,
CREATE_FILE_EVENT= 8,
APPEND_BLOCK_EVENT= 9,
EXEC_LOAD_EVENT= 10,
DELETE_FILE_EVENT= 11,
NEW_LOAD_EVENT= 12,
RAND_EVENT= 13,
USER_VAR_EVENT= 14,
FORMAT_DESCRIPTION_EVENT= 15,
XID_EVENT= 16,
BEGIN_LOAD_QUERY_EVENT= 17,
EXECUTE_LOAD_QUERY_EVENT= 18,
TABLE_MAP_EVENT = 19,
/*
These event numbers were used for 5.1.0 to 5.1.15 and are
therefore obsolete.
*/
PRE_GA_WRITE_ROWS_EVENT = 20,
PRE_GA_UPDATE_ROWS_EVENT = 21,
PRE_GA_DELETE_ROWS_EVENT = 22,
/*
These event numbers are used from 5.1.16 until mysql-5.6.6,
and in MariaDB
*/
WRITE_ROWS_EVENT_V1 = 23,
UPDATE_ROWS_EVENT_V1 = 24,
DELETE_ROWS_EVENT_V1 = 25,
/*
Something out of the ordinary happened on the master
*/
INCIDENT_EVENT= 26,
/*
Heartbeat event to be send by master at its idle time
to ensure master's online status to slave
*/
HEARTBEAT_LOG_EVENT= 27,
/*
In some situations, it is necessary to send over ignorable
data to the slave: data that a slave can handle in case there
is code for handling it, but which can be ignored if it is not
recognized.
These mysql-5.6 events are not recognized (and ignored) by MariaDB
*/
IGNORABLE_LOG_EVENT= 28,
ROWS_QUERY_LOG_EVENT= 29,
/* Version 2 of the Row events, generated only by mysql-5.6.6+ */
WRITE_ROWS_EVENT = 30,
UPDATE_ROWS_EVENT = 31,
DELETE_ROWS_EVENT = 32,
/* MySQL 5.6 GTID events, ignored by MariaDB */
GTID_LOG_EVENT= 33,
ANONYMOUS_GTID_LOG_EVENT= 34,
PREVIOUS_GTIDS_LOG_EVENT= 35,
/* MySQL 5.7 events, ignored by MariaDB */
TRANSACTION_CONTEXT_EVENT= 36,
VIEW_CHANGE_EVENT= 37,
/* not ignored */
XA_PREPARE_LOG_EVENT= 38,
/*
Add new events here - right above this comment!
Existing events (except ENUM_END_EVENT) should never change their numbers
*/
/* New MySQL/Sun events are to be added right above this comment */
MYSQL_EVENTS_END,
MARIA_EVENTS_BEGIN= 160,
/* New Maria event numbers start from here */
ANNOTATE_ROWS_EVENT= 160,
/*
Binlog checkpoint event. Used for XA crash recovery on the master, not used
in replication.
A binlog checkpoint event specifies a binlog file such that XA crash
recovery can start from that file - and it is guaranteed to find all XIDs
that are prepared in storage engines but not yet committed.
*/
BINLOG_CHECKPOINT_EVENT= 161,
/*
Gtid event. For global transaction ID, used to start a new event group,
instead of the old BEGIN query event, and also to mark stand-alone
events.
*/
GTID_EVENT= 162,
/*
Gtid list event. Logged at the start of every binlog, to record the
current replication state. This consists of the last GTID seen for
each replication domain.
*/
GTID_LIST_EVENT= 163,
START_ENCRYPTION_EVENT= 164,
/*
Compressed binlog event.
Note that the order between WRITE/UPDATE/DELETE events is significant;
this is so that we can convert from the compressed to the uncompressed
event type with (type-WRITE_ROWS_COMPRESSED_EVENT + WRITE_ROWS_EVENT)
and similar for _V1.
*/
QUERY_COMPRESSED_EVENT = 165,
WRITE_ROWS_COMPRESSED_EVENT_V1 = 166,
UPDATE_ROWS_COMPRESSED_EVENT_V1 = 167,
DELETE_ROWS_COMPRESSED_EVENT_V1 = 168,
WRITE_ROWS_COMPRESSED_EVENT = 169,
UPDATE_ROWS_COMPRESSED_EVENT = 170,
DELETE_ROWS_COMPRESSED_EVENT = 171,
/* Add new MariaDB events here - right above this comment! */
ENUM_END_EVENT /* end marker */
};
/*
Bit flags for what has been writing to cache. Used to
discard logs with table map events but not row events and
nothing else important. This is stored by cache.
*/
enum enum_logged_status
{
LOGGED_TABLE_MAP= 1,
LOGGED_ROW_EVENT= 2,
LOGGED_NO_DATA= 4,
LOGGED_CRITICAL= 8
};
static inline bool LOG_EVENT_IS_QUERY(enum Log_event_type type)
{
return type == QUERY_EVENT || type == QUERY_COMPRESSED_EVENT;
}
static inline bool LOG_EVENT_IS_WRITE_ROW(enum Log_event_type type)
{
return type == WRITE_ROWS_EVENT || type == WRITE_ROWS_EVENT_V1 ||
type == WRITE_ROWS_COMPRESSED_EVENT ||
type == WRITE_ROWS_COMPRESSED_EVENT_V1;
}
static inline bool LOG_EVENT_IS_UPDATE_ROW(enum Log_event_type type)
{
return type == UPDATE_ROWS_EVENT || type == UPDATE_ROWS_EVENT_V1 ||
type == UPDATE_ROWS_COMPRESSED_EVENT ||
type == UPDATE_ROWS_COMPRESSED_EVENT_V1;
}
static inline bool LOG_EVENT_IS_DELETE_ROW(enum Log_event_type type)
{
return type == DELETE_ROWS_EVENT || type == DELETE_ROWS_EVENT_V1 ||
type == DELETE_ROWS_COMPRESSED_EVENT ||
type == DELETE_ROWS_COMPRESSED_EVENT_V1;
}
static inline bool LOG_EVENT_IS_ROW_COMPRESSED(enum Log_event_type type)
{
return type == WRITE_ROWS_COMPRESSED_EVENT ||
type == WRITE_ROWS_COMPRESSED_EVENT_V1 ||
type == UPDATE_ROWS_COMPRESSED_EVENT ||
type == UPDATE_ROWS_COMPRESSED_EVENT_V1 ||
type == DELETE_ROWS_COMPRESSED_EVENT ||
type == DELETE_ROWS_COMPRESSED_EVENT_V1;
}
static inline bool LOG_EVENT_IS_ROW_V2(enum Log_event_type type)
{
return (type >= WRITE_ROWS_EVENT && type <= DELETE_ROWS_EVENT) ||
(type >= WRITE_ROWS_COMPRESSED_EVENT && type <= DELETE_ROWS_COMPRESSED_EVENT);
}
/*
The number of types we handle in Format_description_log_event (UNKNOWN_EVENT
is not to be handled, it does not exist in binlogs, it does not have a
format).
*/
#define LOG_EVENT_TYPES (ENUM_END_EVENT-1)
enum Int_event_type
{
INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
};
#ifdef MYSQL_SERVER
class String;
class MYSQL_BIN_LOG;
class THD;
#endif
class Format_description_log_event;
class Relay_log_info;
class binlog_cache_data;
bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, FILE *file);
#ifdef MYSQL_CLIENT
enum enum_base64_output_mode {
BASE64_OUTPUT_NEVER= 0,
BASE64_OUTPUT_AUTO= 1,
BASE64_OUTPUT_UNSPEC= 2,
BASE64_OUTPUT_DECODE_ROWS= 3,
/* insert new output modes here */
BASE64_OUTPUT_MODE_COUNT
};
bool copy_event_cache_to_string_and_reinit(IO_CACHE *cache, LEX_STRING *to);
/*
A structure for mysqlbinlog to know how to print events
This structure is passed to the event's print() methods,
There are two types of settings stored here:
1. Last db, flags2, sql_mode etc comes from the last printed event.
They are stored so that only the necessary USE and SET commands
are printed.
2. Other information on how to print the events, e.g. short_form,
hexdump_from. These are not dependent on the last event.
*/
typedef struct st_print_event_info
{
/*
Settings for database, sql_mode etc that comes from the last event
that was printed. We cache these so that we don't have to print
them if they are unchanged.
*/
char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is
char charset[6]; // 3 variables, each of them storable in 2 bytes
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
char delimiter[16];
sql_mode_t sql_mode; /* must be same as THD.variables.sql_mode */
my_thread_id thread_id;
ulonglong row_events;
ulong auto_increment_increment, auto_increment_offset;
uint lc_time_names_number;
uint charset_database_number;
uint verbose;
uint32 flags2;
uint32 server_id;
uint32 domain_id;
uint8 common_header_len;
enum_base64_output_mode base64_output_mode;
my_off_t hexdump_from;
table_mapping m_table_map;
table_mapping m_table_map_ignored;
bool flags2_inited;
bool sql_mode_inited;
bool charset_inited;
bool thread_id_printed;
bool server_id_printed;
bool domain_id_printed;
bool allow_parallel;
bool allow_parallel_printed;
bool found_row_event;
bool print_row_count;
static const uint max_delimiter_size= 16;
/* Settings on how to print the events */
bool short_form;
/*
This is set whenever a Format_description_event is printed.
Later, when an event is printed in base64, this flag is tested: if
no Format_description_event has been seen, it is unsafe to print
the base64 event, so an error message is generated.
*/
bool printed_fd_event;
/*
Track when @@skip_replication changes so we need to output a SET
statement for it.
*/
bool skip_replication;
bool print_table_metadata;
/*
These two caches are used by the row-based replication events to
collect the header information and the main body of the events
making up a statement.
*/
IO_CACHE head_cache;
IO_CACHE body_cache;
IO_CACHE tail_cache;
#ifdef WHEN_FLASHBACK_REVIEW_READY
/* Storing the SQL for reviewing */
IO_CACHE review_sql_cache;
#endif
FILE *file;
/*
Used to include the events within a GTID start/stop boundary
*/
my_bool m_is_event_group_active;
/*
Tracks whether or not output events must be explicitly activated in order
to be printed
*/
my_bool m_is_event_group_filtering_enabled;
st_print_event_info();
~st_print_event_info() {
close_cached_file(&head_cache);
close_cached_file(&body_cache);
close_cached_file(&tail_cache);
#ifdef WHEN_FLASHBACK_REVIEW_READY
close_cached_file(&review_sql_cache);
#endif
}
bool init_ok() /* tells if construction was successful */
{ return my_b_inited(&head_cache) && my_b_inited(&body_cache)
#ifdef WHEN_FLASHBACK_REVIEW_READY
&& my_b_inited(&review_sql_cache)
#endif
; }
void flush_for_error()
{
if (!copy_event_cache_to_file_and_reinit(&head_cache, file))
copy_event_cache_to_file_and_reinit(&body_cache, file);
fflush(file);
}
/*
Notify that all events part of the current group should be printed
*/
void activate_current_event_group()
{
m_is_event_group_active= TRUE;
}
void deactivate_current_event_group()
{
m_is_event_group_active= FALSE;
}
/*
Used for displaying events part of an event group.
Returns TRUE when both event group filtering is enabled and the current
event group should be displayed, OR if event group filtering is
disabled. More specifically, if filtering is disabled, all events
should be shown.
Returns FALSE when event group filtering is enabled and the current event
group is filtered out.
*/
my_bool is_event_group_active()
{
return m_is_event_group_filtering_enabled ? m_is_event_group_active : TRUE;
}
/*
Notify that events must be explicitly activated in order to be printed
*/
void enable_event_group_filtering()
{
m_is_event_group_filtering_enabled= TRUE;
}
} PRINT_EVENT_INFO;
#endif
/**
This class encapsulates writing of Log_event objects to IO_CACHE.
Automatically calculates the checksum and encrypts the data, if necessary.
*/
class Log_event_writer
{
/* Log_event_writer is updated when ctx is set */
int (Log_event_writer::*encrypt_or_write)(const uchar *pos, size_t len);
public:
ulonglong bytes_written;
void *ctx; ///< Encryption context or 0 if no encryption is needed
uint checksum_len;
int write(Log_event *ev);
int write_header(uchar *pos, size_t len);
int write_data(const uchar *pos, size_t len);
int write_footer();
my_off_t pos() { return my_b_safe_tell(file); }
void add_status(enum_logged_status status);
void set_incident();
void set_encrypted_writer()