MySQL  8.0.27
Source Code Documentation
binlog_ostream.h
Go to the documentation of this file.
1 /* Copyright (c) 2018, 2021, Oracle and/or its affiliates.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef BINLOG_OSTREAM_INCLUDED
24 #define BINLOG_OSTREAM_INCLUDED
25 
26 #include <openssl/evp.h>
27 #include "sql/basic_ostream.h"
28 #include "sql/rpl_log_encryption.h"
29 
30 // True if binlog cache is reset.
31 #ifndef NDEBUG
32 extern bool binlog_cache_is_reset;
33 #endif
34 
35 /**
36  Copy data from an input stream to an output stream.
37 
38  @param[in] istream the input stream where data will be copied from
39  @param[out] ostream the output stream where data will be copied into
40  @param[out] ostream_error It will be set to true if an error happens on
41  ostream and the pointer is not null. It is valid
42  only when the function returns true.
43 
44  @retval false Success
45  @retval true Error happens in either the istream or ostream.
46 */
47 template <class ISTREAM, class OSTREAM>
48 bool stream_copy(ISTREAM *istream, OSTREAM *ostream,
49  bool *ostream_error = nullptr) {
50  unsigned char *buffer = nullptr;
51  my_off_t length = 0;
52 
53  bool ret = istream->begin(&buffer, &length);
54  while (!ret && length > 0) {
55  if (ostream->write(buffer, length)) {
56  if (ostream_error != nullptr) *ostream_error = true;
57  return true;
58  }
59 
60  ret = istream->next(&buffer, &length);
61  }
62  return ret;
63 }
64 
65 /**
66  A binlog cache implementation based on IO_CACHE.
67 */
69  public:
72  const IO_CACHE_binlog_cache_storage &) = delete;
75 
76  /**
77  Opens the binlog cache. It creates a memory buffer as long as cache_size.
78  The buffer will be extended up to max_cache_size when writting data. The
79  data exceeds max_cache_size will be writting into temporary file.
80 
81  @param[in] dir Where the temporary file will be created
82  @param[in] prefix Prefix of the temporary file name
83  @param[in] cache_size Size of the memory buffer.
84  @param[in] max_cache_size Maximum size of the memory buffer
85  @retval false Success
86  @retval true Error
87  */
88  bool open(const char *dir, const char *prefix, my_off_t cache_size,
89  my_off_t max_cache_size);
90  void close();
91 
92  bool write(const unsigned char *buffer, my_off_t length) override;
93  bool truncate(my_off_t offset) override;
94  /* purecov: inspected */
95  /* binlog cache doesn't need seek operation. Setting true to return error */
96  bool seek(my_off_t offset [[maybe_unused]]) override { return true; }
97  /**
98  Reset status and drop all data. It looks like a cache never was used after
99  reset.
100  */
101  bool reset();
102  /**
103  Returns the file name if a temporary file is opened, otherwise nullptr is
104  returned.
105  */
106  const char *tmp_file_name() const;
107  /**
108  Returns the count of calling temporary file's write()
109  */
110  size_t disk_writes() const;
111 
112  /**
113  Initializes binlog cache for reading and returns the data at the begin.
114  buffer is controlled by binlog cache implementation, so caller should
115  not release it. If the function sets *length to 0 and no error happens,
116  it has reached the end of the cache.
117 
118  @param[out] buffer It points to buffer where data is read.
119  @param[out] length Length of the data in the buffer.
120  @retval false Success
121  @retval true Error
122  */
123  bool begin(unsigned char **buffer, my_off_t *length);
124  /**
125  Returns next piece of data. buffer is controlled by binlog cache
126  implementation, so caller should not release it. If the function sets
127  *length to 0 and no error happens, it has reached the end of the cache.
128 
129  @param[out] buffer It points to buffer where data is read.
130  @param[out] length Length of the data in the buffer.
131  @retval false Success
132  @retval true Error
133  */
134  bool next(unsigned char **buffer, my_off_t *length);
135  my_off_t length() const;
136  bool flush() override { return false; }
137  bool sync() override { return false; }
138 
139  private:
142  /**
143  Enable IO Cache temporary file encryption.
144 
145  @retval false Success.
146  @retval true Error.
147  */
148  bool enable_encryption();
149  /**
150  Disable IO Cache temporary file encryption.
151  */
152  void disable_encryption();
153  /**
154  Generate a new password for the temporary file encryption.
155 
156  This function is called by reset() that is called every time a transaction
157  commits to cleanup the binary log cache. The file password shall vary not
158  only per temporary file, but also per transaction being committed within a
159  single client connection.
160 
161  @retval false Success.
162  @retval true Error.
163  */
164  bool setup_ciphers_password();
165 };
166 
167 /**
168  Byte container that provides a storage for serializing session
169  binlog events. This way of arranging the classes separates storage layer
170  and binlog layer, hides the implementation detail of low level storage.
171 */
173  public:
174  ~Binlog_cache_storage() override;
175 
176  bool open(my_off_t cache_size, my_off_t max_cache_size);
177  void close();
178 
179  bool write(const unsigned char *buffer, my_off_t length) override {
180  assert(m_pipeline_head != nullptr);
182  }
183  /**
184  Truncates some data at the end of the binlog cache.
185 
186  @param[in] offset Where the binlog cache will be truncated to.
187  @retval false Success
188  @retval true Error
189  */
190  bool truncate(my_off_t offset) { return m_pipeline_head->truncate(offset); }
191 
192  /**
193  Reset status and drop all data. It looks like a cache was never used
194  after reset.
195  */
196  bool reset() { return m_file.reset(); }
197  /**
198  Returns the count of disk writes
199  */
200  size_t disk_writes() const { return m_file.disk_writes(); }
201  /**
202  Returns the name of the temporary file.
203  */
204  const char *tmp_file_name() const { return m_file.tmp_file_name(); }
205 
206  /**
207  Copy all data to a output stream. This function hides the internal
208  implementation of storage detail. So it will not disturb the callers
209  if the implementation of Binlog_cache_storage is changed. If we add
210  a pipeline stream in this class, then we need to change the implementation
211  of this function. But callers are not affected.
212 
213  @param[out] ostream Where the data will be copied into
214  @param[out] ostream_error It will be set to true if an error happens on
215  ostream and the pointer is not null. It is valid
216  only when the function returns true.
217  @retval false Success
218  @retval true Error happens in either the istream or ostream.
219  */
220  bool copy_to(Basic_ostream *ostream, bool *ostream_error = nullptr) {
221  return stream_copy(&m_file, ostream, ostream_error);
222  }
223 
224  /**
225  Returns data length.
226  */
227  my_off_t length() const { return m_file.length(); }
228  /**
229  Returns true if binlog cache is empty.
230  */
231  bool is_empty() const { return length() == 0; }
232 
233  private:
236 };
237 
238 /**
239  It is an Truncatable_ostream which provides encryption feature. It can be
240  setup into an stream pipeline. In the pipeline, it encrypts the data
241  from up stream and then feeds the encrypted data into down stream.
242 */
244  public:
245  ~Binlog_encryption_ostream() override;
246 
247  /**
248  Initialize the context used in the encryption stream and write encryption
249  header into down stream.
250 
251  @param[in] down_ostream The stream for storing encrypted data.
252 
253  @retval false Success
254  @retval true Error.
255  */
256  bool open(std::unique_ptr<Truncatable_ostream> down_ostream);
257 
258  /**
259  Initialize the context used in the encryption stream based on the
260  header passed as parameter. It shall be used when opening an ostream for
261  a stream that was already encrypted (the cypher password already exists).
262 
263  @param[in] down_ostream the stream for storing encrypted data.
264  @param[in] header the encryption header to setup the cypher.
265 
266  @retval false Success.
267  @retval true Error.
268  */
269  bool open(std::unique_ptr<Truncatable_ostream> down_ostream,
270  std::unique_ptr<Rpl_encryption_header> header);
271 
272  /**
273  Re-encrypt the encrypted binary/relay log file header by replacing its
274  binlog encryption key id with the current one and its encrypted file
275  password with the new one, which is got by encrypting its file password
276  with the current binlog encryption key.
277 
278  @retval false Success with an empty error message.
279  @retval true Error with an error message.
280  */
281  std::pair<bool, std::string> reencrypt();
282 
283  void close();
284  bool write(const unsigned char *buffer, my_off_t length) override;
285  bool truncate(my_off_t offset) override;
286  bool seek(my_off_t offset) override;
287  bool flush() override;
288  bool sync() override;
289  /**
290  Return the encrypted file header size.
291 
292  @return the encrypted file header size.
293  */
294  int get_header_size();
295 
296  private:
297  std::unique_ptr<Truncatable_ostream> m_down_ostream;
298  std::unique_ptr<Rpl_encryption_header> m_header;
299  std::unique_ptr<Stream_cipher> m_encryptor;
300 };
301 #endif // BINLOG_OSTREAM_INCLUDED
bool stream_copy(ISTREAM *istream, OSTREAM *ostream, bool *ostream_error=nullptr)
Copy data from an input stream to an output stream.
Definition: binlog_ostream.h:48
bool binlog_cache_is_reset
Definition: binlog_ostream.cc:37
The abstract class for basic output streams which provides write operation.
Definition: basic_ostream.h:34
virtual bool write(const unsigned char *buffer, my_off_t length)=0
Write some bytes into the output stream.
Byte container that provides a storage for serializing session binlog events.
Definition: binlog_ostream.h:172
bool truncate(my_off_t offset)
Truncates some data at the end of the binlog cache.
Definition: binlog_ostream.h:190
~Binlog_cache_storage() override
Definition: binlog_ostream.cc:266
my_off_t length() const
Returns data length.
Definition: binlog_ostream.h:227
IO_CACHE_binlog_cache_storage m_file
Definition: binlog_ostream.h:235
bool is_empty() const
Returns true if binlog cache is empty.
Definition: binlog_ostream.h:231
Truncatable_ostream * m_pipeline_head
Definition: binlog_ostream.h:234
const char * tmp_file_name() const
Returns the name of the temporary file.
Definition: binlog_ostream.h:204
bool open(my_off_t cache_size, my_off_t max_cache_size)
Definition: binlog_ostream.cc:252
bool reset()
Reset status and drop all data.
Definition: binlog_ostream.h:196
size_t disk_writes() const
Returns the count of disk writes.
Definition: binlog_ostream.h:200
bool copy_to(Basic_ostream *ostream, bool *ostream_error=nullptr)
Copy all data to a output stream.
Definition: binlog_ostream.h:220
bool write(const unsigned char *buffer, my_off_t length) override
Write some bytes into the output stream.
Definition: binlog_ostream.h:179
void close()
Definition: binlog_ostream.cc:261
It is an Truncatable_ostream which provides encryption feature.
Definition: binlog_ostream.h:243
int get_header_size()
Return the encrypted file header size.
Definition: binlog_ostream.cc:410
bool open(std::unique_ptr< Truncatable_ostream > down_ostream)
Initialize the context used in the encryption stream and write encryption header into down stream.
Definition: binlog_ostream.cc:279
std::unique_ptr< Rpl_encryption_header > m_header
Definition: binlog_ostream.h:298
std::unique_ptr< Truncatable_ostream > m_down_ostream
Definition: binlog_ostream.h:297
std::unique_ptr< Stream_cipher > m_encryptor
Definition: binlog_ostream.h:299
void close()
Definition: binlog_ostream.cc:362
std::pair< bool, std::string > reencrypt()
Re-encrypt the encrypted binary/relay log file header by replacing its binlog encryption key id with ...
Definition: binlog_ostream.cc:315
bool write(const unsigned char *buffer, my_off_t length) override
Write some bytes into the output stream.
Definition: binlog_ostream.cc:368
bool sync() override
Sync.
Definition: binlog_ostream.cc:408
~Binlog_encryption_ostream() override
Definition: binlog_ostream.cc:268
bool flush() override
Flush data.
Definition: binlog_ostream.cc:406
bool truncate(my_off_t offset) override
Truncate some data at the end of the output stream.
Definition: binlog_ostream.cc:400
bool seek(my_off_t offset) override
Put the write position to a given offset.
Definition: binlog_ostream.cc:395
A binlog cache implementation based on IO_CACHE.
Definition: binlog_ostream.h:68
void disable_encryption()
Disable IO Cache temporary file encryption.
Definition: binlog_ostream.cc:222
const char * tmp_file_name() const
Returns the file name if a temporary file is opened, otherwise nullptr is returned.
Definition: binlog_ostream.cc:146
my_off_t m_max_cache_size
Definition: binlog_ostream.h:141
IO_CACHE_binlog_cache_storage(const IO_CACHE_binlog_cache_storage &)=delete
bool sync() override
Sync.
Definition: binlog_ostream.h:137
bool begin(unsigned char **buffer, my_off_t *length)
Initializes binlog cache for reading and returns the data at the begin.
Definition: binlog_ostream.cc:150
bool flush() override
Flush data.
Definition: binlog_ostream.h:136
bool reset()
Reset status and drop all data.
Definition: binlog_ostream.cc:107
bool truncate(my_off_t offset) override
Truncate some data at the end of the output stream.
Definition: binlog_ostream.cc:92
bool setup_ciphers_password()
Generate a new password for the temporary file encryption.
Definition: binlog_ostream.cc:233
size_t disk_writes() const
Returns the count of calling temporary file's write()
Definition: binlog_ostream.cc:142
bool open(const char *dir, const char *prefix, my_off_t cache_size, my_off_t max_cache_size)
Opens the binlog cache.
Definition: binlog_ostream.cc:43
my_off_t length() const
Definition: binlog_ostream.cc:195
bool enable_encryption()
Enable IO Cache temporary file encryption.
Definition: binlog_ostream.cc:200
void close()
Definition: binlog_ostream.cc:58
IO_CACHE_binlog_cache_storage & operator=(const IO_CACHE_binlog_cache_storage &)=delete
bool seek(my_off_t offset[[maybe_unused]]) override
Definition: binlog_ostream.h:96
IO_CACHE m_io_cache
Definition: binlog_ostream.h:140
~IO_CACHE_binlog_cache_storage() override
Definition: binlog_ostream.cc:41
bool write(const unsigned char *buffer, my_off_t length) override
Write some bytes into the output stream.
Definition: binlog_ostream.cc:60
bool next(unsigned char **buffer, my_off_t *length)
Returns next piece of data.
Definition: binlog_ostream.cc:183
Truncatable_ostream abstract class provides seek() and truncate() interfaces to all truncatable outpu...
Definition: basic_ostream.h:55
virtual bool truncate(my_off_t offset)=0
Truncate some data at the end of the output stream.
ulonglong my_off_t
Definition: my_inttypes.h:71
std::string dir
Double write files location.
Definition: buf0dblwr.cc:74
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:391
This file includes the major components for encrypting/decrypting binary log files.
Definition: my_sys.h:340
static uint64_t cache_size
Definition: xcom_cache.cc:360