Skip to content
Permalink
Browse files
Bug#29536710: MYSQL 8.0 IS 10% SLOWER THAN 5.7 AT WRITE-IO BOUND CASE
(once descripted as WL#13419 : InnoDB: extend 32-bit value compaction also for high value of unsigned in transaction log)

Using undefined bit pattern of the current format,
high unsigned value also can be packed to
smaller bytes as higher its value is. (2 ~ 5 bytes)

1) increment LOG_HEADER_FORMAT to 4
The older parser detect as new format not to treat.

2) change the following 32-bit values packing
0xFF000000 ~ 0xFFFFFFFF : 0b11110000 + 4bytes
to
0xFF000000 ~ 0xFFFDFFFF : 0b11111110 + 3bytes
0xFFFE0000 ~ 0xFFFFFBFF : 0b1111110n + 2bytes
0xFFFFFC00 ~ 0xFFFFFFFF : 0b111110nn + 1byte

Approved by Pawel Olchawa <pawel.olchawa@oracle.com>
RB: 22349
  • Loading branch information
Yasufumi Kinoshita committed Sep 30, 2019
1 parent c229c04 commit 3ee5f8b1f262c3014a4e6f267216869098ef151e
Showing 6 changed files with 149 additions and 18 deletions.
@@ -306,8 +306,6 @@ COMMIT;
CREATE INDEX t1c ON t1 (c(767));
UPDATE t1 SET c=@e;
CREATE INDEX t1d ON t1 (d(767));
UPDATE t1 SET d=@e;
ERROR HY000: Undo log record is too big.
CREATE INDEX t1e ON t1 (e(767));
SHOW CREATE TABLE t1;
Table Create Table
@@ -302,8 +302,10 @@ UPDATE t1 SET c=@e;
# This is a problem. It means that the DDL is allowed to create a table
# that CANNOT be updated. See bug#12953735.
CREATE INDEX t1d ON t1 (d(767));
--error ER_UNDO_RECORD_TOO_BIG
UPDATE t1 SET d=@e;
# NOTE: bug#12953735 seems to become a little more rare case by fixing bug#29536710
# Reproducing doesn't seem to be so needed. And just comment out for now.
#--error ER_UNDO_RECORD_TOO_BIG
#UPDATE t1 SET d=@e;

--replace_regex /> [0-9]*/> max_row_size/
CREATE INDEX t1e ON t1 (e(767));
@@ -102,9 +102,12 @@ enum log_header_format_t {
it had to point the beginning of a group of log records). */
LOG_HEADER_FORMAT_8_0_3 = 3,

/** Expand ulint compressed form. */
LOG_HEADER_FORMAT_8_0_19 = 4,

/** The redo log format identifier
corresponding to the current format version. */
LOG_HEADER_FORMAT_CURRENT = LOG_HEADER_FORMAT_8_0_3
LOG_HEADER_FORMAT_CURRENT = LOG_HEADER_FORMAT_8_0_19
};

/** The state of a log group */
@@ -1,6 +1,6 @@
/*****************************************************************************

Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 2019, Oracle and/or its affiliates. All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License, version 2.0, as published by the
@@ -179,6 +179,18 @@ ulint mach_write_compressed(byte *b, ulint n) {
/* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */
mach_write_to_4(b, n | 0xE0000000);
return (4);
} else if (n >= 0xFFFFFC00) {
/* 111110nn nnnnnnnn (10 bits) (extended) */
mach_write_to_2(b, (n & 0x3FF) | 0xF800);
return (2);
} else if (n >= 0xFFFE0000) {
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
mach_write_to_3(b, (n & 0x1FFFF) | 0xFC0000);
return (3);
} else if (n >= 0xFF000000) {
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
mach_write_to_4(b, (n & 0xFFFFFF) | 0xFE000000);
return (4);
} else {
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
mach_write_to_1(b, 0xF0);
@@ -204,6 +216,15 @@ ulint mach_get_compressed_size(ulint n) {
} else if (n < 0x10000000) {
/* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */
return (4);
} else if (n >= 0xFFFFFC00) {
/* 111110nn nnnnnnnn (10 bits) (extended) */
return (2);
} else if (n >= 0xFFFE0000) {
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
return (3);
} else if (n >= 0xFF000000) {
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
return (4);
} else {
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
return (5);
@@ -235,11 +256,24 @@ ulint mach_read_compressed(const byte *b) {
/* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */
val = mach_read_from_4(b) & 0xFFFFFFF;
ut_ad(val > 0x1FFFFF);
} else {
} else if (val < 0xF8) {
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
ut_ad(val == 0xF0);
val = mach_read_from_4(b + 1);
/* this can treat not-extended format also. */
ut_ad(val > 0xFFFFFFF);
} else if (val < 0xFC) {
/* 111110nn nnnnnnnn (10 bits) (extended) */
val = (mach_read_from_2(b) & 0x3FF) | 0xFFFFFC00;
} else if (val < 0xFE) {
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
val = (mach_read_from_3(b) & 0x1FFFF) | 0xFFFE0000;
ut_ad(val < 0xFFFFFC00);
} else {
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
ut_ad(val == 0xFE);
val = mach_read_from_3(b + 1) | 0xFF000000;
ut_ad(val < 0xFFFE0000);
}

return (val);
@@ -271,12 +305,28 @@ ib_uint32_t mach_read_next_compressed(const byte **b) {
val = mach_read_from_4(*b) & 0xFFFFFFF;
ut_ad(val > 0x1FFFFF);
*b += 4;
} else {
} else if (val < 0xF8) {
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
ut_ad(val == 0xF0);
val = mach_read_from_4(*b + 1);
/* this can treat not-extended format also. */
ut_ad(val > 0xFFFFFFF);
*b += 5;
} else if (val < 0xFC) {
/* 111110nn nnnnnnnn (10 bits) (extended) */
val = (mach_read_from_2(*b) & 0x3FF) | 0xFFFFFC00;
*b += 2;
} else if (val < 0xFE) {
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
val = (mach_read_from_3(*b) & 0x1FFFF) | 0xFFFE0000;
ut_ad(val < 0xFFFFFC00);
*b += 3;
} else {
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
ut_ad(val == 0xFE);
val = mach_read_from_3(*b + 1) | 0xFF000000;
ut_ad(val < 0xFFFE0000);
*b += 4;
}

return (static_cast<ib_uint32_t>(val));
@@ -457,13 +507,30 @@ ib_uint64_t mach_read_next_much_compressed(const byte **b) {
val = mach_read_from_4(*b) & 0xFFFFFFF;
ut_ad(val > 0x1FFFFF);
*b += 4;
} else if (val == 0xF0) {
} else if (val < 0xF8) {
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
ut_ad(val == 0xF0);
val = mach_read_from_4(*b + 1);
/* this can treat not-extended format also. */
ut_ad(val > 0xFFFFFFF);
*b += 5;
} else if (val < 0xFC) {
/* 111110nn nnnnnnnn (10 bits) (extended) */
val = (mach_read_from_2(*b) & 0x3FF) | 0xFFFFFC00;
*b += 2;
} else if (val < 0xFE) {
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
val = (mach_read_from_3(*b) & 0x1FFFF) | 0xFFFE0000;
ut_ad(val < 0xFFFFFC00);
*b += 3;
} else if (val == 0xFE) {
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
ut_ad(val == 0xFE);
val = mach_read_from_3(*b + 1) | 0xFF000000;
ut_ad(val < 0xFFFE0000);
*b += 4;
} else {
/* 11111111 followed by up to 64 bits */
/* 11111111 followed by up to 80 bits */
ut_ad(val == 0xFF);
++*b;
val = mach_read_next_compressed(b);
@@ -1037,13 +1037,23 @@ static MY_ATTRIBUTE((warn_unused_result)) dberr_t

return (DB_ERROR);

case LOG_HEADER_FORMAT_8_0_3:
/* v3 has compatibility with v4. Upgrades LOG_HEADER_FORMAT */
log.format = LOG_HEADER_FORMAT_8_0_19;
mach_write_to_4(buf + LOG_HEADER_FORMAT, log.format);
log_block_set_checksum(buf, log_block_calc_checksum_crc32(buf));
ut_a(fil_redo_io(IORequestLogWrite, page_id_t{log.files_space_id, 0},
univ_page_size, 0, OS_FILE_LOG_BLOCK_SIZE,
buf) == DB_SUCCESS);
break;

case LOG_HEADER_FORMAT_5_7_9:
case LOG_HEADER_FORMAT_8_0_1:

ib::info(ER_IB_MSG_704, ulong{log.format});

case LOG_HEADER_FORMAT_CURRENT:
/* The checkpoint page format is identical upto v3. */
/* The checkpoint page format is identical upto v4. */
break;

default:
@@ -3782,6 +3792,7 @@ dberr_t recv_recovery_from_checkpoint_start(log_t &log, lsn_t flush_lsn) {

case LOG_HEADER_FORMAT_5_7_9:
case LOG_HEADER_FORMAT_8_0_1:
case LOG_HEADER_FORMAT_8_0_3:

ib::info(ER_IB_MSG_732, ulong{log.format});

@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 2019, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License, version 2.0, as published by the
@@ -151,19 +151,69 @@ ib_uint32_t mach_parse_compressed(const byte **ptr, const byte *end_ptr) {
return (0);
}

#ifdef DEPLOY_FENCE
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif

if (val < 0xF8) {
ut_ad(val == 0xF0);

/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
if (end_ptr >= *ptr + 5) {
val = mach_read_from_4(*ptr + 1);
ut_ad(val > 0xFFFFFFF);
*ptr += 5;
return (static_cast<ib_uint32_t>(val));
}

*ptr = NULL;
return (0);
}

#ifdef DEPLOY_FENCE
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif

if (val < 0xFC) {
/* 111110nn nnnnnnnn (10 bits) (extended) */
if (end_ptr >= *ptr + 2) {
val = (mach_read_from_2(*ptr) & 0x3FF) | 0xFFFFFC00;
*ptr += 2;
return (static_cast<ib_uint32_t>(val));
}
*ptr = NULL;
return (0);
}

#ifdef DEPLOY_FENCE
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif

if (val < 0xFE) {
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
if (end_ptr >= *ptr + 3) {
val = (mach_read_from_3(*ptr) & 0x1FFFF) | 0xFFFE0000;
ut_ad(val < 0xFFFFFC00);
*ptr += 3;
return (static_cast<ib_uint32_t>(val));
}
*ptr = NULL;
return (0);
}

#ifdef DEPLOY_FENCE
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif

#undef DEPLOY_FENCE

ut_ad(val == 0xF0);
ut_ad(val == 0xFE);

/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
if (end_ptr >= *ptr + 5) {
val = mach_read_from_4(*ptr + 1);
ut_ad(val > 0xFFFFFFF);
*ptr += 5;
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
if (end_ptr >= *ptr + 4) {
val = mach_read_from_3(*ptr + 1) | 0xFF000000;
ut_ad(val < 0xFFFE0000);
*ptr += 4;
return (static_cast<ib_uint32_t>(val));
}

0 comments on commit 3ee5f8b

Please sign in to comment.