summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2020-01-30 15:50:45 +0200
committerMonty <monty@mariadb.org>2020-03-24 21:00:03 +0200
commit120b73a0692511004bce1e4b4225ad86c051231a (patch)
treee4caa7fd6eb1694c9b81b086ccebc455283361ff /sql
parent91ab42a823b244a3d4b051ab79701b7a552f274a (diff)
downloadmariadb-git-120b73a0692511004bce1e4b4225ad86c051231a.tar.gz
Speed up writing to encrypted binlogs
MDEV-21604 Added "virtual" low level write function encrypt_or_write that is set to point to either normal or encrypted write functions. This patch also fixes a possible memory leak if writing to binary log fails.
Diffstat (limited to 'sql')
-rw-r--r--sql/log.cc7
-rw-r--r--sql/log_event.h7
-rw-r--r--sql/log_event_server.cc51
3 files changed, 39 insertions, 26 deletions
diff --git a/sql/log.cc b/sql/log.cc
index 6e11283904e..72833c7c173 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -5444,7 +5444,10 @@ bool MYSQL_BIN_LOG::write_event(Log_event *ev, binlog_cache_data *cache_data,
{
Log_event_writer writer(file, 0, &crypto);
if (crypto.scheme && file == &log_file)
+ {
writer.ctx= alloca(crypto.ctx_size);
+ writer.set_encrypted_writer();
+ }
if (cache_data)
cache_data->add_status(ev->logged_status());
return writer.write(ev);
@@ -7242,8 +7245,10 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
CacheWriter writer(thd, &log_file, binlog_checksum_options, &crypto);
if (crypto.scheme)
+ {
writer.ctx= alloca(crypto.ctx_size);
-
+ writer.set_encrypted_writer();
+ }
// while there is just one alg the following must hold:
DBUG_ASSERT(binlog_checksum_options == BINLOG_CHECKSUM_ALG_OFF ||
binlog_checksum_options == BINLOG_CHECKSUM_ALG_CRC32);
diff --git a/sql/log_event.h b/sql/log_event.h
index bbbe5c915ad..639cbfbe7aa 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -932,6 +932,8 @@ typedef struct st_print_event_info
class Log_event_writer
{
+ /* Log_event_writer is updated when ctx is set */
+ int (Log_event_writer::*encrypt_or_write)(const uchar *pos, size_t len);
public:
ulonglong bytes_written;
void *ctx; ///< Encryption context or 0 if no encryption is needed
@@ -943,10 +945,13 @@ public:
my_off_t pos() { return my_b_safe_tell(file); }
void add_status(enum_logged_status status);
void set_incident();
+ void set_encrypted_writer()
+ { encrypt_or_write= &Log_event_writer::encrypt_and_write; }
Log_event_writer(IO_CACHE *file_arg, binlog_cache_data *cache_data_arg,
Binlog_crypt_data *cr= 0)
- : bytes_written(0), ctx(0),
+ :encrypt_or_write(&Log_event_writer::write_internal),
+ bytes_written(0), ctx(0),
file(file_arg), cache_data(cache_data_arg), crypto(cr) { }
private:
diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc
index dace82aa835..663be5b647d 100644
--- a/sql/log_event_server.cc
+++ b/sql/log_event_server.cc
@@ -798,6 +798,7 @@ my_bool Log_event::need_checksum()
int Log_event_writer::write_internal(const uchar *pos, size_t len)
{
+ DBUG_ASSERT(!ctx || encrypt_or_write == &Log_event_writer::encrypt_and_write);
if (my_b_safe_write(file, pos, len))
{
DBUG_PRINT("error", ("write to log failed: %d", my_errno));
@@ -826,35 +827,37 @@ int Log_event_writer::maybe_write_event_len(uchar *pos, size_t len)
int Log_event_writer::encrypt_and_write(const uchar *pos, size_t len)
{
- uchar *dst= 0;
- size_t dstsize= 0;
+ uchar *dst;
+ size_t dstsize;
+ uint dstlen;
+ int res; // Safe as res is always set
+ DBUG_ASSERT(ctx);
- if (ctx)
- {
- dstsize= encryption_encrypted_length((uint)len, ENCRYPTION_KEY_SYSTEM_DATA,
- crypto->key_version);
- if (!(dst= (uchar*)my_safe_alloca(dstsize)))
- return 1;
+ if (!len)
+ return 0;
- uint dstlen;
- if (len == 0)
- dstlen= 0;
- else if (encryption_ctx_update(ctx, pos, (uint)len, dst, &dstlen))
- goto err;
+ dstsize= encryption_encrypted_length((uint)len, ENCRYPTION_KEY_SYSTEM_DATA,
+ crypto->key_version);
+ if (!(dst= (uchar*)my_safe_alloca(dstsize)))
+ return 1;
- if (maybe_write_event_len(dst, dstlen))
- return 1;
- pos= dst;
- len= dstlen;
+ if (encryption_ctx_update(ctx, pos, (uint)len, dst, &dstlen))
+ {
+ res= 1;
+ goto err;
}
- if (write_internal(pos, len))
+
+ if (maybe_write_event_len(dst, dstlen))
+ {
+ res= 1;
goto err;
+ }
+
+ res= write_internal(dst, dstlen);
- my_safe_afree(dst, dstsize);
- return 0;
err:
my_safe_afree(dst, dstsize);
- return 1;
+ return res;
}
int Log_event_writer::write_header(uchar *pos, size_t len)
@@ -890,7 +893,7 @@ int Log_event_writer::write_header(uchar *pos, size_t len)
pos+= 4;
len-= 4;
}
- DBUG_RETURN(encrypt_and_write(pos, len));
+ DBUG_RETURN((this->*encrypt_or_write)(pos, len));
}
int Log_event_writer::write_data(const uchar *pos, size_t len)
@@ -899,7 +902,7 @@ int Log_event_writer::write_data(const uchar *pos, size_t len)
if (checksum_len)
crc= my_checksum(crc, pos, len);
- DBUG_RETURN(encrypt_and_write(pos, len));
+ DBUG_RETURN((this->*encrypt_or_write)(pos, len));
}
int Log_event_writer::write_footer()
@@ -909,7 +912,7 @@ int Log_event_writer::write_footer()
{
uchar checksum_buf[BINLOG_CHECKSUM_LEN];
int4store(checksum_buf, crc);
- if (encrypt_and_write(checksum_buf, BINLOG_CHECKSUM_LEN))
+ if ((this->*encrypt_or_write)(checksum_buf, BINLOG_CHECKSUM_LEN))
DBUG_RETURN(ER_ERROR_ON_WRITE);
}
if (ctx)