Skip to content

Commit 3ee5f8b

Browse files
author
Yasufumi Kinoshita
committed
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
1 parent c229c04 commit 3ee5f8b

6 files changed

Lines changed: 149 additions & 18 deletions

File tree

mysql-test/suite/innodb_zip/r/4k.result

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,6 @@ COMMIT;
306306
CREATE INDEX t1c ON t1 (c(767));
307307
UPDATE t1 SET c=@e;
308308
CREATE INDEX t1d ON t1 (d(767));
309-
UPDATE t1 SET d=@e;
310-
ERROR HY000: Undo log record is too big.
311309
CREATE INDEX t1e ON t1 (e(767));
312310
SHOW CREATE TABLE t1;
313311
Table Create Table

mysql-test/suite/innodb_zip/t/4k.test

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,10 @@ UPDATE t1 SET c=@e;
302302
# This is a problem. It means that the DDL is allowed to create a table
303303
# that CANNOT be updated. See bug#12953735.
304304
CREATE INDEX t1d ON t1 (d(767));
305-
--error ER_UNDO_RECORD_TOO_BIG
306-
UPDATE t1 SET d=@e;
305+
# NOTE: bug#12953735 seems to become a little more rare case by fixing bug#29536710
306+
# Reproducing doesn't seem to be so needed. And just comment out for now.
307+
#--error ER_UNDO_RECORD_TOO_BIG
308+
#UPDATE t1 SET d=@e;
307309

308310
--replace_regex /> [0-9]*/> max_row_size/
309311
CREATE INDEX t1e ON t1 (e(767));

storage/innobase/include/log0types.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,12 @@ enum log_header_format_t {
102102
it had to point the beginning of a group of log records). */
103103
LOG_HEADER_FORMAT_8_0_3 = 3,
104104

105+
/** Expand ulint compressed form. */
106+
LOG_HEADER_FORMAT_8_0_19 = 4,
107+
105108
/** The redo log format identifier
106109
corresponding to the current format version. */
107-
LOG_HEADER_FORMAT_CURRENT = LOG_HEADER_FORMAT_8_0_3
110+
LOG_HEADER_FORMAT_CURRENT = LOG_HEADER_FORMAT_8_0_19
108111
};
109112

110113
/** The state of a log group */

storage/innobase/include/mach0data.ic

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22

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

55
This program is free software; you can redistribute it and/or modify it under
66
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) {
179179
/* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */
180180
mach_write_to_4(b, n | 0xE0000000);
181181
return (4);
182+
} else if (n >= 0xFFFFFC00) {
183+
/* 111110nn nnnnnnnn (10 bits) (extended) */
184+
mach_write_to_2(b, (n & 0x3FF) | 0xF800);
185+
return (2);
186+
} else if (n >= 0xFFFE0000) {
187+
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
188+
mach_write_to_3(b, (n & 0x1FFFF) | 0xFC0000);
189+
return (3);
190+
} else if (n >= 0xFF000000) {
191+
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
192+
mach_write_to_4(b, (n & 0xFFFFFF) | 0xFE000000);
193+
return (4);
182194
} else {
183195
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
184196
mach_write_to_1(b, 0xF0);
@@ -204,6 +216,15 @@ ulint mach_get_compressed_size(ulint n) {
204216
} else if (n < 0x10000000) {
205217
/* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */
206218
return (4);
219+
} else if (n >= 0xFFFFFC00) {
220+
/* 111110nn nnnnnnnn (10 bits) (extended) */
221+
return (2);
222+
} else if (n >= 0xFFFE0000) {
223+
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
224+
return (3);
225+
} else if (n >= 0xFF000000) {
226+
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
227+
return (4);
207228
} else {
208229
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
209230
return (5);
@@ -235,11 +256,24 @@ ulint mach_read_compressed(const byte *b) {
235256
/* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */
236257
val = mach_read_from_4(b) & 0xFFFFFFF;
237258
ut_ad(val > 0x1FFFFF);
238-
} else {
259+
} else if (val < 0xF8) {
239260
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
240261
ut_ad(val == 0xF0);
241262
val = mach_read_from_4(b + 1);
263+
/* this can treat not-extended format also. */
242264
ut_ad(val > 0xFFFFFFF);
265+
} else if (val < 0xFC) {
266+
/* 111110nn nnnnnnnn (10 bits) (extended) */
267+
val = (mach_read_from_2(b) & 0x3FF) | 0xFFFFFC00;
268+
} else if (val < 0xFE) {
269+
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
270+
val = (mach_read_from_3(b) & 0x1FFFF) | 0xFFFE0000;
271+
ut_ad(val < 0xFFFFFC00);
272+
} else {
273+
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
274+
ut_ad(val == 0xFE);
275+
val = mach_read_from_3(b + 1) | 0xFF000000;
276+
ut_ad(val < 0xFFFE0000);
243277
}
244278

245279
return (val);
@@ -271,12 +305,28 @@ ib_uint32_t mach_read_next_compressed(const byte **b) {
271305
val = mach_read_from_4(*b) & 0xFFFFFFF;
272306
ut_ad(val > 0x1FFFFF);
273307
*b += 4;
274-
} else {
308+
} else if (val < 0xF8) {
275309
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
276310
ut_ad(val == 0xF0);
277311
val = mach_read_from_4(*b + 1);
312+
/* this can treat not-extended format also. */
278313
ut_ad(val > 0xFFFFFFF);
279314
*b += 5;
315+
} else if (val < 0xFC) {
316+
/* 111110nn nnnnnnnn (10 bits) (extended) */
317+
val = (mach_read_from_2(*b) & 0x3FF) | 0xFFFFFC00;
318+
*b += 2;
319+
} else if (val < 0xFE) {
320+
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
321+
val = (mach_read_from_3(*b) & 0x1FFFF) | 0xFFFE0000;
322+
ut_ad(val < 0xFFFFFC00);
323+
*b += 3;
324+
} else {
325+
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
326+
ut_ad(val == 0xFE);
327+
val = mach_read_from_3(*b + 1) | 0xFF000000;
328+
ut_ad(val < 0xFFFE0000);
329+
*b += 4;
280330
}
281331

282332
return (static_cast<ib_uint32_t>(val));
@@ -457,13 +507,30 @@ ib_uint64_t mach_read_next_much_compressed(const byte **b) {
457507
val = mach_read_from_4(*b) & 0xFFFFFFF;
458508
ut_ad(val > 0x1FFFFF);
459509
*b += 4;
460-
} else if (val == 0xF0) {
510+
} else if (val < 0xF8) {
461511
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
512+
ut_ad(val == 0xF0);
462513
val = mach_read_from_4(*b + 1);
514+
/* this can treat not-extended format also. */
463515
ut_ad(val > 0xFFFFFFF);
464516
*b += 5;
517+
} else if (val < 0xFC) {
518+
/* 111110nn nnnnnnnn (10 bits) (extended) */
519+
val = (mach_read_from_2(*b) & 0x3FF) | 0xFFFFFC00;
520+
*b += 2;
521+
} else if (val < 0xFE) {
522+
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
523+
val = (mach_read_from_3(*b) & 0x1FFFF) | 0xFFFE0000;
524+
ut_ad(val < 0xFFFFFC00);
525+
*b += 3;
526+
} else if (val == 0xFE) {
527+
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
528+
ut_ad(val == 0xFE);
529+
val = mach_read_from_3(*b + 1) | 0xFF000000;
530+
ut_ad(val < 0xFFFE0000);
531+
*b += 4;
465532
} else {
466-
/* 11111111 followed by up to 64 bits */
533+
/* 11111111 followed by up to 80 bits */
467534
ut_ad(val == 0xFF);
468535
++*b;
469536
val = mach_read_next_compressed(b);

storage/innobase/log/log0recv.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,13 +1037,23 @@ static MY_ATTRIBUTE((warn_unused_result)) dberr_t
10371037

10381038
return (DB_ERROR);
10391039

1040+
case LOG_HEADER_FORMAT_8_0_3:
1041+
/* v3 has compatibility with v4. Upgrades LOG_HEADER_FORMAT */
1042+
log.format = LOG_HEADER_FORMAT_8_0_19;
1043+
mach_write_to_4(buf + LOG_HEADER_FORMAT, log.format);
1044+
log_block_set_checksum(buf, log_block_calc_checksum_crc32(buf));
1045+
ut_a(fil_redo_io(IORequestLogWrite, page_id_t{log.files_space_id, 0},
1046+
univ_page_size, 0, OS_FILE_LOG_BLOCK_SIZE,
1047+
buf) == DB_SUCCESS);
1048+
break;
1049+
10401050
case LOG_HEADER_FORMAT_5_7_9:
10411051
case LOG_HEADER_FORMAT_8_0_1:
10421052

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

10451055
case LOG_HEADER_FORMAT_CURRENT:
1046-
/* The checkpoint page format is identical upto v3. */
1056+
/* The checkpoint page format is identical upto v4. */
10471057
break;
10481058

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

37833793
case LOG_HEADER_FORMAT_5_7_9:
37843794
case LOG_HEADER_FORMAT_8_0_1:
3795+
case LOG_HEADER_FORMAT_8_0_3:
37853796

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

storage/innobase/mach/mach0data.cc

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 1995, 2019, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
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) {
151151
return (0);
152152
}
153153

154+
#ifdef DEPLOY_FENCE
155+
__atomic_thread_fence(__ATOMIC_ACQUIRE);
156+
#endif
157+
158+
if (val < 0xF8) {
159+
ut_ad(val == 0xF0);
160+
161+
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
162+
if (end_ptr >= *ptr + 5) {
163+
val = mach_read_from_4(*ptr + 1);
164+
ut_ad(val > 0xFFFFFFF);
165+
*ptr += 5;
166+
return (static_cast<ib_uint32_t>(val));
167+
}
168+
169+
*ptr = NULL;
170+
return (0);
171+
}
172+
173+
#ifdef DEPLOY_FENCE
174+
__atomic_thread_fence(__ATOMIC_ACQUIRE);
175+
#endif
176+
177+
if (val < 0xFC) {
178+
/* 111110nn nnnnnnnn (10 bits) (extended) */
179+
if (end_ptr >= *ptr + 2) {
180+
val = (mach_read_from_2(*ptr) & 0x3FF) | 0xFFFFFC00;
181+
*ptr += 2;
182+
return (static_cast<ib_uint32_t>(val));
183+
}
184+
*ptr = NULL;
185+
return (0);
186+
}
187+
188+
#ifdef DEPLOY_FENCE
189+
__atomic_thread_fence(__ATOMIC_ACQUIRE);
190+
#endif
191+
192+
if (val < 0xFE) {
193+
/* 1111110n nnnnnnnn nnnnnnnn (17 bits) (extended) */
194+
if (end_ptr >= *ptr + 3) {
195+
val = (mach_read_from_3(*ptr) & 0x1FFFF) | 0xFFFE0000;
196+
ut_ad(val < 0xFFFFFC00);
197+
*ptr += 3;
198+
return (static_cast<ib_uint32_t>(val));
199+
}
200+
*ptr = NULL;
201+
return (0);
202+
}
203+
154204
#ifdef DEPLOY_FENCE
155205
__atomic_thread_fence(__ATOMIC_ACQUIRE);
156206
#endif
157207

158208
#undef DEPLOY_FENCE
159209

160-
ut_ad(val == 0xF0);
210+
ut_ad(val == 0xFE);
161211

162-
/* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */
163-
if (end_ptr >= *ptr + 5) {
164-
val = mach_read_from_4(*ptr + 1);
165-
ut_ad(val > 0xFFFFFFF);
166-
*ptr += 5;
212+
/* 11111110 nnnnnnnn nnnnnnnn nnnnnnnn (24 bits) (extended) */
213+
if (end_ptr >= *ptr + 4) {
214+
val = mach_read_from_3(*ptr + 1) | 0xFF000000;
215+
ut_ad(val < 0xFFFE0000);
216+
*ptr += 4;
167217
return (static_cast<ib_uint32_t>(val));
168218
}
169219

0 commit comments

Comments
 (0)