MDEV-8264 encryption for binlog
* Start_encryption_log_event * --encrypt-binlog command line option based on google patches.
This commit is contained in:
parent
41d68cabee
commit
b85a00161e
@ -2575,6 +2575,11 @@ void *sql_alloc(size_t size)
|
||||
return alloc_root(&s_mem_root, size);
|
||||
}
|
||||
|
||||
struct encryption_service_st encryption_handler=
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
We must include this here as it's compiled with different options for
|
||||
the server
|
||||
|
@ -10,19 +10,19 @@
|
||||
#
|
||||
# Format_description_log_event length =
|
||||
# 19 /* event common header */ +
|
||||
# 57 /* misc stuff in the Format description header */ +
|
||||
# 58 /* misc stuff in the Format description header */ +
|
||||
# number of events +
|
||||
# 1 /* Checksum algorithm */ +
|
||||
# 4 /* CRC32 length */
|
||||
#
|
||||
# With current number of events = 163,
|
||||
# With current number of events = 164,
|
||||
#
|
||||
# binlog_start_pos = 4 + 19 + 57 + 163 + 1 + 4 = 248.
|
||||
# binlog_start_pos = 4 + 19 + 57 + 163 + 1 + 4 = 249.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
let $binlog_start_pos=248;
|
||||
let $binlog_start_pos=249;
|
||||
--disable_query_log
|
||||
SET @binlog_start_pos=248;
|
||||
SET @binlog_start_pos=249;
|
||||
--enable_query_log
|
||||
|
||||
|
@ -4,7 +4,7 @@ if ($binlog_start)
|
||||
}
|
||||
if (!$binlog_start)
|
||||
{
|
||||
--let $_binlog_start=248
|
||||
--let $_binlog_start=249
|
||||
}
|
||||
if ($binlog_file)
|
||||
{
|
||||
|
@ -176,6 +176,8 @@ The following options may be given as the first argument:
|
||||
--div-precision-increment=#
|
||||
Precision of the result of '/' operator will be increased
|
||||
on that value
|
||||
--encrypt-binlog Encrypt binary logs (including relay logs)
|
||||
(Defaults to on; use --skip-encrypt-binlog to disable.)
|
||||
--encrypt-tmp-disk-tables
|
||||
Encrypt temporary on-disk tables (created as part of
|
||||
query execution)
|
||||
@ -1170,6 +1172,7 @@ delayed-insert-limit 100
|
||||
delayed-insert-timeout 300
|
||||
delayed-queue-size 1000
|
||||
div-precision-increment 4
|
||||
encrypt-binlog TRUE
|
||||
encrypt-tmp-disk-tables FALSE
|
||||
encrypt-tmp-files TRUE
|
||||
enforce-storage-engine (No default value)
|
||||
|
@ -71,7 +71,7 @@ insert into t1 values (1) /* will not be applied on slave due to simulation */;
|
||||
set @@global.debug_dbug='d,simulate_slave_unaware_checksum';
|
||||
start slave;
|
||||
include/wait_for_slave_io_error.inc [errno=1236]
|
||||
Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'Slave can not handle replication events with the checksum that master is configured to log; the first event 'master-bin.000009' at 367, the last event read from 'master-bin.000010' at 4, the last byte read from 'master-bin.000010' at 248.''
|
||||
Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'Slave can not handle replication events with the checksum that master is configured to log; the first event 'master-bin.000009' at 368, the last event read from 'master-bin.000010' at 4, the last byte read from 'master-bin.000010' at 249.''
|
||||
select count(*) as zero from t1;
|
||||
zero
|
||||
0
|
||||
|
@ -695,6 +695,20 @@ NUMERIC_BLOCK_SIZE 1
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
VARIABLE_NAME ENCRYPT_BINLOG
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE ON
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE ON
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE BOOLEAN
|
||||
VARIABLE_COMMENT Encrypt binary logs (including relay logs)
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
ENUM_VALUE_LIST OFF,ON
|
||||
READ_ONLY YES
|
||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||
VARIABLE_NAME ENCRYPT_TMP_DISK_TABLES
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE OFF
|
||||
|
@ -170,7 +170,7 @@
|
||||
VARIABLE_COMMENT Precision of the result of '/' operator will be increased on that value
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 30
|
||||
@@ -799,7 +799,7 @@
|
||||
@@ -813,7 +813,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 0
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -179,7 +179,7 @@
|
||||
VARIABLE_COMMENT If non-zero, binary logs will be purged after expire_logs_days days; possible purges happen at startup and at binary log rotation
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 99
|
||||
@@ -827,7 +827,7 @@
|
||||
@@ -841,7 +841,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -188,7 +188,7 @@
|
||||
VARIABLE_COMMENT The number of connections on extra-port
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 100000
|
||||
@@ -869,7 +869,7 @@
|
||||
@@ -883,7 +883,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 0
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -197,7 +197,7 @@
|
||||
VARIABLE_COMMENT A dedicated thread is created to flush all tables at the given interval
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 31536000
|
||||
@@ -911,7 +911,7 @@
|
||||
@@ -925,7 +925,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 84
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -206,7 +206,7 @@
|
||||
VARIABLE_COMMENT The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable
|
||||
NUMERIC_MIN_VALUE 10
|
||||
NUMERIC_MAX_VALUE 84
|
||||
@@ -925,7 +925,7 @@
|
||||
@@ -939,7 +939,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 4
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -215,7 +215,7 @@
|
||||
VARIABLE_COMMENT The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 84
|
||||
@@ -939,7 +939,7 @@
|
||||
@@ -953,7 +953,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 20
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -224,7 +224,7 @@
|
||||
VARIABLE_COMMENT Number of best matches to use for query expansion
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 1000
|
||||
@@ -998,7 +998,7 @@
|
||||
@@ -1012,7 +1012,7 @@
|
||||
VARIABLE_TYPE BIGINT UNSIGNED
|
||||
VARIABLE_COMMENT The maximum length of the result of function GROUP_CONCAT()
|
||||
NUMERIC_MIN_VALUE 4
|
||||
@ -233,7 +233,7 @@
|
||||
NUMERIC_BLOCK_SIZE 1
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
@@ -1233,7 +1233,7 @@
|
||||
@@ -1247,7 +1247,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 0
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -242,7 +242,7 @@
|
||||
VARIABLE_COMMENT Number of bytes used for a histogram. If set to 0, no histograms are created by ANALYZE.
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 255
|
||||
@@ -1261,7 +1261,7 @@
|
||||
@@ -1275,7 +1275,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 128
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -251,7 +251,7 @@
|
||||
VARIABLE_COMMENT How many host names should be cached to avoid resolving.
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 65536
|
||||
@@ -1373,7 +1373,7 @@
|
||||
@@ -1387,7 +1387,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 28800
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -260,7 +260,7 @@
|
||||
VARIABLE_COMMENT The number of seconds the server waits for activity on an interactive connection before closing it
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 31536000
|
||||
@@ -1404,7 +1404,7 @@
|
||||
@@ -1418,7 +1418,7 @@
|
||||
VARIABLE_TYPE BIGINT UNSIGNED
|
||||
VARIABLE_COMMENT The size of the buffer that is used for joins
|
||||
NUMERIC_MIN_VALUE 128
|
||||
@ -269,7 +269,7 @@
|
||||
NUMERIC_BLOCK_SIZE 128
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
@@ -1429,7 +1429,7 @@
|
||||
@@ -1443,7 +1443,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 2
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -278,7 +278,7 @@
|
||||
VARIABLE_COMMENT Controls what join operations can be executed with join buffers. Odd numbers are used for plain join buffers while even numbers are used for linked buffers
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 8
|
||||
@@ -1681,7 +1681,7 @@
|
||||
@@ -1695,7 +1695,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 31536000
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -287,7 +287,7 @@
|
||||
VARIABLE_COMMENT Timeout in seconds to wait for a lock before returning an error.
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 31536000
|
||||
@@ -1821,7 +1821,7 @@
|
||||
@@ -1835,7 +1835,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -296,7 +296,7 @@
|
||||
VARIABLE_COMMENT Write to slow log every #th slow query. Set to 1 to log everything. Increase it to reduce the size of the slow or the performance impact of slow logging
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -1849,7 +1849,7 @@
|
||||
@@ -1863,7 +1863,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -305,7 +305,7 @@
|
||||
VARIABLE_COMMENT Log some not critical warnings to the general log file.Value can be between 0 and 11. Higher values mean more verbosity
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -1905,7 +1905,7 @@
|
||||
@@ -1919,7 +1919,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1048576
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -314,7 +314,7 @@
|
||||
VARIABLE_COMMENT Max packet length to send to or receive from the server
|
||||
NUMERIC_MIN_VALUE 1024
|
||||
NUMERIC_MAX_VALUE 1073741824
|
||||
@@ -1915,14 +1915,14 @@
|
||||
@@ -1929,14 +1929,14 @@
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
VARIABLE_NAME MAX_BINLOG_CACHE_SIZE
|
||||
SESSION_VALUE NULL
|
||||
@ -332,7 +332,7 @@
|
||||
NUMERIC_BLOCK_SIZE 4096
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
@@ -1933,7 +1933,7 @@
|
||||
@@ -1947,7 +1947,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1073741824
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -341,7 +341,7 @@
|
||||
VARIABLE_COMMENT Binary log will be rotated automatically when the size exceeds this value.
|
||||
NUMERIC_MIN_VALUE 4096
|
||||
NUMERIC_MAX_VALUE 1073741824
|
||||
@@ -1943,14 +1943,14 @@
|
||||
@@ -1957,14 +1957,14 @@
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
VARIABLE_NAME MAX_BINLOG_STMT_CACHE_SIZE
|
||||
SESSION_VALUE NULL
|
||||
@ -359,7 +359,7 @@
|
||||
NUMERIC_BLOCK_SIZE 4096
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
@@ -1961,7 +1961,7 @@
|
||||
@@ -1975,7 +1975,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 151
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -368,7 +368,7 @@
|
||||
VARIABLE_COMMENT The number of simultaneous clients allowed
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 100000
|
||||
@@ -1975,7 +1975,7 @@
|
||||
@@ -1989,7 +1989,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 100
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -377,7 +377,7 @@
|
||||
VARIABLE_COMMENT If there is more than this number of interrupted connections from a host this host will be blocked from further connections
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -1989,7 +1989,7 @@
|
||||
@@ -2003,7 +2003,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 20
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -386,7 +386,7 @@
|
||||
VARIABLE_COMMENT Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero INSERT DELAYED will be not used
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 16384
|
||||
@@ -2017,7 +2017,7 @@
|
||||
@@ -2031,7 +2031,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 64
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -395,7 +395,7 @@
|
||||
VARIABLE_COMMENT Max number of errors/warnings to store for a statement
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 65535
|
||||
@@ -2034,7 +2034,7 @@
|
||||
@@ -2048,7 +2048,7 @@
|
||||
VARIABLE_TYPE BIGINT UNSIGNED
|
||||
VARIABLE_COMMENT Don't allow creation of heap tables bigger than this
|
||||
NUMERIC_MIN_VALUE 16384
|
||||
@ -404,7 +404,7 @@
|
||||
NUMERIC_BLOCK_SIZE 1024
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
@@ -2045,7 +2045,7 @@
|
||||
@@ -2059,7 +2059,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 20
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -413,7 +413,7 @@
|
||||
VARIABLE_COMMENT Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero INSERT DELAYED will be not used
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 16384
|
||||
@@ -2073,7 +2073,7 @@
|
||||
@@ -2087,7 +2087,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1024
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -422,7 +422,7 @@
|
||||
VARIABLE_COMMENT Max number of bytes in sorted records
|
||||
NUMERIC_MIN_VALUE 4
|
||||
NUMERIC_MAX_VALUE 8388608
|
||||
@@ -2087,7 +2087,7 @@
|
||||
@@ -2101,7 +2101,7 @@
|
||||
GLOBAL_VALUE_ORIGIN AUTO
|
||||
DEFAULT_VALUE 1048576
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -431,7 +431,7 @@
|
||||
VARIABLE_COMMENT The maximum BLOB length to send to server from mysql_send_long_data API. Deprecated option; use max_allowed_packet instead.
|
||||
NUMERIC_MIN_VALUE 1024
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -2101,7 +2101,7 @@
|
||||
@@ -2115,7 +2115,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 16382
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -440,7 +440,7 @@
|
||||
VARIABLE_COMMENT Maximum number of prepared statements in the server
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2129,7 +2129,7 @@
|
||||
@@ -2143,7 +2143,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 4294967295
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -449,7 +449,7 @@
|
||||
VARIABLE_COMMENT Limit assumed max number of seeks when looking up rows based on a key
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -2143,7 +2143,7 @@
|
||||
@@ -2157,7 +2157,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1024
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -458,7 +458,7 @@
|
||||
VARIABLE_COMMENT The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored)
|
||||
NUMERIC_MIN_VALUE 4
|
||||
NUMERIC_MAX_VALUE 8388608
|
||||
@@ -2157,7 +2157,7 @@
|
||||
@@ -2171,7 +2171,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 0
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -467,7 +467,7 @@
|
||||
VARIABLE_COMMENT Maximum stored procedure recursion depth
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 255
|
||||
@@ -2185,7 +2185,7 @@
|
||||
@@ -2199,7 +2199,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 32
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -476,7 +476,7 @@
|
||||
VARIABLE_COMMENT Unused, will be removed.
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -2213,7 +2213,7 @@
|
||||
@@ -2227,7 +2227,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 4294967295
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -485,7 +485,7 @@
|
||||
VARIABLE_COMMENT After this many write locks, allow some read locks to run in between
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -2227,7 +2227,7 @@
|
||||
@@ -2241,7 +2241,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1024
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -494,7 +494,7 @@
|
||||
VARIABLE_COMMENT Unused
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2241,7 +2241,7 @@
|
||||
@@ -2255,7 +2255,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 8
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -503,7 +503,7 @@
|
||||
VARIABLE_COMMENT Unused
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 1024
|
||||
@@ -2255,7 +2255,7 @@
|
||||
@@ -2269,7 +2269,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 0
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -512,7 +512,7 @@
|
||||
VARIABLE_COMMENT Don't write queries to slow log that examine fewer rows than that
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -2269,7 +2269,7 @@
|
||||
@@ -2283,7 +2283,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 262144
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -521,7 +521,7 @@
|
||||
VARIABLE_COMMENT Size of buffer to use when using MRR with range access
|
||||
NUMERIC_MIN_VALUE 8192
|
||||
NUMERIC_MAX_VALUE 2147483647
|
||||
@@ -2283,10 +2283,10 @@
|
||||
@@ -2297,10 +2297,10 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 256
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -534,7 +534,7 @@
|
||||
NUMERIC_BLOCK_SIZE 1
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
@@ -2297,7 +2297,7 @@
|
||||
@@ -2311,7 +2311,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1024
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -543,7 +543,7 @@
|
||||
VARIABLE_COMMENT Block size to be used for MyISAM index pages
|
||||
NUMERIC_MIN_VALUE 1024
|
||||
NUMERIC_MAX_VALUE 16384
|
||||
@@ -2311,7 +2311,7 @@
|
||||
@@ -2325,7 +2325,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 6
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -552,7 +552,7 @@
|
||||
VARIABLE_COMMENT Default pointer size to be used for MyISAM tables
|
||||
NUMERIC_MIN_VALUE 2
|
||||
NUMERIC_MAX_VALUE 7
|
||||
@@ -2321,9 +2321,9 @@
|
||||
@@ -2335,9 +2335,9 @@
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
VARIABLE_NAME MYISAM_MAX_SORT_FILE_SIZE
|
||||
SESSION_VALUE NULL
|
||||
@ -564,7 +564,7 @@
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE BIGINT UNSIGNED
|
||||
VARIABLE_COMMENT Don't use the fast sort index method to created index if the temporary file would get bigger than this
|
||||
@@ -2335,14 +2335,14 @@
|
||||
@@ -2349,14 +2349,14 @@
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
VARIABLE_NAME MYISAM_MMAP_SIZE
|
||||
SESSION_VALUE NULL
|
||||
@ -582,7 +582,7 @@
|
||||
NUMERIC_BLOCK_SIZE 1
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY YES
|
||||
@@ -2367,10 +2367,10 @@
|
||||
@@ -2381,10 +2381,10 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -595,7 +595,7 @@
|
||||
NUMERIC_BLOCK_SIZE 1
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
@@ -2384,7 +2384,7 @@
|
||||
@@ -2398,7 +2398,7 @@
|
||||
VARIABLE_TYPE BIGINT UNSIGNED
|
||||
VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE
|
||||
NUMERIC_MIN_VALUE 4096
|
||||
@ -604,7 +604,7 @@
|
||||
NUMERIC_BLOCK_SIZE 1
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
@@ -2437,7 +2437,7 @@
|
||||
@@ -2451,7 +2451,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 16384
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -613,7 +613,7 @@
|
||||
VARIABLE_COMMENT Buffer length for TCP/IP and socket communication
|
||||
NUMERIC_MIN_VALUE 1024
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2451,7 +2451,7 @@
|
||||
@@ -2465,7 +2465,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 30
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -622,7 +622,7 @@
|
||||
VARIABLE_COMMENT Number of seconds to wait for more data from a connection before aborting the read
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 31536000
|
||||
@@ -2465,7 +2465,7 @@
|
||||
@@ -2479,7 +2479,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 10
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -631,7 +631,7 @@
|
||||
VARIABLE_COMMENT If a read on a communication port is interrupted, retry this many times before giving up
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -2479,7 +2479,7 @@
|
||||
@@ -2493,7 +2493,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 60
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -640,7 +640,7 @@
|
||||
VARIABLE_COMMENT Number of seconds to wait for a block to be written to a connection before aborting the write
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 31536000
|
||||
@@ -2549,7 +2549,7 @@
|
||||
@@ -2563,7 +2563,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -649,7 +649,7 @@
|
||||
VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 1
|
||||
@@ -2563,7 +2563,7 @@
|
||||
@@ -2577,7 +2577,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 62
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -658,7 +658,7 @@
|
||||
VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to 63, the optimizer will switch to the original find_best search. NOTE: The value 63 and its associated behaviour is deprecated
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 63
|
||||
@@ -2577,7 +2577,7 @@
|
||||
@@ -2591,7 +2591,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 100
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -667,7 +667,7 @@
|
||||
VARIABLE_COMMENT Controls number of record samples to check condition selectivity
|
||||
NUMERIC_MIN_VALUE 10
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
@@ -2605,7 +2605,7 @@
|
||||
@@ -2619,7 +2619,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1
|
||||
VARIABLE_SCOPE SESSION
|
||||
@ -676,7 +676,7 @@
|
||||
VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples
|
||||
NUMERIC_MIN_VALUE 1
|
||||
NUMERIC_MAX_VALUE 5
|
||||
@@ -2633,7 +2633,7 @@
|
||||
@@ -2647,7 +2647,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -685,7 +685,7 @@
|
||||
VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2647,7 +2647,7 @@
|
||||
@@ -2661,7 +2661,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -694,7 +694,7 @@
|
||||
VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 200
|
||||
@@ -2661,7 +2661,7 @@
|
||||
@@ -2675,7 +2675,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -703,7 +703,7 @@
|
||||
VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2675,7 +2675,7 @@
|
||||
@@ -2689,7 +2689,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -712,7 +712,7 @@
|
||||
VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1024
|
||||
@@ -2689,7 +2689,7 @@
|
||||
@@ -2703,7 +2703,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -721,7 +721,7 @@
|
||||
VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2703,7 +2703,7 @@
|
||||
@@ -2717,7 +2717,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -730,7 +730,7 @@
|
||||
VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1024
|
||||
@@ -2717,7 +2717,7 @@
|
||||
@@ -2731,7 +2731,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -739,7 +739,7 @@
|
||||
VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2731,7 +2731,7 @@
|
||||
@@ -2745,7 +2745,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -748,7 +748,7 @@
|
||||
VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1024
|
||||
@@ -2745,7 +2745,7 @@
|
||||
@@ -2759,7 +2759,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -757,7 +757,7 @@
|
||||
VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2759,7 +2759,7 @@
|
||||
@@ -2773,7 +2773,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 80
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -766,7 +766,7 @@
|
||||
VARIABLE_COMMENT Maximum number of condition instruments.
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 256
|
||||
@@ -2773,7 +2773,7 @@
|
||||
@@ -2787,7 +2787,7 @@
|
||||
GLOBAL_VALUE_ORIGIN CONFIG
|
||||
DEFAULT_VALUE -1
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
@ -775,7 +775,7 @@
|
||||
VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing.
|
||||
NUMERIC_MIN_VALUE -1
|
||||
NUMERIC_MAX_VALUE 1048576
|
||||
@@ -2787,7 +2787,7 @@
|
||||
@@ -2801,7 +2801,7 @@
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 1024
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
|
@ -709,6 +709,20 @@ NUMERIC_BLOCK_SIZE 1
|
||||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
VARIABLE_NAME ENCRYPT_BINLOG
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE ON
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE ON
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE BOOLEAN
|
||||
VARIABLE_COMMENT Encrypt binary logs (including relay logs)
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
ENUM_VALUE_LIST OFF,ON
|
||||
READ_ONLY YES
|
||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||
VARIABLE_NAME ENCRYPT_TMP_DISK_TABLES
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE OFF
|
||||
|
100
sql/log.cc
100
sql/log.cc
@ -3457,6 +3457,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
|
||||
else
|
||||
s.checksum_alg= (enum_binlog_checksum_alg)binlog_checksum_options;
|
||||
|
||||
crypto.scheme = 0;
|
||||
DBUG_ASSERT(s.checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
|
||||
if (!s.is_valid())
|
||||
goto err;
|
||||
@ -3465,6 +3466,26 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
|
||||
goto err;
|
||||
bytes_written+= s.data_written;
|
||||
|
||||
if (encrypt_binlog)
|
||||
{
|
||||
uint key_version= encryption_key_get_latest_version(ENCRYPTION_KEY_SYSTEM_DATA);
|
||||
if (key_version != ENCRYPTION_KEY_VERSION_INVALID &&
|
||||
key_version != ENCRYPTION_KEY_NOT_ENCRYPTED)
|
||||
{
|
||||
if (my_random_bytes(crypto.nonce, sizeof(crypto.nonce)))
|
||||
goto err;
|
||||
|
||||
Start_encryption_log_event sele(1, key_version, crypto.nonce);
|
||||
sele.checksum_alg= s.checksum_alg;
|
||||
if (write_event(&sele))
|
||||
goto err;
|
||||
|
||||
// Start_encryption_log_event is written, enable the encryption
|
||||
if (crypto.init(sele.crypto_scheme, key_version))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_relay_log)
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
@ -5107,7 +5128,10 @@ end:
|
||||
|
||||
bool MYSQL_BIN_LOG::write_event(Log_event *ev, IO_CACHE *file)
|
||||
{
|
||||
Log_event_writer writer(file);
|
||||
Log_event_writer writer(file, &crypto);
|
||||
if (crypto.scheme && file == &log_file)
|
||||
writer.ctx= alloca(crypto.ctx_size);
|
||||
|
||||
return writer.write(ev);
|
||||
}
|
||||
|
||||
@ -5145,32 +5169,62 @@ err:
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...)
|
||||
bool MYSQL_BIN_LOG::write_event_buffer(uchar* buf, uint len)
|
||||
{
|
||||
bool error= 0;
|
||||
DBUG_ENTER("MYSQL_BIN_LOG::appendv");
|
||||
va_list(args);
|
||||
va_start(args,len);
|
||||
bool error= 1;
|
||||
uchar *ebuf= 0;
|
||||
DBUG_ENTER("MYSQL_BIN_LOG::write_event_buffer");
|
||||
|
||||
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
|
||||
|
||||
mysql_mutex_assert_owner(&LOCK_log);
|
||||
do
|
||||
|
||||
if (crypto.scheme != 0)
|
||||
{
|
||||
if (my_b_append(&log_file,(uchar*) buf,len))
|
||||
{
|
||||
error= 1;
|
||||
DBUG_ASSERT(crypto.scheme == 1);
|
||||
|
||||
uint elen;
|
||||
uchar iv[BINLOG_IV_LENGTH];
|
||||
|
||||
ebuf= (uchar*)my_safe_alloca(len);
|
||||
if (!ebuf)
|
||||
goto err;
|
||||
}
|
||||
bytes_written += len;
|
||||
} while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
|
||||
|
||||
crypto.set_iv(iv, my_b_append_tell(&log_file));
|
||||
|
||||
/*
|
||||
we want to encrypt everything, excluding the event length:
|
||||
massage the data before the encryption
|
||||
*/
|
||||
memcpy(buf + EVENT_LEN_OFFSET, buf, 4);
|
||||
|
||||
if (encryption_crypt(buf + 4, len - 4,
|
||||
ebuf + 4, &elen,
|
||||
crypto.key, crypto.key_length, iv, sizeof(iv),
|
||||
ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD,
|
||||
ENCRYPTION_KEY_SYSTEM_DATA, crypto.key_version))
|
||||
goto err;
|
||||
|
||||
DBUG_ASSERT(elen == len - 4);
|
||||
|
||||
/* massage the data after the encryption */
|
||||
memcpy(ebuf, ebuf + EVENT_LEN_OFFSET, 4);
|
||||
int4store(ebuf + EVENT_LEN_OFFSET, len);
|
||||
|
||||
buf= ebuf;
|
||||
}
|
||||
if (my_b_append(&log_file, buf, len))
|
||||
goto err;
|
||||
bytes_written+= len;
|
||||
|
||||
error= 0;
|
||||
DBUG_PRINT("info",("max_size: %lu",max_size));
|
||||
if (flush_and_sync(0))
|
||||
goto err;
|
||||
if (my_b_append_tell(&log_file) > max_size)
|
||||
error= new_file_without_locking();
|
||||
err:
|
||||
my_safe_afree(ebuf, len);
|
||||
if (!error)
|
||||
signal_update();
|
||||
DBUG_RETURN(error);
|
||||
@ -6533,8 +6587,9 @@ class CacheWriter: public Log_event_writer
|
||||
public:
|
||||
ulong remains;
|
||||
|
||||
CacheWriter(THD *thd_arg, IO_CACHE *file_arg, bool do_checksum)
|
||||
: Log_event_writer(file_arg), remains(0), thd(thd_arg), first(true)
|
||||
CacheWriter(THD *thd_arg, IO_CACHE *file_arg, bool do_checksum,
|
||||
Binlog_crypt_data *cr)
|
||||
: Log_event_writer(file_arg, cr), remains(0), thd(thd_arg), first(true)
|
||||
{ checksum_len= do_checksum ? BINLOG_CHECKSUM_LEN : 0; }
|
||||
|
||||
~CacheWriter()
|
||||
@ -6585,7 +6640,10 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
|
||||
long val;
|
||||
ulong end_log_pos_inc= 0; // each event processed adds BINLOG_CHECKSUM_LEN 2 t
|
||||
uchar header[LOG_EVENT_HEADER_LEN];
|
||||
CacheWriter writer(thd, &log_file, binlog_checksum_options);
|
||||
CacheWriter writer(thd, &log_file, binlog_checksum_options, &crypto);
|
||||
|
||||
if (crypto.scheme)
|
||||
writer.ctx= alloca(crypto.ctx_size);
|
||||
|
||||
// while there is just one alg the following must hold:
|
||||
DBUG_ASSERT(binlog_checksum_options == BINLOG_CHECKSUM_ALG_OFF ||
|
||||
@ -9670,6 +9728,13 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name,
|
||||
break;
|
||||
#endif
|
||||
|
||||
case START_ENCRYPTION_EVENT:
|
||||
{
|
||||
if (fdle->start_decryption((Start_encryption_log_event*) ev))
|
||||
goto err2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Nothing. */
|
||||
break;
|
||||
@ -9746,6 +9811,7 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name,
|
||||
sql_print_error("Error reading binlog files during recovery. Aborting.");
|
||||
goto err2;
|
||||
}
|
||||
fdle->reset_crypto();
|
||||
}
|
||||
|
||||
if (do_xa)
|
||||
|
@ -527,6 +527,9 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
|
||||
ulonglong group_commit_trigger_count, group_commit_trigger_timeout;
|
||||
ulonglong group_commit_trigger_lock_wait;
|
||||
|
||||
/* binlog encryption data */
|
||||
struct Binlog_crypt_data crypto;
|
||||
|
||||
/* pointer to the sync period variable, for binlog this will be
|
||||
sync_binlog_period, for relay log this will be
|
||||
sync_relay_log_period
|
||||
@ -740,11 +743,7 @@ public:
|
||||
bool write_event(Log_event *ev, IO_CACHE *file);
|
||||
bool write_event(Log_event *ev) { return write_event(ev, &log_file); }
|
||||
|
||||
/*
|
||||
v stands for vector
|
||||
invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
|
||||
*/
|
||||
bool appendv(const char* buf,uint len,...);
|
||||
bool write_event_buffer(uchar* buf,uint len);
|
||||
bool append(Log_event* ev);
|
||||
bool append_no_lock(Log_event* ev);
|
||||
|
||||
|
324
sql/log_event.cc
324
sql/log_event.cc
@ -816,6 +816,7 @@ const char* Log_event::get_type_str(Log_event_type type)
|
||||
case BINLOG_CHECKPOINT_EVENT: return "Binlog_checkpoint";
|
||||
case GTID_EVENT: return "Gtid";
|
||||
case GTID_LIST_EVENT: return "Gtid_list";
|
||||
case START_ENCRYPTION_EVENT: return "Start_encryption";
|
||||
default: return "Unknown"; /* impossible */
|
||||
}
|
||||
}
|
||||
@ -1129,8 +1130,9 @@ my_bool Log_event::need_checksum()
|
||||
the local RL's Rotate and the master's Rotate
|
||||
which IO thread instantiates via queue_binlog_ver_3_event.
|
||||
*/
|
||||
get_type_code() == ROTATE_EVENT
|
||||
|| /* FD is always checksummed */
|
||||
get_type_code() == ROTATE_EVENT ||
|
||||
get_type_code() == START_ENCRYPTION_EVENT ||
|
||||
/* FD is always checksummed */
|
||||
get_type_code() == FORMAT_DESCRIPTION_EVENT) &&
|
||||
checksum_alg != BINLOG_CHECKSUM_ALG_OFF));
|
||||
|
||||
@ -1152,6 +1154,53 @@ int Log_event_writer::write_internal(const uchar *pos, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
as soon as encryption produces the first output block, write event_len
|
||||
where it should be in a valid event header
|
||||
*/
|
||||
int Log_event_writer::maybe_write_event_len(uchar *pos, size_t len)
|
||||
{
|
||||
if (len && event_len)
|
||||
{
|
||||
DBUG_ASSERT(len >= EVENT_LEN_OFFSET);
|
||||
if (write_internal(pos + EVENT_LEN_OFFSET - 4, 4))
|
||||
return 1;
|
||||
int4store(pos + EVENT_LEN_OFFSET - 4, event_len);
|
||||
event_len= 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Log_event_writer::encrypt_and_write(const uchar *pos, size_t len)
|
||||
{
|
||||
uchar *dst= 0;
|
||||
size_t dstsize= 0;
|
||||
|
||||
if (ctx)
|
||||
{
|
||||
dstsize= encryption_encrypted_length(len, ENCRYPTION_KEY_SYSTEM_DATA,
|
||||
crypto->key_version);
|
||||
if (!(dst= (uchar*)my_safe_alloca(dstsize)))
|
||||
return 1;
|
||||
|
||||
uint dstlen;
|
||||
if (encryption_ctx_update(ctx, pos, len, dst, &dstlen))
|
||||
goto err;
|
||||
if (maybe_write_event_len(dst, dstlen))
|
||||
return 1;
|
||||
pos= dst;
|
||||
len= dstlen;
|
||||
}
|
||||
if (write_internal(pos, len))
|
||||
goto err;
|
||||
|
||||
my_safe_afree(dst, dstsize);
|
||||
return 0;
|
||||
err:
|
||||
my_safe_afree(dst, dstsize);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Log_event_writer::write_header(uchar *pos, size_t len)
|
||||
{
|
||||
DBUG_ENTER("write_footer");
|
||||
@ -1169,7 +1218,23 @@ int Log_event_writer::write_header(uchar *pos, size_t len)
|
||||
pos[FLAGS_OFFSET]= save;
|
||||
}
|
||||
|
||||
return write_internal(pos, len);
|
||||
if (ctx)
|
||||
{
|
||||
uchar iv[BINLOG_IV_LENGTH];
|
||||
crypto->set_iv(iv, my_b_safe_tell(file));
|
||||
if (encryption_ctx_init(ctx, crypto->key, crypto->key_length,
|
||||
iv, sizeof(iv), ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD,
|
||||
ENCRYPTION_KEY_SYSTEM_DATA, crypto->key_version))
|
||||
return 1;
|
||||
|
||||
DBUG_ASSERT(len >= LOG_EVENT_HEADER_LEN);
|
||||
event_len= uint4korr(pos + EVENT_LEN_OFFSET);
|
||||
DBUG_ASSERT(event_len >= len);
|
||||
memcpy(pos + EVENT_LEN_OFFSET, pos, 4);
|
||||
pos+= 4;
|
||||
len-= 4;
|
||||
}
|
||||
return encrypt_and_write(pos, len);
|
||||
}
|
||||
|
||||
int Log_event_writer::write_data(const uchar *pos, size_t len)
|
||||
@ -1177,7 +1242,7 @@ int Log_event_writer::write_data(const uchar *pos, size_t len)
|
||||
if (checksum_len)
|
||||
crc= my_checksum(crc, pos, len);
|
||||
|
||||
return write_internal(pos, len);
|
||||
return encrypt_and_write(pos, len);
|
||||
}
|
||||
|
||||
int Log_event_writer::write_footer()
|
||||
@ -1187,7 +1252,16 @@ int Log_event_writer::write_footer()
|
||||
{
|
||||
uchar checksum_buf[BINLOG_CHECKSUM_LEN];
|
||||
int4store(checksum_buf, crc);
|
||||
if (write_internal(checksum_buf, BINLOG_CHECKSUM_LEN))
|
||||
if (encrypt_and_write(checksum_buf, BINLOG_CHECKSUM_LEN))
|
||||
DBUG_RETURN(ER_ERROR_ON_WRITE);
|
||||
}
|
||||
if (ctx)
|
||||
{
|
||||
uint dstlen;
|
||||
uchar dst[MY_AES_BLOCK_SIZE*2];
|
||||
if (encryption_ctx_finish(ctx, dst, &dstlen))
|
||||
DBUG_RETURN(1);
|
||||
if (maybe_write_event_len(dst, dstlen) || write_internal(dst, dstlen))
|
||||
DBUG_RETURN(ER_ERROR_ON_WRITE);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
@ -1262,6 +1336,7 @@ bool Log_event::write_header(ulong event_data_length)
|
||||
*/
|
||||
|
||||
int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||
const Format_description_log_event *fdle,
|
||||
enum enum_binlog_checksum_alg checksum_alg_arg)
|
||||
{
|
||||
ulong data_len;
|
||||
@ -1299,7 +1374,7 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||
opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
|
||||
DBUG_RETURN(LOG_READ_TOO_LARGE);
|
||||
|
||||
if (data_len > LOG_EVENT_MINIMAL_HEADER_LEN)
|
||||
if (likely(data_len > LOG_EVENT_MINIMAL_HEADER_LEN))
|
||||
{
|
||||
/* Append rest of event, read directly from file into packet */
|
||||
if (packet->append(file, data_len - LOG_EVENT_MINIMAL_HEADER_LEN))
|
||||
@ -1319,7 +1394,42 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||
DBUG_RETURN(my_errno == ENOMEM ? LOG_READ_MEM :
|
||||
(file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
|
||||
}
|
||||
}
|
||||
|
||||
if (fdle->crypto_data.scheme)
|
||||
{
|
||||
uchar iv[BINLOG_IV_LENGTH];
|
||||
fdle->crypto_data.set_iv(iv, my_b_tell(file) - data_len);
|
||||
|
||||
char *newpkt= (char*)my_malloc(data_len + ev_offset + 1, MYF(MY_WME));
|
||||
if (!newpkt)
|
||||
DBUG_RETURN(LOG_READ_MEM);
|
||||
memcpy(newpkt, packet->ptr(), ev_offset);
|
||||
|
||||
uint dstlen;
|
||||
uchar *src= (uchar*)packet->ptr() + ev_offset;
|
||||
uchar *dst= (uchar*)newpkt + ev_offset;
|
||||
memcpy(src + EVENT_LEN_OFFSET, src, 4);
|
||||
if (encryption_crypt(src + 4, data_len - 4, dst + 4, &dstlen,
|
||||
fdle->crypto_data.key, fdle->crypto_data.key_length, iv,
|
||||
sizeof(iv), ENCRYPTION_FLAG_DECRYPT | ENCRYPTION_FLAG_NOPAD,
|
||||
ENCRYPTION_KEY_SYSTEM_DATA, fdle->crypto_data.key_version))
|
||||
{
|
||||
my_free(newpkt);
|
||||
DBUG_RETURN(LOG_READ_DECRYPT);
|
||||
}
|
||||
DBUG_ASSERT(dstlen == data_len - 4);
|
||||
memcpy(dst, dst + EVENT_LEN_OFFSET, 4);
|
||||
int4store(dst + EVENT_LEN_OFFSET, data_len);
|
||||
packet->reset(newpkt, data_len + ev_offset, data_len + ev_offset + 1,
|
||||
&my_charset_bin);
|
||||
}
|
||||
|
||||
/*
|
||||
CRC verification of the Dump thread
|
||||
*/
|
||||
if (data_len > LOG_EVENT_MINIMAL_HEADER_LEN)
|
||||
{
|
||||
/* Corrupt the event for Dump thread*/
|
||||
DBUG_EXECUTE_IF("corrupt_read_log_event2",
|
||||
uchar *debug_event_buf_c = (uchar*) packet->ptr() + ev_offset;
|
||||
@ -1331,28 +1441,19 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||
DBUG_SET("-d,corrupt_read_log_event2");
|
||||
}
|
||||
);
|
||||
/*
|
||||
CRC verification of the Dump thread
|
||||
*/
|
||||
if (event_checksum_test((uchar*) packet->ptr() + ev_offset,
|
||||
data_len, checksum_alg_arg))
|
||||
data_len, checksum_alg_arg))
|
||||
DBUG_RETURN(LOG_READ_CHECKSUM_FAILURE);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@note
|
||||
Allocates memory; The caller is responsible for clean-up.
|
||||
*/
|
||||
Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
mysql_mutex_t* log_lock,
|
||||
const Format_description_log_event
|
||||
*description_event,
|
||||
Log_event* Log_event::read_log_event(IO_CACHE* file, mysql_mutex_t* log_lock,
|
||||
const Format_description_log_event *fdle,
|
||||
my_bool crc_check)
|
||||
{
|
||||
DBUG_ENTER("Log_event::read_log_event(IO_CACHE*,Format_description_log_event*...)");
|
||||
DBUG_ASSERT(description_event != 0);
|
||||
DBUG_ASSERT(fdle != 0);
|
||||
String event;
|
||||
const char *error= 0;
|
||||
Log_event *res= 0;
|
||||
@ -1360,14 +1461,14 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
if (log_lock)
|
||||
mysql_mutex_lock(log_lock);
|
||||
|
||||
switch (read_log_event(file, &event, BINLOG_CHECKSUM_ALG_OFF))
|
||||
switch (read_log_event(file, &event, fdle, BINLOG_CHECKSUM_ALG_OFF))
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case LOG_READ_EOF: // no error here; we are at the file's end
|
||||
goto err;
|
||||
case LOG_READ_BOGUS:
|
||||
error= "Event too small";
|
||||
error= "Event invalid";
|
||||
goto err;
|
||||
case LOG_READ_IO:
|
||||
error= "read error";
|
||||
@ -1381,6 +1482,9 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
case LOG_READ_TOO_LARGE:
|
||||
error= "Event too big";
|
||||
goto err;
|
||||
case LOG_READ_DECRYPT:
|
||||
error= "Event decryption failure";
|
||||
goto err;
|
||||
case LOG_READ_CHECKSUM_FAILURE:
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
@ -1389,7 +1493,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
}
|
||||
|
||||
if ((res= read_log_event(event.ptr(), event.length(),
|
||||
&error, description_event, crc_check)))
|
||||
&error, fdle, crc_check)))
|
||||
res->register_temp_buf(event.release(), true);
|
||||
|
||||
err:
|
||||
@ -1401,8 +1505,8 @@ err:
|
||||
if (event.length() >= OLD_HEADER_LEN)
|
||||
sql_print_error("Error in Log_event::read_log_event(): '%s',"
|
||||
" data_len: %lu, event_type: %d", error,
|
||||
uint4korr(event.ptr() + EVENT_LEN_OFFSET),
|
||||
(uchar)(event.ptr()[EVENT_TYPE_OFFSET]));
|
||||
uint4korr(&event[EVENT_LEN_OFFSET]),
|
||||
(uchar)event[EVENT_TYPE_OFFSET]);
|
||||
else
|
||||
sql_print_error("Error in Log_event::read_log_event(): '%s'", error);
|
||||
/*
|
||||
@ -1420,26 +1524,25 @@ err:
|
||||
|
||||
|
||||
/**
|
||||
Binlog format tolerance is in (buf, event_len, description_event)
|
||||
Binlog format tolerance is in (buf, event_len, fdle)
|
||||
constructors.
|
||||
*/
|
||||
|
||||
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
const char **error,
|
||||
const Format_description_log_event *description_event,
|
||||
const Format_description_log_event *fdle,
|
||||
my_bool crc_check)
|
||||
{
|
||||
Log_event* ev;
|
||||
enum enum_binlog_checksum_alg alg;
|
||||
DBUG_ENTER("Log_event::read_log_event(char*,...)");
|
||||
DBUG_ASSERT(description_event != 0);
|
||||
DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
|
||||
DBUG_ASSERT(fdle != 0);
|
||||
DBUG_PRINT("info", ("binlog_version: %d", fdle->binlog_version));
|
||||
DBUG_DUMP_EVENT_BUF(buf, event_len);
|
||||
|
||||
/* Check the integrity */
|
||||
if (event_len < EVENT_LEN_OFFSET ||
|
||||
(uchar)buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
|
||||
(uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
|
||||
(uchar)buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT)
|
||||
{
|
||||
*error="Sanity check failed"; // Needed to free buffer
|
||||
DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
|
||||
@ -1448,16 +1551,16 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
uint event_type= (uchar)buf[EVENT_TYPE_OFFSET];
|
||||
// all following START events in the current file are without checksum
|
||||
if (event_type == START_EVENT_V3)
|
||||
(const_cast< Format_description_log_event *>(description_event))->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
|
||||
(const_cast< Format_description_log_event *>(fdle))->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
|
||||
/*
|
||||
CRC verification by SQL and Show-Binlog-Events master side.
|
||||
The caller has to provide @description_event->checksum_alg to
|
||||
The caller has to provide @fdle->checksum_alg to
|
||||
be the last seen FD's (A) descriptor.
|
||||
If event is FD the descriptor is in it.
|
||||
Notice, FD of the binlog can be only in one instance and therefore
|
||||
Show-Binlog-Events executing master side thread needs just to know
|
||||
the only FD's (A) value - whereas RL can contain more.
|
||||
In the RL case, the alg is kept in FD_e (@description_event) which is reset
|
||||
In the RL case, the alg is kept in FD_e (@fdle) which is reset
|
||||
to the newer read-out event after its execution with possibly new alg descriptor.
|
||||
Therefore in a typical sequence of RL:
|
||||
{FD_s^0, FD_m, E_m^1} E_m^1
|
||||
@ -1469,7 +1572,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
|
||||
*/
|
||||
alg= (event_type != FORMAT_DESCRIPTION_EVENT) ?
|
||||
description_event->checksum_alg : get_checksum_alg(buf, event_len);
|
||||
fdle->checksum_alg : get_checksum_alg(buf, event_len);
|
||||
// Emulate the corruption during reading an event
|
||||
DBUG_EXECUTE_IF("corrupt_read_log_event_char",
|
||||
if (event_type != FORMAT_DESCRIPTION_EVENT)
|
||||
@ -1488,7 +1591,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
*error= "Event crc check failed! Most likely there is event corruption.";
|
||||
if (force_opt)
|
||||
{
|
||||
ev= new Unknown_log_event(buf, description_event);
|
||||
ev= new Unknown_log_event(buf, fdle);
|
||||
DBUG_RETURN(ev);
|
||||
}
|
||||
else
|
||||
@ -1500,17 +1603,17 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
#endif
|
||||
}
|
||||
|
||||
if (event_type > description_event->number_of_event_types &&
|
||||
if (event_type > fdle->number_of_event_types &&
|
||||
event_type != FORMAT_DESCRIPTION_EVENT)
|
||||
{
|
||||
/*
|
||||
It is unsafe to use the description_event if its post_header_len
|
||||
It is unsafe to use the fdle if its post_header_len
|
||||
array does not include the event type.
|
||||
*/
|
||||
DBUG_PRINT("error", ("event type %d found, but the current "
|
||||
"Format_description_log_event supports only %d event "
|
||||
"types", event_type,
|
||||
description_event->number_of_event_types));
|
||||
fdle->number_of_event_types));
|
||||
ev= NULL;
|
||||
}
|
||||
else
|
||||
@ -1525,9 +1628,9 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
array, which was set up when the Format_description_log_event
|
||||
was read.
|
||||
*/
|
||||
if (description_event->event_type_permutation)
|
||||
if (fdle->event_type_permutation)
|
||||
{
|
||||
int new_event_type= description_event->event_type_permutation[event_type];
|
||||
int new_event_type= fdle->event_type_permutation[event_type];
|
||||
DBUG_PRINT("info", ("converting event type %d to %d (%s)",
|
||||
event_type, new_event_type,
|
||||
get_type_str((Log_event_type)new_event_type)));
|
||||
@ -1538,99 +1641,102 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
(event_type == FORMAT_DESCRIPTION_EVENT ||
|
||||
alg != BINLOG_CHECKSUM_ALG_OFF))
|
||||
event_len= event_len - BINLOG_CHECKSUM_LEN;
|
||||
|
||||
|
||||
switch(event_type) {
|
||||
case QUERY_EVENT:
|
||||
ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
|
||||
ev = new Query_log_event(buf, event_len, fdle, QUERY_EVENT);
|
||||
break;
|
||||
case LOAD_EVENT:
|
||||
ev = new Load_log_event(buf, event_len, description_event);
|
||||
ev = new Load_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case NEW_LOAD_EVENT:
|
||||
ev = new Load_log_event(buf, event_len, description_event);
|
||||
ev = new Load_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case ROTATE_EVENT:
|
||||
ev = new Rotate_log_event(buf, event_len, description_event);
|
||||
ev = new Rotate_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case BINLOG_CHECKPOINT_EVENT:
|
||||
ev = new Binlog_checkpoint_log_event(buf, event_len, description_event);
|
||||
ev = new Binlog_checkpoint_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case GTID_EVENT:
|
||||
ev = new Gtid_log_event(buf, event_len, description_event);
|
||||
ev = new Gtid_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case GTID_LIST_EVENT:
|
||||
ev = new Gtid_list_log_event(buf, event_len, description_event);
|
||||
ev = new Gtid_list_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case CREATE_FILE_EVENT:
|
||||
ev = new Create_file_log_event(buf, event_len, description_event);
|
||||
ev = new Create_file_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case APPEND_BLOCK_EVENT:
|
||||
ev = new Append_block_log_event(buf, event_len, description_event);
|
||||
ev = new Append_block_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case DELETE_FILE_EVENT:
|
||||
ev = new Delete_file_log_event(buf, event_len, description_event);
|
||||
ev = new Delete_file_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case EXEC_LOAD_EVENT:
|
||||
ev = new Execute_load_log_event(buf, event_len, description_event);
|
||||
ev = new Execute_load_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
|
||||
ev = new Start_log_event_v3(buf, event_len, description_event);
|
||||
ev = new Start_log_event_v3(buf, event_len, fdle);
|
||||
break;
|
||||
case STOP_EVENT:
|
||||
ev = new Stop_log_event(buf, description_event);
|
||||
ev = new Stop_log_event(buf, fdle);
|
||||
break;
|
||||
case INTVAR_EVENT:
|
||||
ev = new Intvar_log_event(buf, description_event);
|
||||
ev = new Intvar_log_event(buf, fdle);
|
||||
break;
|
||||
case XID_EVENT:
|
||||
ev = new Xid_log_event(buf, description_event);
|
||||
ev = new Xid_log_event(buf, fdle);
|
||||
break;
|
||||
case RAND_EVENT:
|
||||
ev = new Rand_log_event(buf, description_event);
|
||||
ev = new Rand_log_event(buf, fdle);
|
||||
break;
|
||||
case USER_VAR_EVENT:
|
||||
ev = new User_var_log_event(buf, event_len, description_event);
|
||||
ev = new User_var_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case FORMAT_DESCRIPTION_EVENT:
|
||||
ev = new Format_description_log_event(buf, event_len, description_event);
|
||||
ev = new Format_description_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
#if defined(HAVE_REPLICATION)
|
||||
case PRE_GA_WRITE_ROWS_EVENT:
|
||||
ev = new Write_rows_log_event_old(buf, event_len, description_event);
|
||||
ev = new Write_rows_log_event_old(buf, event_len, fdle);
|
||||
break;
|
||||
case PRE_GA_UPDATE_ROWS_EVENT:
|
||||
ev = new Update_rows_log_event_old(buf, event_len, description_event);
|
||||
ev = new Update_rows_log_event_old(buf, event_len, fdle);
|
||||
break;
|
||||
case PRE_GA_DELETE_ROWS_EVENT:
|
||||
ev = new Delete_rows_log_event_old(buf, event_len, description_event);
|
||||
ev = new Delete_rows_log_event_old(buf, event_len, fdle);
|
||||
break;
|
||||
case WRITE_ROWS_EVENT_V1:
|
||||
case WRITE_ROWS_EVENT:
|
||||
ev = new Write_rows_log_event(buf, event_len, description_event);
|
||||
ev = new Write_rows_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case UPDATE_ROWS_EVENT_V1:
|
||||
case UPDATE_ROWS_EVENT:
|
||||
ev = new Update_rows_log_event(buf, event_len, description_event);
|
||||
ev = new Update_rows_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case DELETE_ROWS_EVENT_V1:
|
||||
case DELETE_ROWS_EVENT:
|
||||
ev = new Delete_rows_log_event(buf, event_len, description_event);
|
||||
ev = new Delete_rows_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case TABLE_MAP_EVENT:
|
||||
ev = new Table_map_log_event(buf, event_len, description_event);
|
||||
ev = new Table_map_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
#endif
|
||||
case BEGIN_LOAD_QUERY_EVENT:
|
||||
ev = new Begin_load_query_log_event(buf, event_len, description_event);
|
||||
ev = new Begin_load_query_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case EXECUTE_LOAD_QUERY_EVENT:
|
||||
ev= new Execute_load_query_log_event(buf, event_len, description_event);
|
||||
ev= new Execute_load_query_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case INCIDENT_EVENT:
|
||||
ev = new Incident_log_event(buf, event_len, description_event);
|
||||
ev = new Incident_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case ANNOTATE_ROWS_EVENT:
|
||||
ev = new Annotate_rows_log_event(buf, event_len, description_event);
|
||||
ev = new Annotate_rows_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
case START_ENCRYPTION_EVENT:
|
||||
ev = new Start_encryption_log_event(buf, event_len, fdle);
|
||||
break;
|
||||
default:
|
||||
DBUG_PRINT("error",("Unknown event code: %d",
|
||||
@ -1676,7 +1782,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
*error= "Found invalid event in binary log";
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
ev= new Unknown_log_event(buf, description_event);
|
||||
ev= new Unknown_log_event(buf, fdle);
|
||||
#else
|
||||
*error= "Found invalid event in binary log";
|
||||
DBUG_RETURN(0);
|
||||
@ -4797,6 +4903,7 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
|
||||
BINLOG_CHECKPOINT_HEADER_LEN;
|
||||
post_header_len[GTID_EVENT-1]= GTID_HEADER_LEN;
|
||||
post_header_len[GTID_LIST_EVENT-1]= GTID_LIST_HEADER_LEN;
|
||||
post_header_len[START_ENCRYPTION_EVENT-1]= START_ENCRYPTION_HEADER_LEN;
|
||||
|
||||
// Sanity-check that all post header lengths are initialized.
|
||||
int i;
|
||||
@ -4851,6 +4958,7 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
|
||||
}
|
||||
calc_server_version_split();
|
||||
checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
|
||||
reset_crypto();
|
||||
}
|
||||
|
||||
|
||||
@ -4908,6 +5016,7 @@ Format_description_log_event(const char* buf,
|
||||
{
|
||||
checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
|
||||
}
|
||||
reset_crypto();
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -5023,6 +5132,7 @@ int Format_description_log_event::do_apply_event(rpl_group_info *rgi)
|
||||
if (!ret)
|
||||
{
|
||||
/* Save the information describing this binlog */
|
||||
copy_crypto_data(rli->relay_log.description_event_for_exec);
|
||||
delete rli->relay_log.description_event_for_exec;
|
||||
rli->relay_log.description_event_for_exec= this;
|
||||
}
|
||||
@ -5064,6 +5174,17 @@ Format_description_log_event::do_shall_skip(rpl_group_info *rgi)
|
||||
|
||||
#endif
|
||||
|
||||
bool Format_description_log_event::start_decryption(Start_encryption_log_event* sele)
|
||||
{
|
||||
DBUG_ASSERT(crypto_data.scheme == 0);
|
||||
|
||||
if (!sele->is_valid())
|
||||
return 1;
|
||||
|
||||
memcpy(crypto_data.nonce, sele->nonce, BINLOG_NONCE_LENGTH);
|
||||
return crypto_data.init(sele->crypto_scheme, sele->key_version);
|
||||
}
|
||||
|
||||
static inline void
|
||||
do_server_version_split(char* version,
|
||||
Format_description_log_event::master_version_split *split_versions)
|
||||
@ -5170,8 +5291,60 @@ enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len)
|
||||
ret == BINLOG_CHECKSUM_ALG_CRC32);
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
|
||||
Start_encryption_log_event::Start_encryption_log_event(
|
||||
const char* buf, uint event_len,
|
||||
const Format_description_log_event* description_event)
|
||||
:Log_event(buf, description_event)
|
||||
{
|
||||
if ((int)event_len ==
|
||||
LOG_EVENT_MINIMAL_HEADER_LEN + Start_encryption_log_event::get_data_size())
|
||||
{
|
||||
buf += LOG_EVENT_MINIMAL_HEADER_LEN;
|
||||
crypto_scheme = *(uchar*)buf;
|
||||
key_version = uint4korr(buf + BINLOG_CRYPTO_SCHEME_LENGTH);
|
||||
memcpy(nonce,
|
||||
buf + BINLOG_CRYPTO_SCHEME_LENGTH + BINLOG_KEY_VERSION_LENGTH,
|
||||
BINLOG_NONCE_LENGTH);
|
||||
}
|
||||
else
|
||||
crypto_scheme= ~0; // invalid
|
||||
}
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
int Start_encryption_log_event::do_apply_event(rpl_group_info* rgi)
|
||||
{
|
||||
return rgi->rli->relay_log.description_event_for_exec->start_decryption(this);
|
||||
}
|
||||
|
||||
int Start_encryption_log_event::do_update_pos(rpl_group_info *rgi)
|
||||
{
|
||||
/*
|
||||
master never sends Start_encryption_log_event, any SELE that a slave
|
||||
might see was created locally in MYSQL_BIN_LOG::open() on the slave
|
||||
*/
|
||||
rgi->inc_event_relay_log_pos();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef MYSQL_SERVER
|
||||
void Start_encryption_log_event::print(FILE* file,
|
||||
PRINT_EVENT_INFO* print_event_info)
|
||||
{
|
||||
Write_on_release_cache cache(&print_event_info->head_cache, file);
|
||||
StringBuffer<1024> buf;
|
||||
buf.append(STRING_WITH_LEN("# Encryption scheme: "));
|
||||
buf.append_ulonglong(crypto_scheme);
|
||||
buf.append(STRING_WITH_LEN(", key_version: "));
|
||||
buf.append_ulonglong(key_version);
|
||||
buf.append(STRING_WITH_LEN(", nonce: "));
|
||||
buf.append_hex(nonce, BINLOG_NONCE_LENGTH);
|
||||
buf.append(STRING_WITH_LEN("\n# The rest of the binlog is encrypted!\n"));
|
||||
my_b_write(&cache, (uchar*)buf.ptr(), buf.length());
|
||||
}
|
||||
#endif
|
||||
/**************************************************************************
|
||||
Load_log_event methods
|
||||
General note about Load_log_event: the binlogging of LOAD DATA INFILE is
|
||||
@ -12290,7 +12463,12 @@ Incident_log_event::Incident_log_event(const char *buf, uint event_len,
|
||||
char const *const str_end= buf + event_len;
|
||||
uint8 len= 0; // Assignment to keep compiler happy
|
||||
const char *str= NULL; // Assignment to keep compiler happy
|
||||
read_str(&ptr, str_end, &str, &len);
|
||||
if (read_str(&ptr, str_end, &str, &len))
|
||||
{
|
||||
/* Mark this event invalid */
|
||||
m_incident= INCIDENT_NONE;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
if (!(m_message.str= (char*) my_malloc(len+1, MYF(MY_WME))))
|
||||
{
|
||||
/* Mark this event invalid */
|
||||
|
103
sql/log_event.h
103
sql/log_event.h
@ -81,6 +81,7 @@ class String;
|
||||
#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
|
||||
|
||||
@ -211,6 +212,7 @@ class String;
|
||||
#define BINLOG_CHECKPOINT_HEADER_LEN 4
|
||||
#define GTID_HEADER_LEN 19
|
||||
#define GTID_LIST_HEADER_LEN 4
|
||||
#define START_ENCRYPTION_HEADER_LEN 0
|
||||
|
||||
/*
|
||||
Max number of possible extra bytes in a replication event compared to a
|
||||
@ -666,6 +668,8 @@ enum Log_event_type
|
||||
*/
|
||||
GTID_LIST_EVENT= 163,
|
||||
|
||||
START_ENCRYPTION_EVENT= 164,
|
||||
|
||||
/* Add new MariaDB events here - right above this comment! */
|
||||
|
||||
ENUM_END_EVENT /* end marker */
|
||||
@ -790,12 +794,13 @@ typedef struct st_print_event_info
|
||||
|
||||
/**
|
||||
This class encapsulates writing of Log_event objects to IO_CACHE.
|
||||
Automatically calculates the checksum if necessary.
|
||||
Automatically calculates the checksum and encrypts the data, if necessary.
|
||||
*/
|
||||
class Log_event_writer
|
||||
{
|
||||
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);
|
||||
@ -803,7 +808,9 @@ public:
|
||||
int write_footer();
|
||||
my_off_t pos() { return my_b_safe_tell(file); }
|
||||
|
||||
Log_event_writer(IO_CACHE *file_arg) : bytes_written(0), file(file_arg) { }
|
||||
Log_event_writer(IO_CACHE *file_arg, Binlog_crypt_data *cr= 0)
|
||||
: bytes_written(0), ctx(0),
|
||||
file(file_arg), crypto(cr) { }
|
||||
|
||||
private:
|
||||
IO_CACHE *file;
|
||||
@ -811,8 +818,17 @@ private:
|
||||
Placeholder for event checksum while writing to binlog.
|
||||
*/
|
||||
ha_checksum crc;
|
||||
|
||||
/**
|
||||
Encryption data (key, nonce). Only used if ctx != 0.
|
||||
*/
|
||||
Binlog_crypt_data *crypto;
|
||||
/**
|
||||
Event length to be written into the next encrypted block
|
||||
*/
|
||||
uint event_len;
|
||||
int write_internal(const uchar *pos, size_t len);
|
||||
int encrypt_and_write(const uchar *pos, size_t len);
|
||||
int maybe_write_event_len(uchar *pos, size_t len);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1163,6 +1179,7 @@ public:
|
||||
@retval LOG_READ_TOO_LARGE event too large
|
||||
*/
|
||||
static int read_log_event(IO_CACHE* file, String* packet,
|
||||
const Format_description_log_event *fdle,
|
||||
enum enum_binlog_checksum_alg checksum_alg_arg);
|
||||
/*
|
||||
The value is set by caller of FD constructor and
|
||||
@ -1289,7 +1306,6 @@ public:
|
||||
const char* get_type_str();
|
||||
|
||||
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
|
||||
public:
|
||||
|
||||
/**
|
||||
Apply the event to the database.
|
||||
@ -1381,6 +1397,7 @@ public:
|
||||
case HEARTBEAT_LOG_EVENT:
|
||||
case BINLOG_CHECKPOINT_EVENT:
|
||||
case GTID_LIST_EVENT:
|
||||
case START_ENCRYPTION_EVENT:
|
||||
return false;
|
||||
|
||||
default:
|
||||
@ -2457,6 +2474,73 @@ protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@class Start_encryption_log_event
|
||||
|
||||
Start_encryption_log_event marks the beginning of encrypted data (all events
|
||||
after this event are encrypted).
|
||||
|
||||
It contains the cryptographic scheme used for the encryption as well as any
|
||||
data required to decrypt (except the actual key).
|
||||
|
||||
For binlog cryptoscheme 1: key version, and nonce for iv generation.
|
||||
*/
|
||||
class Start_encryption_log_event : public Log_event
|
||||
{
|
||||
public:
|
||||
#ifdef MYSQL_SERVER
|
||||
Start_encryption_log_event(uint crypto_scheme_arg, uint key_version_arg,
|
||||
const uchar* nonce_arg)
|
||||
: crypto_scheme(crypto_scheme_arg), key_version(key_version_arg)
|
||||
{
|
||||
cache_type = EVENT_NO_CACHE;
|
||||
DBUG_ASSERT(crypto_scheme == 1);
|
||||
memcpy(nonce, nonce_arg, BINLOG_NONCE_LENGTH);
|
||||
}
|
||||
|
||||
bool write_data_body()
|
||||
{
|
||||
uchar scheme_buf= crypto_scheme;
|
||||
uchar key_version_buf[BINLOG_KEY_VERSION_LENGTH];
|
||||
int4store(key_version_buf, key_version);
|
||||
return write_data(&scheme_buf, sizeof(scheme_buf)) ||
|
||||
write_data(key_version_buf, sizeof(key_version_buf)) ||
|
||||
write_data(nonce, BINLOG_NONCE_LENGTH);
|
||||
}
|
||||
#else
|
||||
void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
|
||||
#endif
|
||||
|
||||
Start_encryption_log_event(
|
||||
const char* buf, uint event_len,
|
||||
const Format_description_log_event* description_event);
|
||||
|
||||
bool is_valid() const { return crypto_scheme == 1; }
|
||||
|
||||
Log_event_type get_type_code() { return START_ENCRYPTION_EVENT; }
|
||||
|
||||
int get_data_size()
|
||||
{
|
||||
return BINLOG_CRYPTO_SCHEME_LENGTH + BINLOG_KEY_VERSION_LENGTH +
|
||||
BINLOG_NONCE_LENGTH;
|
||||
}
|
||||
|
||||
uint crypto_scheme;
|
||||
uint key_version;
|
||||
uchar nonce[BINLOG_NONCE_LENGTH];
|
||||
|
||||
protected:
|
||||
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
|
||||
virtual int do_apply_event(rpl_group_info* rgi);
|
||||
virtual int do_update_pos(rpl_group_info *rgi);
|
||||
virtual enum_skip_reason do_shall_skip(rpl_group_info* rgi)
|
||||
{
|
||||
return Log_event::EVENT_SKIP_NOT;
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@class Format_description_log_event
|
||||
@ -2534,6 +2618,17 @@ public:
|
||||
return FORMAT_DESCRIPTION_HEADER_LEN;
|
||||
}
|
||||
|
||||
Binlog_crypt_data crypto_data;
|
||||
bool start_decryption(Start_encryption_log_event* sele);
|
||||
void copy_crypto_data(const Format_description_log_event* o)
|
||||
{
|
||||
crypto_data= o->crypto_data;
|
||||
}
|
||||
void reset_crypto()
|
||||
{
|
||||
crypto_data.scheme= 0;
|
||||
}
|
||||
|
||||
void calc_server_version_split();
|
||||
static bool is_version_before_checksum(const master_version_split *version_split);
|
||||
protected:
|
||||
|
@ -629,6 +629,7 @@ char server_version[SERVER_VERSION_LENGTH];
|
||||
char *mysqld_unix_port, *opt_mysql_tmpdir;
|
||||
ulong thread_handling;
|
||||
|
||||
my_bool encrypt_binlog;
|
||||
my_bool encrypt_tmp_disk_tables, encrypt_tmp_files;
|
||||
|
||||
/** name of reference on left expression in rewritten IN subquery */
|
||||
|
@ -255,6 +255,7 @@ extern ulong connection_errors_internal;
|
||||
extern ulong connection_errors_max_connection;
|
||||
extern ulong connection_errors_peer_addr;
|
||||
extern ulong log_warnings;
|
||||
extern my_bool encrypt_binlog;
|
||||
extern my_bool encrypt_tmp_disk_tables, encrypt_tmp_files;
|
||||
extern ulong encryption_algorithm;
|
||||
extern const char *encryption_algorithm_names[];
|
||||
|
@ -17,6 +17,9 @@
|
||||
#ifndef RPL_CONSTANTS_H
|
||||
#define RPL_CONSTANTS_H
|
||||
|
||||
#include <my_sys.h>
|
||||
#include <my_crypt.h>
|
||||
|
||||
/**
|
||||
Enumeration of the incidents that can occur for the server.
|
||||
*/
|
||||
@ -78,4 +81,32 @@ enum enum_binlog_checksum_alg {
|
||||
// or events from checksum-unaware servers
|
||||
};
|
||||
|
||||
#define BINLOG_CRYPTO_SCHEME_LENGTH 1
|
||||
#define BINLOG_KEY_VERSION_LENGTH 4
|
||||
#define BINLOG_IV_LENGTH MY_AES_BLOCK_SIZE
|
||||
#define BINLOG_IV_OFFS_LENGTH 4
|
||||
#define BINLOG_NONCE_LENGTH (BINLOG_IV_LENGTH - BINLOG_IV_OFFS_LENGTH)
|
||||
|
||||
struct Binlog_crypt_data {
|
||||
uint scheme;
|
||||
uint key_version, key_length, ctx_size;
|
||||
uchar key[MY_AES_MAX_KEY_LENGTH];
|
||||
uchar nonce[BINLOG_NONCE_LENGTH];
|
||||
|
||||
int init(uint sch, uint kv)
|
||||
{
|
||||
scheme= sch;
|
||||
ctx_size= encryption_ctx_size(ENCRYPTION_KEY_SYSTEM_DATA, kv);
|
||||
key_version= kv;
|
||||
key_length= sizeof(key);
|
||||
return encryption_key_get(ENCRYPTION_KEY_SYSTEM_DATA, kv, key, &key_length);
|
||||
}
|
||||
|
||||
void set_iv(uchar* iv, uint32 offs) const
|
||||
{
|
||||
memcpy(iv, nonce, BINLOG_NONCE_LENGTH);
|
||||
int4store(iv + BINLOG_NONCE_LENGTH, offs);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* RPL_CONSTANTS_H */
|
||||
|
@ -570,16 +570,26 @@ do_retry:
|
||||
err= 1;
|
||||
goto check_retry;
|
||||
}
|
||||
description_event->reset_crypto();
|
||||
/* Loop to try again on the new log file. */
|
||||
}
|
||||
|
||||
event_type= ev->get_type_code();
|
||||
if (event_type == FORMAT_DESCRIPTION_EVENT)
|
||||
{
|
||||
Format_description_log_event *newde= (Format_description_log_event*)ev;
|
||||
newde->copy_crypto_data(description_event);
|
||||
delete description_event;
|
||||
description_event= (Format_description_log_event *)ev;
|
||||
description_event= newde;
|
||||
continue;
|
||||
} else if (!Log_event::is_group_event(event_type))
|
||||
}
|
||||
else if (event_type == START_ENCRYPTION_EVENT)
|
||||
{
|
||||
description_event->start_decryption((Start_encryption_log_event*)ev);
|
||||
delete ev;
|
||||
continue;
|
||||
}
|
||||
else if (!Log_event::is_group_event(event_type))
|
||||
{
|
||||
delete ev;
|
||||
continue;
|
||||
|
@ -547,9 +547,12 @@ read_relay_log_description_event(IO_CACHE *cur_log, ulonglong start_pos,
|
||||
typ= ev->get_type_code();
|
||||
if (typ == FORMAT_DESCRIPTION_EVENT)
|
||||
{
|
||||
Format_description_log_event *old= fdev;
|
||||
DBUG_PRINT("info",("found Format_description_log_event"));
|
||||
delete fdev;
|
||||
fdev= (Format_description_log_event*) ev;
|
||||
fdev->copy_crypto_data(old);
|
||||
delete old;
|
||||
|
||||
/*
|
||||
As ev was returned by read_log_event, it has passed is_valid(), so
|
||||
my_malloc() in ctor worked, no need to check again.
|
||||
@ -571,6 +574,17 @@ read_relay_log_description_event(IO_CACHE *cur_log, ulonglong start_pos,
|
||||
or Format_desc.
|
||||
*/
|
||||
}
|
||||
else if (typ == START_ENCRYPTION_EVENT)
|
||||
{
|
||||
if (fdev->start_decryption((Start_encryption_log_event*) ev))
|
||||
{
|
||||
*errmsg= "Unable to set up decryption of binlog.";
|
||||
delete ev;
|
||||
delete fdev;
|
||||
return NULL;
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("info",("found event of another type=%d", typ));
|
||||
|
@ -5607,6 +5607,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
|
||||
error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
tmp->copy_crypto_data(mi->rli.relay_log.description_event_for_queue);
|
||||
delete mi->rli.relay_log.description_event_for_queue;
|
||||
mi->rli.relay_log.description_event_for_queue= tmp;
|
||||
if (tmp->checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
|
||||
@ -6028,7 +6029,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (likely(!(rli->relay_log.appendv(buf,event_len,0))))
|
||||
if (likely(!rli->relay_log.write_event_buffer((uchar*)buf, event_len)))
|
||||
{
|
||||
mi->master_log_pos+= inc_pos;
|
||||
DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
|
||||
@ -6778,6 +6779,7 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size)
|
||||
mysql_file_close(rli->cur_log_fd, MYF(MY_WME));
|
||||
rli->cur_log_fd = -1;
|
||||
rli->last_inuse_relaylog->completed= true;
|
||||
rli->relay_log.description_event_for_exec->reset_crypto();
|
||||
|
||||
if (relay_log_purge)
|
||||
{
|
||||
|
160
sql/sql_repl.cc
160
sql/sql_repl.cc
@ -644,6 +644,9 @@ void set_read_error(binlog_send_info *info, int error)
|
||||
case LOG_READ_CHECKSUM_FAILURE:
|
||||
info->errmsg= "event read from binlog did not pass crc check";
|
||||
break;
|
||||
case LOG_READ_DECRYPT:
|
||||
info->errmsg= "event decryption failure";
|
||||
break;
|
||||
default:
|
||||
info->errmsg= "unknown error reading log event on the master";
|
||||
break;
|
||||
@ -918,9 +921,14 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
|
||||
typ= ev->get_type_code();
|
||||
if (typ == GTID_LIST_EVENT)
|
||||
break; /* Done, found it */
|
||||
if (typ == START_ENCRYPTION_EVENT)
|
||||
{
|
||||
if (fdle->start_decryption((Start_encryption_log_event*) ev))
|
||||
errormsg= "Could not set up decryption for binlog.";
|
||||
}
|
||||
delete ev;
|
||||
if (typ == ROTATE_EVENT || typ == STOP_EVENT ||
|
||||
typ == FORMAT_DESCRIPTION_EVENT)
|
||||
typ == FORMAT_DESCRIPTION_EVENT || typ == START_ENCRYPTION_EVENT)
|
||||
continue; /* Continue looking */
|
||||
|
||||
/* We did not find any Gtid_list_log_event, must be old binlog. */
|
||||
@ -1437,7 +1445,7 @@ gtid_state_from_pos(const char *name, uint32 offset,
|
||||
break;
|
||||
|
||||
packet.length(0);
|
||||
err= Log_event::read_log_event(&cache, &packet,
|
||||
err= Log_event::read_log_event(&cache, &packet, fdev,
|
||||
opt_master_verify_checksum ? current_checksum_alg
|
||||
: BINLOG_CHECKSUM_ALG_OFF);
|
||||
if (err)
|
||||
@ -1474,6 +1482,20 @@ gtid_state_from_pos(const char *name, uint32 offset,
|
||||
delete fdev;
|
||||
fdev= tmp;
|
||||
}
|
||||
else if (typ == START_ENCRYPTION_EVENT)
|
||||
{
|
||||
uint sele_len = packet.length();
|
||||
if (current_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
|
||||
{
|
||||
sele_len -= BINLOG_CHECKSUM_LEN;
|
||||
}
|
||||
Start_encryption_log_event sele(packet.ptr(), sele_len, fdev);
|
||||
if (fdev->start_decryption(&sele))
|
||||
{
|
||||
errormsg= "Could not start decryption of binlog.";
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else if (typ != FORMAT_DESCRIPTION_EVENT && !found_format_description_event)
|
||||
{
|
||||
errormsg= "Did not find format description log event while searching "
|
||||
@ -2216,9 +2238,10 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
||||
the binlog
|
||||
*/
|
||||
info->last_pos= my_b_tell(log);
|
||||
error= Log_event::read_log_event(log, packet,
|
||||
error= Log_event::read_log_event(log, packet, info->fdev,
|
||||
opt_master_verify_checksum
|
||||
? info->current_checksum_alg : BINLOG_CHECKSUM_ALG_OFF);
|
||||
? info->current_checksum_alg
|
||||
: BINLOG_CHECKSUM_ALG_OFF);
|
||||
linfo->pos= my_b_tell(log);
|
||||
|
||||
if (error)
|
||||
@ -2268,10 +2291,13 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint ev_len= packet->length() - ev_offset;
|
||||
if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
|
||||
ev_len-= BINLOG_CHECKSUM_LEN;
|
||||
|
||||
Format_description_log_event *tmp;
|
||||
if (!(tmp= new Format_description_log_event(packet->ptr()+ev_offset,
|
||||
packet->length()-ev_offset,
|
||||
info->fdev)))
|
||||
if (!(tmp= new Format_description_log_event(packet->ptr() + ev_offset,
|
||||
ev_len, info->fdev)))
|
||||
{
|
||||
info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
||||
info->errmsg= "Corrupt Format_description event found "
|
||||
@ -2338,6 +2364,57 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Read the following Start_encryption_log_event but don't send it to slave.
|
||||
Slave doesn't need to know whether master's binlog is encrypted,
|
||||
and if it'll want to encrypt its logs, it should generate its own
|
||||
random nonce, not use the one from the master.
|
||||
*/
|
||||
packet->length(0);
|
||||
info->last_pos= linfo->pos;
|
||||
error= Log_event::read_log_event(log, packet, info->fdev,
|
||||
opt_master_verify_checksum
|
||||
? info->current_checksum_alg
|
||||
: BINLOG_CHECKSUM_ALG_OFF);
|
||||
linfo->pos= my_b_tell(log);
|
||||
|
||||
if (error)
|
||||
{
|
||||
set_read_error(info, error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET]);
|
||||
if (event_type == START_ENCRYPTION_EVENT)
|
||||
{
|
||||
Start_encryption_log_event *sele= (Start_encryption_log_event *)
|
||||
Log_event::read_log_event(packet->ptr(), packet->length(), &info->errmsg,
|
||||
info->fdev, BINLOG_CHECKSUM_ALG_OFF);
|
||||
if (!sele)
|
||||
{
|
||||
info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->fdev->start_decryption(sele))
|
||||
{
|
||||
info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
||||
info->errmsg= "Could not decrypt binlog: encryption key error";
|
||||
return 1;
|
||||
}
|
||||
delete sele;
|
||||
}
|
||||
else if (start_pos == BIN_LOG_HEADER_SIZE)
|
||||
{
|
||||
/*
|
||||
not Start_encryption_log_event - seek back. But only if
|
||||
send_one_binlog_file() isn't going to seek anyway
|
||||
*/
|
||||
my_b_seek(log, info->last_pos);
|
||||
linfo->pos= info->last_pos;
|
||||
}
|
||||
|
||||
|
||||
/** all done */
|
||||
return 0;
|
||||
}
|
||||
@ -2547,7 +2624,7 @@ static int send_events(binlog_send_info *info, IO_CACHE* log, LOG_INFO* linfo,
|
||||
return 1;
|
||||
|
||||
info->last_pos= linfo->pos;
|
||||
error= Log_event::read_log_event(log, packet,
|
||||
error= Log_event::read_log_event(log, packet, info->fdev,
|
||||
opt_master_verify_checksum ? info->current_checksum_alg
|
||||
: BINLOG_CHECKSUM_ALG_OFF);
|
||||
linfo->pos= my_b_tell(log);
|
||||
@ -2598,8 +2675,9 @@ static int send_events(binlog_send_info *info, IO_CACHE* log, LOG_INFO* linfo,
|
||||
});
|
||||
#endif
|
||||
|
||||
if ((info->errmsg= send_event_to_slave(info, event_type, log,
|
||||
ev_offset, &info->error_gtid)))
|
||||
if (event_type != START_ENCRYPTION_EVENT &&
|
||||
((info->errmsg= send_event_to_slave(info, event_type, log,
|
||||
ev_offset, &info->error_gtid))))
|
||||
return 1;
|
||||
|
||||
if (unlikely(info->send_fake_gtid_list) &&
|
||||
@ -3876,38 +3954,52 @@ bool mysql_show_binlog_events(THD* thd)
|
||||
Read the first event in case it's a Format_description_log_event, to
|
||||
know the format. If there's no such event, we are 3.23 or 4.x. This
|
||||
code, like before, can't read 3.23 binlogs.
|
||||
Also read the second event, in case it's a Start_encryption_log_event.
|
||||
This code will fail on a mixed relay log (one which has Format_desc then
|
||||
Rotate then Format_desc).
|
||||
*/
|
||||
ev= Log_event::read_log_event(&log, (mysql_mutex_t*)0, description_event,
|
||||
opt_master_verify_checksum);
|
||||
if (ev)
|
||||
|
||||
my_off_t scan_pos = BIN_LOG_HEADER_SIZE;
|
||||
while (scan_pos < pos)
|
||||
{
|
||||
ev= Log_event::read_log_event(&log, (mysql_mutex_t*)0, description_event,
|
||||
opt_master_verify_checksum);
|
||||
scan_pos = my_b_tell(&log);
|
||||
if (ev == NULL || !ev->is_valid())
|
||||
{
|
||||
mysql_mutex_unlock(log_lock);
|
||||
errmsg = "Wrong offset or I/O error";
|
||||
goto err;
|
||||
}
|
||||
if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
|
||||
{
|
||||
delete description_event;
|
||||
description_event= (Format_description_log_event*) ev;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ev->get_type_code() == START_ENCRYPTION_EVENT)
|
||||
{
|
||||
if (description_event->start_decryption((Start_encryption_log_event*) ev))
|
||||
{
|
||||
delete ev;
|
||||
mysql_mutex_unlock(log_lock);
|
||||
errmsg = "Could not initialize decryption of binlog.";
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
delete ev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
my_b_seek(&log, pos);
|
||||
|
||||
if (!description_event->is_valid())
|
||||
{
|
||||
errmsg="Invalid Format_description event; could be out of memory";
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (event_count = 0;
|
||||
(ev = Log_event::read_log_event(&log, (mysql_mutex_t*) 0,
|
||||
description_event,
|
||||
opt_master_verify_checksum)); )
|
||||
{
|
||||
if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
|
||||
description_event->checksum_alg= ev->checksum_alg;
|
||||
|
||||
if (event_count >= limit_start &&
|
||||
ev->net_send(thd, protocol, linfo.log_file_name, pos))
|
||||
{
|
||||
@ -3917,8 +4009,30 @@ bool mysql_show_binlog_events(THD* thd)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
|
||||
{
|
||||
Format_description_log_event* new_fdle=
|
||||
(Format_description_log_event*) ev;
|
||||
new_fdle->copy_crypto_data(description_event);
|
||||
delete description_event;
|
||||
description_event= new_fdle;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ev->get_type_code() == START_ENCRYPTION_EVENT)
|
||||
{
|
||||
if (description_event->start_decryption((Start_encryption_log_event*) ev))
|
||||
{
|
||||
errmsg = "Error starting decryption";
|
||||
delete ev;
|
||||
mysql_mutex_unlock(log_lock);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
|
||||
pos = my_b_tell(&log);
|
||||
delete ev;
|
||||
|
||||
if (++event_count >= limit_end)
|
||||
break;
|
||||
|
@ -467,6 +467,10 @@ public:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool append_hex(const uchar *src, uint32 srclen)
|
||||
{
|
||||
return append_hex((const char*)src, srclen);
|
||||
}
|
||||
bool fill(uint32 max_length,char fill);
|
||||
void strip_sp();
|
||||
friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
||||
|
@ -1132,7 +1132,6 @@ static Sys_var_mybool Sys_log_bin(
|
||||
"log_bin", "Whether the binary log is enabled",
|
||||
READ_ONLY GLOBAL_VAR(opt_bin_log), NO_CMD_LINE, DEFAULT(FALSE));
|
||||
|
||||
|
||||
static Sys_var_mybool Sys_trust_function_creators(
|
||||
"log_bin_trust_function_creators",
|
||||
"If set to FALSE (the default), then when --log-bin is used, creation "
|
||||
@ -5215,6 +5214,11 @@ static Sys_var_mybool Sys_encrypt_tmp_files(
|
||||
READ_ONLY GLOBAL_VAR(encrypt_tmp_files),
|
||||
CMD_LINE(OPT_ARG), DEFAULT(TRUE));
|
||||
|
||||
static Sys_var_mybool Sys_binlog_encryption(
|
||||
"encrypt_binlog", "Encrypt binary logs (including relay logs)",
|
||||
READ_ONLY GLOBAL_VAR(encrypt_binlog), CMD_LINE(OPT_ARG),
|
||||
DEFAULT(TRUE));
|
||||
|
||||
static const char *binlog_row_image_names[]= {"MINIMAL", "NOBLOB", "FULL", NullS};
|
||||
static Sys_var_enum Sys_binlog_row_image(
|
||||
"binlog_row_image",
|
||||
|
Loading…
x
Reference in New Issue
Block a user