Skip to content

Commit

Permalink
Binlog in Engine: Very first sketch, able to create and write an Inno…
Browse files Browse the repository at this point in the history
…DB tablespace

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
  • Loading branch information
knielsen committed Feb 26, 2024
1 parent ae6684d commit 95958c3
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 8 deletions.
11 changes: 11 additions & 0 deletions mysql-test/suite/binlog/t/binlog_in_engine.test
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 2 additions & 1 deletion storage/innobase/buf/buf0flu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1626,7 +1626,8 @@ static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED,
bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed)
{
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;
ulint max_n_flush= srv_io_capacity;
Expand Down
10 changes: 7 additions & 3 deletions storage/innobase/fil/fil0fil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ it is an absolute path. */
const char* fil_path_to_mysql_datadir;

/** Common InnoDB file extensions */
const char* dot_ext[] = { "", ".ibd", ".isl", ".cfg" };
const char* dot_ext[] = { "", ".ibd", ".isl", ".cfg", ".ibb" };

/** Number of pending tablespace flushes */
Atomic_counter<ulint> fil_n_pending_tablespace_flushes;
Expand Down Expand Up @@ -1044,6 +1044,9 @@ fil_space_t *fil_space_t::create(uint32_t id, uint32_t flags,
if (UNIV_LIKELY(id <= fil_system.max_assigned_id)) {
break;
}
if (id == SRV_SPACE_ID_BINLOG0 || id == SRV_SPACE_ID_BINLOG1) {
break;
}
if (UNIV_UNLIKELY(srv_operation == SRV_OPERATION_BACKUP)) {
break;
}
Expand Down Expand Up @@ -1603,9 +1606,10 @@ inline void mtr_t::log_file_op(mfile_type_t type, uint32_t space_id,
ut_ad(!(byte(type) & 15));

/* 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(!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;
if (!is_logged())
Expand Down
126 changes: 126 additions & 0 deletions storage/innobase/fsp/fsp0fsp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3763,3 +3763,129 @@ void fsp_shrink_temp_space()
mtr.commit();
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_FILE_ON_ERROR_NO_EXIT,
OS_FILE_AIO, 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()),
FIL_TYPE_TABLESPACE, 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);
IF_WIN(node->find_metadata(), node->find_metadata(fh, true));
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();
}
4 changes: 4 additions & 0 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4481,6 +4481,10 @@ innobase_commit(
if (commit_trx
|| (!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. */
if (!trx->active_commit_ordered) {
innobase_commit_ordered_2(trx, thd);
Expand Down
4 changes: 3 additions & 1 deletion storage/innobase/include/fil0fil.h
Original file line number Diff line number Diff line change
Expand Up @@ -1129,10 +1129,12 @@ enum ib_extention {
NO_EXT = 0,
IBD = 1,
ISL = 2,
CFG = 3
CFG = 3,
IBB = 4
};
extern const char* dot_ext[];
#define DOT_IBD dot_ext[IBD]
#define DOT_IBB dot_ext[IBB]
#define DOT_ISL dot_ext[ISL]
#define DOT_CFG dot_ext[CFG]

Expand Down
2 changes: 2 additions & 0 deletions storage/innobase/include/fsp0fsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,8 @@ void fsp_system_tablespace_truncate();
/** Truncate the temporary tablespace */
void fsp_shrink_temp_space();

extern void fsp_binlog_test(const uchar *data, uint32_t len);

#ifndef UNIV_DEBUG
# define fsp_init_file_page(space, block, mtr) fsp_init_file_page(block, mtr)
#endif
Expand Down
6 changes: 5 additions & 1 deletion storage/innobase/include/fsp0types.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ Created May 26, 2009 Vasil Dimov
#pragma once
#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;
/** 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. */
constexpr uint32_t SRV_TMP_SPACE_ID= 0xFFFFFFFEU;

Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/include/mtr0log.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Mini-transaction log record encoding and decoding
#include "mtr0mtr.h"

/** 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) */
constexpr uint32_t MIN_2BYTE= 1 << 7;
Expand Down
3 changes: 2 additions & 1 deletion storage/innobase/log/log0recv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2973,7 +2973,8 @@ recv_sys_t::parse_mtr_result recv_sys_t::parse(source &l, bool if_exists)

if (is_predefined_tablespace(space_id))
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;

if (UNIV_UNLIKELY(!recv_needed_recovery && srv_read_only_mode))
Expand Down

0 comments on commit 95958c3

Please sign in to comment.