mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-34705: Binlog in Engine: Very first sketch, able to create and write an InnoDB tablespace
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
11
mysql-test/suite/binlog/t/binlog_in_engine.test
Normal file
11
mysql-test/suite/binlog/t/binlog_in_engine.test
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_binlog_format_mixed.inc
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (2);
|
||||||
|
INSERT INTO t1 VALUES (3);
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
DROP TABLE t1;
|
@@ -1605,7 +1605,8 @@ static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED,
|
|||||||
bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) noexcept
|
bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) noexcept
|
||||||
{
|
{
|
||||||
const auto space_id= space->id;
|
const auto space_id= space->id;
|
||||||
ut_ad(space_id < SRV_SPACE_ID_UPPER_BOUND);
|
ut_ad(space_id < SRV_SPACE_ID_UPPER_BOUND ||
|
||||||
|
space_id == SRV_SPACE_ID_BINLOG0 || space_id == SRV_SPACE_ID_BINLOG1);
|
||||||
|
|
||||||
bool may_have_skipped= false;
|
bool may_have_skipped= false;
|
||||||
ulint max_n_flush= srv_io_capacity;
|
ulint max_n_flush= srv_io_capacity;
|
||||||
|
@@ -186,7 +186,7 @@ it is an absolute path. */
|
|||||||
const char* fil_path_to_mysql_datadir;
|
const char* fil_path_to_mysql_datadir;
|
||||||
|
|
||||||
/** Common InnoDB file extensions */
|
/** Common InnoDB file extensions */
|
||||||
const char* dot_ext[] = { "", ".ibd", ".isl", ".cfg" };
|
const char* dot_ext[] = { "", ".ibd", ".isl", ".cfg", ".ibb" };
|
||||||
|
|
||||||
/** Number of pending tablespace flushes */
|
/** Number of pending tablespace flushes */
|
||||||
Atomic_counter<ulint> fil_n_pending_tablespace_flushes;
|
Atomic_counter<ulint> fil_n_pending_tablespace_flushes;
|
||||||
@@ -1003,6 +1003,8 @@ fil_space_t *fil_space_t::create(uint32_t id, uint32_t flags,
|
|||||||
default:
|
default:
|
||||||
if (UNIV_LIKELY(id <= fil_system.max_assigned_id))
|
if (UNIV_LIKELY(id <= fil_system.max_assigned_id))
|
||||||
break;
|
break;
|
||||||
|
if (id == SRV_SPACE_ID_BINLOG0 || id == SRV_SPACE_ID_BINLOG1)
|
||||||
|
break;
|
||||||
if (UNIV_UNLIKELY(srv_operation == SRV_OPERATION_BACKUP))
|
if (UNIV_UNLIKELY(srv_operation == SRV_OPERATION_BACKUP))
|
||||||
break;
|
break;
|
||||||
if (!fil_system.space_id_reuse_warned)
|
if (!fil_system.space_id_reuse_warned)
|
||||||
@@ -1560,9 +1562,10 @@ inline void mtr_t::log_file_op(mfile_type_t type, uint32_t space_id,
|
|||||||
ut_ad(!(byte(type) & 15));
|
ut_ad(!(byte(type) & 15));
|
||||||
|
|
||||||
/* fil_name_parse() requires that there be at least one path
|
/* fil_name_parse() requires that there be at least one path
|
||||||
separator and that the file path end with ".ibd". */
|
separator and that the file path end with ".ibd" or "ibb". */
|
||||||
ut_ad(strchr(path, '/'));
|
ut_ad(strchr(path, '/'));
|
||||||
ut_ad(!strcmp(&path[strlen(path) - strlen(DOT_IBD)], DOT_IBD));
|
ut_ad(!strcmp(&path[strlen(path) - strlen(DOT_IBD)], DOT_IBD) ||
|
||||||
|
!strcmp(&path[strlen(path) - strlen(DOT_IBB)], DOT_IBB));
|
||||||
|
|
||||||
m_modifications= true;
|
m_modifications= true;
|
||||||
if (!is_logged())
|
if (!is_logged())
|
||||||
|
@@ -4266,3 +4266,127 @@ func_exit:
|
|||||||
mtr.commit();
|
mtr.commit();
|
||||||
sql_print_information("InnoDB: Temporary tablespace truncated successfully");
|
sql_print_information("InnoDB: Temporary tablespace truncated successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fil_space_t* binlog_space;
|
||||||
|
buf_block_t *binlog_cur_block;
|
||||||
|
uint32_t binlog_cur_page_no;
|
||||||
|
uint32_t binlog_cur_page_offset;
|
||||||
|
|
||||||
|
/** Create a binlog tablespace file
|
||||||
|
@param[in] name file name
|
||||||
|
@return DB_SUCCESS or error code */
|
||||||
|
dberr_t fsp_binlog_tablespace_create(const char* name)
|
||||||
|
{
|
||||||
|
pfs_os_file_t fh;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
uint32_t size= (1<<20) >> srv_page_size_shift /* ToDo --max-binlog-size */;
|
||||||
|
if(srv_read_only_mode)
|
||||||
|
return DB_ERROR;
|
||||||
|
|
||||||
|
os_file_create_subdirs_if_needed(name);
|
||||||
|
|
||||||
|
/* ToDo: Do we need here an mtr.log_file_op(FILE_CREATE) like in fil_ibd_create(()? */
|
||||||
|
fh = os_file_create(
|
||||||
|
innodb_data_file_key, name,
|
||||||
|
OS_FILE_CREATE, OS_DATA_FILE, srv_read_only_mode, &ret);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
os_file_close(fh);
|
||||||
|
return DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ToDo: Enryption? */
|
||||||
|
fil_encryption_t mode= FIL_ENCRYPTION_OFF;
|
||||||
|
fil_space_crypt_t* crypt_data= nullptr;
|
||||||
|
|
||||||
|
/* We created the binlog file and now write it full of zeros */
|
||||||
|
if (!os_file_set_size(name, fh,
|
||||||
|
os_offset_t{size} << srv_page_size_shift)) {
|
||||||
|
ib::error() << "Unable to allocate " << name;
|
||||||
|
os_file_close(fh);
|
||||||
|
os_file_delete(innodb_data_file_key, name);
|
||||||
|
return DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
|
uint32_t space_id= SRV_SPACE_ID_BINLOG0;
|
||||||
|
if (!(binlog_space= fil_space_t::create(space_id,
|
||||||
|
( FSP_FLAGS_FCRC32_MASK_MARKER |
|
||||||
|
FSP_FLAGS_FCRC32_PAGE_SSIZE()),
|
||||||
|
false, crypt_data,
|
||||||
|
mode, true))) {
|
||||||
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
return DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
fil_node_t* node = binlog_space->add(name, fh, size, false, true);
|
||||||
|
node->find_metadata();
|
||||||
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
|
||||||
|
binlog_cur_page_no= 0;
|
||||||
|
binlog_cur_page_offset= FIL_PAGE_DATA;
|
||||||
|
return DB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fsp_binlog_write_start(uint32_t page_no,
|
||||||
|
const uchar *data, uint32_t len, mtr_t *mtr)
|
||||||
|
{
|
||||||
|
buf_block_t *block= fsp_page_create(binlog_space, page_no, mtr);
|
||||||
|
mtr->memcpy<mtr_t::MAYBE_NOP>(*block, FIL_PAGE_DATA + block->page.frame,
|
||||||
|
data, len);
|
||||||
|
binlog_cur_block= block;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fsp_binlog_write_offset(uint32_t page_no, uint32_t offset,
|
||||||
|
const uchar *data, uint32_t len, mtr_t *mtr)
|
||||||
|
{
|
||||||
|
dberr_t err;
|
||||||
|
/* ToDo: Is RW_SX_LATCH appropriate here? */
|
||||||
|
buf_block_t *block= buf_page_get_gen(page_id_t{binlog_space->id, page_no},
|
||||||
|
0, RW_SX_LATCH, binlog_cur_block,
|
||||||
|
BUF_GET, mtr, &err);
|
||||||
|
ut_a(err == DB_SUCCESS);
|
||||||
|
mtr->memcpy<mtr_t::MAYBE_NOP>(*block,
|
||||||
|
offset + block->page.frame,
|
||||||
|
data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fsp_binlog_append(const uchar *data, uint32_t len, mtr_t *mtr)
|
||||||
|
{
|
||||||
|
ut_ad(binlog_cur_page_offset <= srv_page_size - FIL_PAGE_DATA_END);
|
||||||
|
uint32_t remain= ((uint32_t)srv_page_size - FIL_PAGE_DATA_END) -
|
||||||
|
binlog_cur_page_offset;
|
||||||
|
// ToDo: Some kind of mutex to protect binlog access.
|
||||||
|
while (len > 0) {
|
||||||
|
if (remain < 4) {
|
||||||
|
binlog_cur_page_offset= FIL_PAGE_DATA;
|
||||||
|
remain= ((uint32_t)srv_page_size - FIL_PAGE_DATA_END) -
|
||||||
|
binlog_cur_page_offset;
|
||||||
|
++binlog_cur_page_no;
|
||||||
|
}
|
||||||
|
uint32_t this_len= std::min<uint32_t>(len, remain);
|
||||||
|
if (binlog_cur_page_offset == FIL_PAGE_DATA)
|
||||||
|
fsp_binlog_write_start(binlog_cur_page_no, data, this_len, mtr);
|
||||||
|
else
|
||||||
|
fsp_binlog_write_offset(binlog_cur_page_no, binlog_cur_page_offset,
|
||||||
|
data, this_len, mtr);
|
||||||
|
len-= this_len;
|
||||||
|
data+= this_len;
|
||||||
|
binlog_cur_page_offset+= this_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fsp_binlog_test(const uchar *data, uint32_t len)
|
||||||
|
{
|
||||||
|
mtr_t mtr;
|
||||||
|
mtr.start();
|
||||||
|
if (!binlog_space)
|
||||||
|
fsp_binlog_tablespace_create("./binlog-000000.ibb");
|
||||||
|
mtr.set_named_space(binlog_space);
|
||||||
|
fsp_binlog_append(data, len, &mtr);
|
||||||
|
mtr.commit();
|
||||||
|
}
|
||||||
|
@@ -4550,6 +4550,10 @@ innobase_commit(
|
|||||||
if (commit_trx
|
if (commit_trx
|
||||||
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
|
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
|
||||||
|
|
||||||
|
/* ToDo: This is just a random very initial test of writing
|
||||||
|
something into a binlog tablespace. */
|
||||||
|
if (!opt_bootstrap)
|
||||||
|
fsp_binlog_test((const uchar *)"Hulubulu!!?!", 12);
|
||||||
/* Run the fast part of commit if we did not already. */
|
/* Run the fast part of commit if we did not already. */
|
||||||
if (!trx->active_commit_ordered) {
|
if (!trx->active_commit_ordered) {
|
||||||
innobase_commit_ordered_2(trx, thd);
|
innobase_commit_ordered_2(trx, thd);
|
||||||
|
@@ -1120,10 +1120,12 @@ enum ib_extention {
|
|||||||
NO_EXT = 0,
|
NO_EXT = 0,
|
||||||
IBD = 1,
|
IBD = 1,
|
||||||
ISL = 2,
|
ISL = 2,
|
||||||
CFG = 3
|
CFG = 3,
|
||||||
|
IBB = 4
|
||||||
};
|
};
|
||||||
extern const char* dot_ext[];
|
extern const char* dot_ext[];
|
||||||
#define DOT_IBD dot_ext[IBD]
|
#define DOT_IBD dot_ext[IBD]
|
||||||
|
#define DOT_IBB dot_ext[IBB]
|
||||||
#define DOT_ISL dot_ext[ISL]
|
#define DOT_ISL dot_ext[ISL]
|
||||||
#define DOT_CFG dot_ext[CFG]
|
#define DOT_CFG dot_ext[CFG]
|
||||||
|
|
||||||
|
@@ -556,6 +556,8 @@ void fsp_system_tablespace_truncate(bool shutdown);
|
|||||||
/** Truncate the temporary tablespace */
|
/** Truncate the temporary tablespace */
|
||||||
void fsp_shrink_temp_space();
|
void fsp_shrink_temp_space();
|
||||||
|
|
||||||
|
extern void fsp_binlog_test(const uchar *data, uint32_t len);
|
||||||
|
|
||||||
#ifndef UNIV_DEBUG
|
#ifndef UNIV_DEBUG
|
||||||
# define fsp_init_file_page(space, block, mtr) fsp_init_file_page(block, mtr)
|
# define fsp_init_file_page(space, block, mtr) fsp_init_file_page(block, mtr)
|
||||||
#endif
|
#endif
|
||||||
|
@@ -27,8 +27,12 @@ Created May 26, 2009 Vasil Dimov
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ut0byte.h"
|
#include "ut0byte.h"
|
||||||
|
|
||||||
/** All persistent tablespaces have a smaller fil_space_t::id than this. */
|
/** All persistent tablespaces (except binlog tablespaces) have a smaller
|
||||||
|
fil_space_t::id than this. */
|
||||||
constexpr uint32_t SRV_SPACE_ID_UPPER_BOUND= 0xFFFFFFF0U;
|
constexpr uint32_t SRV_SPACE_ID_UPPER_BOUND= 0xFFFFFFF0U;
|
||||||
|
/** Binlog tablespaces. */
|
||||||
|
constexpr uint32_t SRV_SPACE_ID_BINLOG0 = SRV_SPACE_ID_UPPER_BOUND + 1;
|
||||||
|
constexpr uint32_t SRV_SPACE_ID_BINLOG1 = SRV_SPACE_ID_UPPER_BOUND + 2;
|
||||||
/** The fil_space_t::id of the innodb_temporary tablespace. */
|
/** The fil_space_t::id of the innodb_temporary tablespace. */
|
||||||
constexpr uint32_t SRV_TMP_SPACE_ID= 0xFFFFFFFEU;
|
constexpr uint32_t SRV_TMP_SPACE_ID= 0xFFFFFFFEU;
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ Mini-transaction log record encoding and decoding
|
|||||||
#include "mtr0mtr.h"
|
#include "mtr0mtr.h"
|
||||||
|
|
||||||
/** The smallest invalid page identifier for persistent tablespaces */
|
/** The smallest invalid page identifier for persistent tablespaces */
|
||||||
constexpr page_id_t end_page_id{SRV_SPACE_ID_UPPER_BOUND, 0};
|
constexpr page_id_t end_page_id{SRV_SPACE_ID_BINLOG1, 0};
|
||||||
|
|
||||||
/** The minimum 2-byte integer (0b10xxxxxx xxxxxxxx) */
|
/** The minimum 2-byte integer (0b10xxxxxx xxxxxxxx) */
|
||||||
constexpr uint32_t MIN_2BYTE= 1 << 7;
|
constexpr uint32_t MIN_2BYTE= 1 << 7;
|
||||||
|
@@ -2998,7 +2998,8 @@ restart:
|
|||||||
|
|
||||||
if (space_id == TRX_SYS_SPACE || srv_is_undo_tablespace(space_id))
|
if (space_id == TRX_SYS_SPACE || srv_is_undo_tablespace(space_id))
|
||||||
goto file_rec_error;
|
goto file_rec_error;
|
||||||
if (fnend - fn < 4 || memcmp(fnend - 4, DOT_IBD, 4))
|
if (fnend - fn < 4 ||
|
||||||
|
(memcmp(fnend - 4, DOT_IBD, 4) && memcmp(fnend - 4, DOT_IBB, 4)))
|
||||||
goto file_rec_error;
|
goto file_rec_error;
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(!recv_needed_recovery && srv_read_only_mode))
|
if (UNIV_UNLIKELY(!recv_needed_recovery && srv_read_only_mode))
|
||||||
|
Reference in New Issue
Block a user