diff options
author | Monty <monty@mariadb.org> | 2020-01-30 15:50:45 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2020-03-24 21:00:03 +0200 |
commit | 120b73a0692511004bce1e4b4225ad86c051231a (patch) | |
tree | e4caa7fd6eb1694c9b81b086ccebc455283361ff /sql | |
parent | 91ab42a823b244a3d4b051ab79701b7a552f274a (diff) | |
download | mariadb-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.cc | 7 | ||||
-rw-r--r-- | sql/log_event.h | 7 | ||||
-rw-r--r-- | sql/log_event_server.cc | 51 |
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) |