summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-09-02 09:58:08 +0200
committerSergei Golubchik <serg@mariadb.org>2015-09-04 10:33:55 +0200
commitb85a00161e91080cb82b99e812c18eafb6467737 (patch)
tree3b502db8d25f0eb0a93901e3417d097626ecf8ea
parent41d68cabee1d9c2a8e8c7a006b17070392a85ed7 (diff)
downloadmariadb-git-b85a00161e91080cb82b99e812c18eafb6467737.tar.gz
MDEV-8264 encryption for binlog
* Start_encryption_log_event * --encrypt-binlog command line option based on google patches.
-rw-r--r--client/mysqlbinlog.cc5
-rw-r--r--mysql-test/include/binlog_start_pos.inc10
-rw-r--r--mysql-test/include/show_binlog_events2.inc2
-rw-r--r--mysql-test/r/mysqld--help.result3
-rw-r--r--mysql-test/suite/rpl/r/rpl_checksum.result2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result14
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff128
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result14
-rw-r--r--sql/log.cc100
-rw-r--r--sql/log.h9
-rw-r--r--sql/log_event.cc324
-rw-r--r--sql/log_event.h103
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/mysqld.h1
-rw-r--r--sql/rpl_constants.h31
-rw-r--r--sql/rpl_parallel.cc14
-rw-r--r--sql/rpl_rli.cc16
-rw-r--r--sql/slave.cc4
-rw-r--r--sql/sql_repl.cc160
-rw-r--r--sql/sql_string.h4
-rw-r--r--sql/sys_vars.cc6
21 files changed, 753 insertions, 198 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 3b4cfb8f993..587e5389860 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -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
diff --git a/mysql-test/include/binlog_start_pos.inc b/mysql-test/include/binlog_start_pos.inc
index 7dac1b376ee..a187e18b3a4 100644
--- a/mysql-test/include/binlog_start_pos.inc
+++ b/mysql-test/include/binlog_start_pos.inc
@@ -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
diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc
index e72522dc272..356bf6dc727 100644
--- a/mysql-test/include/show_binlog_events2.inc
+++ b/mysql-test/include/show_binlog_events2.inc
@@ -4,7 +4,7 @@ if ($binlog_start)
}
if (!$binlog_start)
{
- --let $_binlog_start=248
+ --let $_binlog_start=249
}
if ($binlog_file)
{
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index 65a0fad4a84..20f8eac7f8f 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -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)
diff --git a/mysql-test/suite/rpl/r/rpl_checksum.result b/mysql-test/suite/rpl/r/rpl_checksum.result
index 3f9c780ed67..b8c718ff821 100644
--- a/mysql-test/suite/rpl/r/rpl_checksum.result
+++ b/mysql-test/suite/rpl/r/rpl_checksum.result
@@ -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
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index a2a89722868..f7470d93842 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -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
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
index 4e3acc8a8bc..14db85da8e2 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff
@@ -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
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index fac934f01ef..d98ca0129eb 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -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
diff --git a/sql/log.cc b/sql/log.cc
index 8d8c96f6703..8a6d38c7e2e 100644
--- a/sql/log.cc
+++ b/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)
diff --git a/sql/log.h b/sql/log.h
index 31cb4b2f0ae..9bf80d6e603 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -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);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 8617e35953e..5bdcb8fcbf4 100644
--- a/sql/log_event.cc
+++ b/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 */
diff --git a/sql/log_event.h b/sql/log_event.h
index 77b3d1f5216..f96075db77d 100644
--- a/sql/log_event.h
+++ b/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:
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 76d74952e89..8d0ac59f89e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -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 */
diff --git a/sql/mysqld.h b/sql/mysqld.h
index e494b1abbe1..16ba93ab434 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -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[];
diff --git a/sql/rpl_constants.h b/sql/rpl_constants.h
index b1f1286184e..0a7fde439dd 100644
--- a/sql/rpl_constants.h
+++ b/sql/rpl_constants.h
@@ -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 */
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 8703ee4ff0c..844c3a3c4f8 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -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;
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 6fcd841d18a..078838f9ef2 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -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));
diff --git a/sql/slave.cc b/sql/slave.cc
index 13acc8c62ba..6e5bfedf89b 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -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)
{
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 2a4c26de1c9..5cf55d89d3e 100644
--- a/sql/sql_repl.cc
+++ b/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;
diff --git a/sql/sql_string.h b/sql/sql_string.h
index a46374373f5..99fe6b60d37 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -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);
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 99611c557f6..387fe1b7ef7 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -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",