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.
This commit is contained in:
parent
91ab42a823
commit
120b73a069
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
dstsize= encryption_encrypted_length((uint)len, ENCRYPTION_KEY_SYSTEM_DATA,
|
||||
crypto->key_version);
|
||||
if (!(dst= (uchar*)my_safe_alloca(dstsize)))
|
||||
return 1;
|
||||
|
||||
if (encryption_ctx_update(ctx, pos, (uint)len, dst, &dstlen))
|
||||
{
|
||||
dstsize= encryption_encrypted_length((uint)len, ENCRYPTION_KEY_SYSTEM_DATA,
|
||||
crypto->key_version);
|
||||
if (!(dst= (uchar*)my_safe_alloca(dstsize)))
|
||||
return 1;
|
||||
|
||||
uint dstlen;
|
||||
if (len == 0)
|
||||
dstlen= 0;
|
||||
else if (encryption_ctx_update(ctx, pos, (uint)len, dst, &dstlen))
|
||||
goto err;
|
||||
|
||||
if (maybe_write_event_len(dst, dstlen))
|
||||
return 1;
|
||||
pos= dst;
|
||||
len= dstlen;
|
||||
}
|
||||
if (write_internal(pos, len))
|
||||
res= 1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user