33 # include "page0zip.ic"
44 #ifndef UNIV_HOTBACKUP
54 # include "buf0checksum.h"
55 # define lock_move_reorganize_page(block, temp_block) ((void) 0)
56 # define buf_LRU_stat_inc_unzip() ((void) 0)
59 #ifndef UNIV_HOTBACKUP
66 #ifdef HAVE_PSI_INTERFACE
67 UNIV_INTERN mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
72 UNIV_INTERN uint page_zip_level = DEFAULT_COMPRESSION_LEVEL;
76 UNIV_INTERN my_bool page_zip_log_pages =
true;
85 static const byte infimum_extra[] = {
91 static const byte infimum_data[] = {
92 0x69, 0x6e, 0x66, 0x69,
93 0x6d, 0x75, 0x6d, 0x00
96 static const byte supremum_extra_data[] = {
100 0x73, 0x75, 0x70, 0x72,
101 0x65, 0x6d, 0x75, 0x6d
108 #define ASSERT_ZERO(b, s) \
109 ut_ad(!memcmp(b, field_ref_zero, ut_min(s, sizeof field_ref_zero)))
112 #define ASSERT_ZERO_BLOB(b) \
113 ut_ad(!memcmp(b, field_ref_zero, sizeof field_ref_zero))
117 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
119 __attribute__((format (printf, 1, 2)))
134 fputs(
" InnoDB: ", stderr);
136 res = vfprintf(stderr, fmt, ap);
143 # define page_zip_fail(fmt_args) page_zip_fail_func fmt_args
147 # define page_zip_fail(fmt_args)
150 #ifndef UNIV_HOTBACKUP
165 + PAGE_ZIP_DIR_SLOT_SIZE
166 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN
169 - REC_N_NEW_EXTRA_BYTES)
171 - compressBound(2 * (n_fields + 1));
172 return(size > 0 ? (ulint) size : 0);
225 #define page_zip_dir_start_low(page_zip, n_dense) \
226 ((page_zip)->data + page_zip_dir_start_offs(page_zip, n_dense))
232 #define page_zip_dir_start(page_zip) \
233 page_zip_dir_start_low(page_zip, page_zip_dir_elems(page_zip))
245 ulint
size = PAGE_ZIP_DIR_SLOT_SIZE
264 for (; slot < end; slot += PAGE_ZIP_DIR_SLOT_SIZE) {
286 ut_ad(page_zip_simple_validate(page_zip));
305 ut_ad(page_zip_simple_validate(page_zip));
324 ut_ad(page_zip_simple_validate(page_zip));
327 - PAGE_ZIP_DIR_SLOT_SIZE * (slot + 1)));
330 #ifndef UNIV_HOTBACKUP
335 page_zip_compress_write_log(
356 - PAGE_HEAP_NO_USER_LOW;
359 trailer_size *= PAGE_ZIP_DIR_SLOT_SIZE + REC_NODE_PTR_SIZE;
361 trailer_size *= PAGE_ZIP_DIR_SLOT_SIZE
362 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
364 trailer_size *= PAGE_ZIP_DIR_SLOT_SIZE;
369 #if FIL_PAGE_DATA > PAGE_DATA
370 # error "FIL_PAGE_DATA > PAGE_DATA"
392 - trailer_size, trailer_size);
401 page_zip_get_n_prev_extern(
423 ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
424 left = heap_no - PAGE_HEAP_NO_USER_LOW;
425 if (UNIV_UNLIKELY(!left)) {
429 for (i = 0; i < n_recs; i++) {
431 & PAGE_ZIP_DIR_SLOT_MASK);
450 page_zip_fixed_field_encode(
457 if (UNIV_LIKELY(val < 126)) {
466 *buf++ = (byte) (0x80 | val >> 8);
478 page_zip_fields_encode(
487 const byte* buf_start =
buf;
490 ulint trx_id_col = 0;
494 ut_ad(trx_id_pos == ULINT_UNDEFINED || trx_id_pos < n);
496 for (i = col = 0; i <
n; i++) {
497 dict_field_t* field = dict_index_get_nth_field(index, i);
511 if (UNIV_UNLIKELY(column->
len > 255)
512 || UNIV_UNLIKELY(column->
mtype == DATA_BLOB)) {
519 buf = page_zip_fixed_field_encode(
520 buf, fixed_sum << 1 | 1);
530 if (fixed_sum && UNIV_UNLIKELY
537 buf = page_zip_fixed_field_encode(
538 buf, fixed_sum << 1 | 1);
543 if (i && UNIV_UNLIKELY(i == trx_id_pos)) {
548 buf = page_zip_fixed_field_encode(
549 buf, fixed_sum << 1 | 1);
565 buf = page_zip_fixed_field_encode(
566 buf, fixed_sum << 1 | 1);
571 buf = page_zip_fixed_field_encode(
579 buf = page_zip_fixed_field_encode(buf, fixed_sum << 1 | 1);
582 if (trx_id_pos != ULINT_UNDEFINED) {
593 *buf++ = (byte) (0x80 | i >> 8);
597 ut_ad((ulint) (buf - buf_start) <= (n + 2) * 2);
598 return((ulint) (buf - buf_start));
625 status = REC_STATUS_ORDINARY;
627 status = REC_STATUS_NODE_PTR;
630 min_mark = REC_INFO_MIN_REC_FLAG;
639 rec = page + PAGE_NEW_INFIMUM;
646 if (UNIV_UNLIKELY(offs == PAGE_NEW_SUPREMUM)) {
651 ut_a(heap_no >= PAGE_HEAP_NO_USER_LOW);
652 ut_a(heap_no < n_heap);
653 ut_a(offs < UNIV_PAGE_SIZE - PAGE_DIR);
654 ut_a(offs >= PAGE_ZIP_START);
655 #if PAGE_ZIP_DIR_SLOT_MASK & (PAGE_ZIP_DIR_SLOT_MASK + 1)
656 # error "PAGE_ZIP_DIR_SLOT_MASK is not 1 less than a power of 2"
658 #if PAGE_ZIP_DIR_SLOT_MASK < UNIV_PAGE_SIZE_MAX - 1
659 # error "PAGE_ZIP_DIR_SLOT_MASK < UNIV_PAGE_SIZE_MAX - 1"
662 offs |= PAGE_ZIP_DIR_SLOT_OWNED;
666 if (info_bits & REC_INFO_DELETED_FLAG) {
667 info_bits &= ~REC_INFO_DELETED_FLAG;
668 offs |= PAGE_ZIP_DIR_SLOT_DEL;
670 ut_a(info_bits == min_mark);
677 if (UNIV_LIKELY_NULL(recs)) {
679 ut_a(!recs[heap_no - PAGE_HEAP_NO_USER_LOW]);
681 recs[heap_no - PAGE_HEAP_NO_USER_LOW] =
rec;
691 ut_ad(!(offs & ~PAGE_ZIP_DIR_SLOT_MASK));
695 ut_a(heap_no >= PAGE_HEAP_NO_USER_LOW);
696 ut_a(heap_no < n_heap);
698 ut_a(!rec[-REC_N_NEW_EXTRA_BYTES]);
703 if (UNIV_LIKELY_NULL(recs)) {
705 ut_a(!recs[heap_no - PAGE_HEAP_NO_USER_LOW]);
707 recs[heap_no - PAGE_HEAP_NO_USER_LOW] =
rec;
714 ut_a(i + PAGE_HEAP_NO_USER_LOW == n_heap);
729 return(
mem_heap_zalloc(static_cast<mem_heap_t*>(opaque), items * size));
738 void* opaque __attribute__((unused)),
739 void* address __attribute__((unused)))
756 strm->zalloc = page_zip_zalloc;
757 strm->zfree = page_zip_free;
761 #if 0 || defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
763 # define PAGE_ZIP_COMPRESS_DBG
766 #ifdef PAGE_ZIP_COMPRESS_DBG
769 UNIV_INTERN ibool page_zip_compress_dbg;
774 UNIV_INTERN
unsigned page_zip_compress_log;
781 page_zip_compress_deflate(
788 if (UNIV_UNLIKELY(page_zip_compress_dbg)) {
791 if (UNIV_LIKELY_NULL(logfile)) {
792 fwrite(strm->next_in, 1, strm->avail_in, logfile);
794 status = deflate(strm, flush);
795 if (UNIV_UNLIKELY(page_zip_compress_dbg)) {
796 fprintf(stderr,
" -> %d\n", status);
808 # define deflate(strm, flush) page_zip_compress_deflate(logfile, strm, flush)
810 # define FILE_LOGFILE FILE* logfile,
812 # define LOGFILE logfile,
815 # define FILE_LOGFILE
825 page_zip_compress_node_ptrs(
840 const rec_t* rec = *recs++;
842 offsets = rec_get_offsets(rec, index, offsets,
843 ULINT_UNDEFINED, &heap);
852 c_stream->avail_in = rec - REC_N_NEW_EXTRA_BYTES
855 if (c_stream->avail_in) {
856 err = deflate(c_stream, Z_NO_FLUSH);
857 if (UNIV_UNLIKELY(err != Z_OK)) {
861 ut_ad(!c_stream->avail_in);
864 c_stream->next_in = (byte*) rec;
868 if (c_stream->avail_in) {
869 err = deflate(c_stream, Z_NO_FLUSH);
870 if (UNIV_UNLIKELY(err != Z_OK)) {
875 ut_ad(!c_stream->avail_in);
877 memcpy(storage - REC_NODE_PTR_SIZE
879 c_stream->next_in, REC_NODE_PTR_SIZE);
880 c_stream->next_in += REC_NODE_PTR_SIZE;
891 page_zip_compress_sec(
904 const rec_t* rec = *recs++;
907 c_stream->avail_in = rec - REC_N_NEW_EXTRA_BYTES
910 if (UNIV_LIKELY(c_stream->avail_in)) {
911 UNIV_MEM_ASSERT_RW(c_stream->next_in,
913 err = deflate(c_stream, Z_NO_FLUSH);
914 if (UNIV_UNLIKELY(err != Z_OK)) {
919 ut_ad(!c_stream->avail_in);
920 ut_ad(c_stream->next_in == rec - REC_N_NEW_EXTRA_BYTES);
924 c_stream->next_in = (byte*) rec;
936 page_zip_compress_clust_ext(
962 if (UNIV_UNLIKELY(i == trx_id_col)) {
966 src = rec_get_nth_field(rec, offsets, i, &len);
967 ut_ad(src + DATA_TRX_ID_LEN
968 == rec_get_nth_field(rec, offsets,
970 ut_ad(len == DATA_ROLL_PTR_LEN);
974 = src - c_stream->next_in;
976 if (c_stream->avail_in) {
977 err = deflate(c_stream, Z_NO_FLUSH);
978 if (UNIV_UNLIKELY(err != Z_OK)) {
984 ut_ad(!c_stream->avail_in);
985 ut_ad(c_stream->next_in == src);
988 - (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
991 DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
994 += DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
999 src = rec_get_nth_field(rec, offsets, i, &len);
1003 c_stream->avail_in = src
1004 - c_stream->next_in;
1005 if (UNIV_LIKELY(c_stream->avail_in)) {
1006 err = deflate(c_stream, Z_NO_FLUSH);
1007 if (UNIV_UNLIKELY(err != Z_OK)) {
1013 ut_ad(!c_stream->avail_in);
1014 ut_ad(c_stream->next_in == src);
1022 (c_stream->avail_out
1023 <= BTR_EXTERN_FIELD_REF_SIZE)) {
1025 return(Z_BUF_ERROR);
1028 ut_ad(*externs == c_stream->next_out
1029 + c_stream->avail_out
1036 if (UNIV_LIKELY_NULL
1049 memcpy(*externs, c_stream->next_in
1050 - BTR_EXTERN_FIELD_REF_SIZE,
1051 BTR_EXTERN_FIELD_REF_SIZE);
1063 page_zip_compress_clust(
1080 ulint* offsets = NULL;
1082 byte* externs = storage - n_dense
1083 * (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
1085 ut_ad(*n_blobs == 0);
1088 const rec_t* rec = *recs++;
1090 offsets = rec_get_offsets(rec, index, offsets,
1091 ULINT_UNDEFINED, &heap);
1099 c_stream->avail_in = rec - REC_N_NEW_EXTRA_BYTES
1100 - c_stream->next_in;
1102 if (c_stream->avail_in) {
1103 err = deflate(c_stream, Z_NO_FLUSH);
1104 if (UNIV_UNLIKELY(err != Z_OK)) {
1109 ut_ad(!c_stream->avail_in);
1110 ut_ad(c_stream->next_in == rec - REC_N_NEW_EXTRA_BYTES);
1114 c_stream->next_in = (byte*) rec;
1122 err = page_zip_compress_clust_ext(
1124 c_stream, rec, offsets, trx_id_col,
1125 deleted, storage, &externs, n_blobs);
1127 if (UNIV_UNLIKELY(err != Z_OK)) {
1136 src = rec_get_nth_field(rec, offsets,
1138 ut_ad(src + DATA_TRX_ID_LEN
1139 == rec_get_nth_field(rec, offsets,
1140 trx_id_col + 1, &len));
1141 ut_ad(len == DATA_ROLL_PTR_LEN);
1147 c_stream->avail_in = src - c_stream->next_in;
1149 if (c_stream->avail_in) {
1150 err = deflate(c_stream, Z_NO_FLUSH);
1151 if (UNIV_UNLIKELY(err != Z_OK)) {
1157 ut_ad(!c_stream->avail_in);
1158 ut_ad(c_stream->next_in == src);
1161 - (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
1164 DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
1167 += DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
1175 - c_stream->next_in;
1177 if (c_stream->avail_in) {
1178 err = deflate(c_stream, Z_NO_FLUSH);
1179 if (UNIV_UNLIKELY(err != Z_OK)) {
1184 ut_ad(!c_stream->avail_in);
1185 }
while (--n_dense);
1219 #ifndef UNIV_HOTBACKUP
1222 #ifdef PAGE_ZIP_COMPRESS_DBG
1223 FILE* logfile = NULL;
1233 ut_ad(page_zip_simple_validate(page_zip));
1237 UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
1240 ut_a(!memcmp(page + (PAGE_NEW_INFIMUM - REC_N_NEW_EXTRA_BYTES),
1241 infimum_extra,
sizeof infimum_extra));
1242 ut_a(!memcmp(page + PAGE_NEW_INFIMUM,
1243 infimum_data,
sizeof infimum_data));
1244 ut_a(page[PAGE_NEW_SUPREMUM - REC_N_NEW_EXTRA_BYTES]
1246 <= PAGE_DIR_SLOT_MAX_N_OWNED);
1247 ut_a(!memcmp(page + (PAGE_NEW_SUPREMUM - REC_N_NEW_EXTRA_BYTES + 1),
1248 supremum_extra_data,
sizeof supremum_extra_data));
1252 == PAGE_NEW_SUPREMUM);
1263 #ifdef PAGE_ZIP_COMPRESS_DBG
1264 if (UNIV_UNLIKELY(page_zip_compress_dbg)) {
1265 fprintf(stderr,
"compress %p %p %lu %lu %lu\n",
1266 (
void*) page_zip, (
void*) page,
1270 if (UNIV_UNLIKELY(page_zip_compress_log)) {
1272 char logfilename[9];
1274 "%08x", page_zip_compress_log++);
1275 logfile = fopen(logfilename,
"wb");
1279 fwrite(page, 1, UNIV_PAGE_SIZE, logfile);
1289 #ifndef UNIV_HOTBACKUP
1291 if (cmp_per_index_enabled) {
1298 if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
1307 + n_fields * (2 +
sizeof(ulint))
1308 + REC_OFFS_HEADER_SIZE
1309 + n_dense * ((
sizeof *recs)
1310 - PAGE_ZIP_DIR_SLOT_SIZE)
1311 + UNIV_PAGE_SIZE * 4
1312 + (512 << MAX_MEM_LEVEL));
1314 recs =
static_cast<const rec_t**
>(
1317 fields =
static_cast<byte*
>(
mem_heap_alloc(heap, (n_fields + 1) * 2));
1319 buf =
static_cast<byte*
>(
1327 err = deflateInit2(&c_stream, level,
1328 Z_DEFLATED, UNIV_PAGE_SIZE_SHIFT,
1329 MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
1332 c_stream.next_out =
buf;
1335 c_stream.avail_out = buf_end - buf - 1;
1340 index, DATA_TRX_ID);
1341 ut_ad(trx_id_col > 0);
1342 ut_ad(trx_id_col != ULINT_UNDEFINED);
1344 slot_size = PAGE_ZIP_DIR_SLOT_SIZE
1345 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
1350 == ULINT_UNDEFINED);
1352 slot_size = PAGE_ZIP_DIR_SLOT_SIZE;
1355 slot_size = PAGE_ZIP_DIR_SLOT_SIZE + REC_NODE_PTR_SIZE;
1356 trx_id_col = ULINT_UNDEFINED;
1359 if (UNIV_UNLIKELY(c_stream.avail_out <= n_dense * slot_size
1364 c_stream.avail_out -= n_dense * slot_size;
1365 c_stream.avail_in = page_zip_fields_encode(n_fields, index,
1366 trx_id_col, fields);
1367 c_stream.next_in = fields;
1368 if (UNIV_LIKELY(!trx_id_col)) {
1369 trx_id_col = ULINT_UNDEFINED;
1372 UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in);
1373 err = deflate(&c_stream, Z_FULL_FLUSH);
1378 ut_ad(!c_stream.avail_in);
1380 page_zip_dir_encode(page, buf_end, recs);
1382 c_stream.next_in = (byte*) page + PAGE_ZIP_START;
1384 storage = buf_end - n_dense * PAGE_ZIP_DIR_SLOT_SIZE;
1387 if (UNIV_UNLIKELY(!n_dense)) {
1390 err = page_zip_compress_node_ptrs(
LOGFILE
1391 &c_stream, recs, n_dense,
1392 index, storage, heap);
1393 if (UNIV_UNLIKELY(err != Z_OK)) {
1396 }
else if (UNIV_LIKELY(trx_id_col == ULINT_UNDEFINED)) {
1398 err = page_zip_compress_sec(
LOGFILE
1399 &c_stream, recs, n_dense);
1400 if (UNIV_UNLIKELY(err != Z_OK)) {
1405 err = page_zip_compress_clust(
LOGFILE
1406 &c_stream, recs, n_dense,
1407 index, &n_blobs, trx_id_col,
1408 buf_end - PAGE_ZIP_DIR_SLOT_SIZE
1411 if (UNIV_UNLIKELY(err != Z_OK)) {
1417 ut_ad(!c_stream.avail_in);
1423 - (c_stream.next_in -
page);
1424 ut_a(c_stream.avail_in <= UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR);
1426 UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in);
1427 err = deflate(&c_stream, Z_FINISH);
1429 if (UNIV_UNLIKELY(err != Z_STREAM_END)) {
1431 deflateEnd(&c_stream);
1434 #ifdef PAGE_ZIP_COMPRESS_DBG
1439 #ifndef UNIV_HOTBACKUP
1447 if (cmp_per_index_enabled) {
1457 err = deflateEnd(&c_stream);
1460 ut_ad(buf + c_stream.total_out == c_stream.next_out);
1461 ut_ad((ulint) (storage - c_stream.next_out) >= c_stream.avail_out);
1465 UNIV_MEM_VALID(buf, c_stream.total_out);
1470 memset(c_stream.next_out, 0, c_stream.avail_out + 1);
1475 page_zip->
m_end = PAGE_DATA + c_stream.total_out;
1486 memcpy(page_zip->
data + PAGE_DATA, buf,
1489 #ifdef UNIV_ZIP_DEBUG
1490 ut_a(page_zip_validate(page_zip, page, index));
1494 #ifndef UNIV_HOTBACKUP
1495 page_zip_compress_write_log(page_zip, page, index, mtr);
1501 #ifdef PAGE_ZIP_COMPRESS_DBG
1506 fseek(logfile, UNIV_PAGE_SIZE, SEEK_SET);
1507 fwrite(sz, 1,
sizeof sz, logfile);
1511 #ifndef UNIV_HOTBACKUP
1515 if (cmp_per_index_enabled) {
1540 return(rec1 > rec2);
1562 page_zip_fields_free(
1581 page_zip_fields_decode(
1597 for (b = buf, n = 0; b < end; n++) {
1605 if (UNIV_UNLIKELY(n > REC_MAX_N_FIELDS)) {
1612 if (UNIV_UNLIKELY(b > end)) {
1615 (
const void*) b, (
const void*) end));
1622 DICT_HDR_SPACE, 0, n);
1629 for (b = buf, i = 0; i <
n; i++) {
1635 if (UNIV_UNLIKELY(val & 0x80)) {
1637 val = (val & 0x7f) << 8 | *b++;
1639 mtype = DATA_FIXBINARY;
1640 }
else if (UNIV_UNLIKELY(val >= 126)) {
1643 mtype = DATA_BINARY;
1644 }
else if (val <= 1) {
1647 mtype = DATA_BINARY;
1651 mtype = DATA_FIXBINARY;
1655 val & 1 ? DATA_NOT_NULL : 0, len);
1657 dict_table_get_nth_col(table, i), 0);
1661 if (UNIV_UNLIKELY(val & 0x80)) {
1662 val = (val & 0x7f) << 8 | *b++;
1668 val = ULINT_UNDEFINED;
1669 }
else if (UNIV_UNLIKELY(val >= n)) {
1670 page_zip_fields_free(index);
1679 if (UNIV_UNLIKELY(index->
n_nullable > val)) {
1680 page_zip_fields_free(index);
1697 page_zip_dir_decode(
1716 if (UNIV_UNLIKELY(n_recs > n_dense)) {
1718 (ulong) n_recs, (ulong) n_dense));
1725 slot = page + (UNIV_PAGE_SIZE - PAGE_DIR - PAGE_DIR_SLOT_SIZE);
1726 UNIV_PREFETCH_RW(slot);
1729 memset(slot + PAGE_DIR_SLOT_SIZE, 0, PAGE_DIR);
1732 slot -= PAGE_DIR_SLOT_SIZE;
1733 UNIV_PREFETCH_RW(slot);
1736 for (i = 0; i < n_recs; i++) {
1739 if (offs & PAGE_ZIP_DIR_SLOT_OWNED) {
1741 slot -= PAGE_DIR_SLOT_SIZE;
1742 UNIV_PREFETCH_RW(slot);
1745 if (UNIV_UNLIKELY((offs & PAGE_ZIP_DIR_SLOT_MASK)
1746 < PAGE_ZIP_START + REC_N_NEW_EXTRA_BYTES)) {
1748 (
unsigned) i, (
unsigned) n_recs,
1753 recs[
i] = page + (offs & PAGE_ZIP_DIR_SLOT_MASK);
1758 const page_dir_slot_t* last_slot = page_dir_get_nth_slot(
1761 if (UNIV_UNLIKELY(slot != last_slot)) {
1764 (
const void*) last_slot));
1770 for (; i < n_dense; i++) {
1773 if (UNIV_UNLIKELY(offs & ~PAGE_ZIP_DIR_SLOT_MASK)) {
1775 (
unsigned) i, (
unsigned) n_dense,
1780 recs[
i] = page + offs;
1783 if (UNIV_LIKELY(n_dense > 1)) {
1784 page_zip_dir_sort(recs, recs_aux, 0, n_dense);
1794 page_zip_set_extra_bytes(
1807 rec = page + PAGE_NEW_INFIMUM;
1809 for (i = 0; i <
n; i++) {
1812 if (offs & PAGE_ZIP_DIR_SLOT_DEL) {
1813 info_bits |= REC_INFO_DELETED_FLAG;
1815 if (UNIV_UNLIKELY(offs & PAGE_ZIP_DIR_SLOT_OWNED)) {
1816 info_bits |= n_owned;
1821 offs &= PAGE_ZIP_DIR_SLOT_MASK;
1822 if (UNIV_UNLIKELY(offs < PAGE_ZIP_START
1823 + REC_N_NEW_EXTRA_BYTES)) {
1826 (
unsigned) i, (
unsigned) n,
1833 rec[-REC_N_NEW_EXTRA_BYTES] = (byte) info_bits;
1841 page[PAGE_NEW_SUPREMUM - REC_N_NEW_EXTRA_BYTES] = (byte) n_owned;
1847 if (UNIV_LIKELY(i == n)) {
1852 (
unsigned) i, (
unsigned) n));
1860 if (UNIV_UNLIKELY(!offs)
1861 || UNIV_UNLIKELY(offs & ~PAGE_ZIP_DIR_SLOT_MASK)) {
1869 rec[-REC_N_NEW_EXTRA_BYTES] = 0;
1880 rec[-REC_N_NEW_EXTRA_BYTES] = 0;
1892 page_zip_apply_log_ext(
1895 const ulint* offsets,
1902 byte* next_out =
rec;
1911 if (UNIV_UNLIKELY(i == trx_id_col)) {
1913 dst = rec_get_nth_field(rec, offsets,
1915 if (UNIV_UNLIKELY(dst - next_out >= end - data)
1917 (len < (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN))
1921 " %p - %p >= %p - %p\n",
1924 (
const void*) next_out,
1926 (
const void*) data));
1930 memcpy(next_out, data, dst - next_out);
1931 data += dst - next_out;
1932 next_out = dst + (DATA_TRX_ID_LEN
1933 + DATA_ROLL_PTR_LEN);
1935 dst = rec_get_nth_field(rec, offsets,
1938 >= BTR_EXTERN_FIELD_REF_SIZE);
1940 len += dst - next_out
1943 if (UNIV_UNLIKELY(data + len >= end)) {
1945 "ext %p+%lu >= %p\n",
1948 (
const void*) end));
1952 memcpy(next_out, data, len);
1960 len = rec_get_end(rec, offsets) - next_out;
1961 if (UNIV_UNLIKELY(data + len >= end)) {
1963 "last %p+%lu >= %p\n",
1966 (
const void*) end));
1969 memcpy(next_out, data, len);
1998 const byte*
const end = data +
size;
2007 if (UNIV_UNLIKELY(!val)) {
2011 val = (val & 0x7f) << 8 | *data++;
2012 if (UNIV_UNLIKELY(!val)) {
2014 " invalid val %x%x\n",
2015 data[-2], data[-1]));
2019 if (UNIV_UNLIKELY(data >= end)) {
2022 (
const void*) end));
2025 if (UNIV_UNLIKELY((val >> 1) > n_dense)) {
2027 (ulong) val, (ulong) n_dense));
2032 rec = recs[(val >> 1) - 1];
2034 hs = ((val >> 1) + 1) << REC_HEAP_NO_SHIFT;
2035 hs |= heap_status & ((1 << REC_HEAP_NO_SHIFT) - 1);
2041 if (UNIV_UNLIKELY(hs > heap_status)) {
2043 (ulong) hs, (ulong) heap_status));
2045 }
else if (hs == heap_status) {
2047 if (UNIV_UNLIKELY(val & 1)) {
2050 " attempting to create"
2051 " deleted rec %lu\n",
2055 heap_status += 1 << REC_HEAP_NO_SHIFT;
2064 offs = rec_get_offsets(rec, index, offsets,
2065 ULINT_UNDEFINED, &heap);
2068 if (UNIV_LIKELY_NULL(heap)) {
2074 #if REC_STATUS_NODE_PTR != TRUE
2075 # error "REC_STATUS_NODE_PTR != TRUE"
2078 hs & REC_STATUS_NODE_PTR,
2080 rec_offs_make_valid(rec, index, offsets);
2084 byte* start = rec_get_start(rec, offsets);
2085 byte* b = rec - REC_N_NEW_EXTRA_BYTES;
2086 while (b != start) {
2095 if (UNIV_UNLIKELY(hs & REC_STATUS_NODE_PTR)) {
2097 "%lu&REC_STATUS_NODE_PTR\n",
2102 data = page_zip_apply_log_ext(
2103 rec, offsets, trx_id_col, data, end);
2105 if (UNIV_UNLIKELY(!data)) {
2108 }
else if (UNIV_UNLIKELY(hs & REC_STATUS_NODE_PTR)) {
2110 - REC_NODE_PTR_SIZE;
2112 if (UNIV_UNLIKELY(data + len >= end)) {
2114 "node_ptr %p+%lu >= %p\n",
2117 (
const void*) end));
2120 memcpy(rec, data, len);
2122 }
else if (UNIV_LIKELY(trx_id_col == ULINT_UNDEFINED)) {
2127 if (UNIV_UNLIKELY(data + len >= end)) {
2129 "sec %p+%lu >= %p\n",
2132 (
const void*) end));
2136 memcpy(rec, data, len);
2144 if (UNIV_UNLIKELY(data + l >= end)
2145 || UNIV_UNLIKELY(len < (DATA_TRX_ID_LEN
2146 + DATA_ROLL_PTR_LEN))) {
2148 "trx_id %p+%lu >= %p\n",
2151 (
const void*) end));
2156 memcpy(rec, data, l);
2160 b = rec + l + (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
2161 len = rec_get_end(rec, offsets) - b;
2162 if (UNIV_UNLIKELY(data + len >= end)) {
2164 "clust %p+%lu >= %p\n",
2167 (
const void*) end));
2170 memcpy(b, data, len);
2182 page_zip_decompress_heap_no(
2188 if (d_stream->next_out != rec - REC_N_NEW_EXTRA_BYTES) {
2194 d_stream->next_out =
rec;
2198 heap_status += 1 << REC_HEAP_NO_SHIFT;
2207 page_zip_decompress_node_ptrs(
2218 ulint heap_status = REC_STATUS_NODE_PTR
2219 | PAGE_HEAP_NO_USER_LOW << REC_HEAP_NO_SHIFT;
2221 const byte* storage;
2224 d_stream->avail_in -= n_dense
2225 * (PAGE_ZIP_DIR_SLOT_SIZE + REC_NODE_PTR_SIZE);
2228 for (slot = 0; slot < n_dense; slot++) {
2229 rec_t* rec = recs[slot];
2231 d_stream->avail_out = rec - REC_N_NEW_EXTRA_BYTES
2232 - d_stream->next_out;
2234 ut_ad(d_stream->avail_out < UNIV_PAGE_SIZE
2235 - PAGE_ZIP_START - PAGE_DIR);
2236 switch (inflate(d_stream, Z_SYNC_FLUSH)) {
2238 page_zip_decompress_heap_no(
2239 d_stream, rec, heap_status);
2243 if (!d_stream->avail_out) {
2249 " 1 inflate(Z_SYNC_FLUSH)=%s\n",
2254 if (!page_zip_decompress_heap_no(
2255 d_stream, rec, heap_status)) {
2260 offsets = rec_get_offsets(rec, index, offsets,
2261 ULINT_UNDEFINED, &heap);
2269 - REC_NODE_PTR_SIZE;
2271 switch (inflate(d_stream, Z_SYNC_FLUSH)) {
2276 if (!d_stream->avail_out) {
2282 " 2 inflate(Z_SYNC_FLUSH)=%s\n",
2290 memset(d_stream->next_out, 0, REC_NODE_PTR_SIZE);
2291 d_stream->next_out += REC_NODE_PTR_SIZE;
2293 ut_ad(d_stream->next_out == rec_get_end(rec, offsets));
2301 if (UNIV_UNLIKELY(d_stream->avail_out > UNIV_PAGE_SIZE
2302 - PAGE_ZIP_START - PAGE_DIR)) {
2305 " avail_out = %u\n",
2306 d_stream->avail_out));
2310 if (UNIV_UNLIKELY(inflate(d_stream, Z_FINISH) != Z_STREAM_END)) {
2312 " inflate(Z_FINISH)=%s\n",
2315 inflateEnd(d_stream);
2323 if (UNIV_UNLIKELY(inflateEnd(d_stream) != Z_OK)) {
2331 memset(d_stream->next_out, 0,
2332 page_dir_get_nth_slot(page,
2334 - d_stream->next_out);
2338 page_zip->m_start = PAGE_DATA + d_stream->total_in;
2343 const byte* mod_log_ptr;
2344 mod_log_ptr = page_zip_apply_log(d_stream->next_in,
2345 d_stream->avail_in + 1,
2347 ULINT_UNDEFINED, heap_status,
2350 if (UNIV_UNLIKELY(!mod_log_ptr)) {
2353 page_zip->
m_end = mod_log_ptr - page_zip->
data;
2354 page_zip->
m_nonempty = mod_log_ptr != d_stream->next_in;
2358 (page_zip_get_trailer_len(page_zip,
2362 " %lu + %lu >= %lu, %lu\n",
2363 (ulong) page_zip_get_trailer_len(
2365 (ulong) page_zip->
m_end,
2374 for (slot = 0; slot < n_dense; slot++) {
2375 rec_t* rec = recs[slot];
2377 offsets = rec_get_offsets(rec, index, offsets,
2378 ULINT_UNDEFINED, &heap);
2382 storage -= REC_NODE_PTR_SIZE;
2384 memcpy(rec_get_end(rec, offsets) - REC_NODE_PTR_SIZE,
2385 storage, REC_NODE_PTR_SIZE);
2396 page_zip_decompress_sec(
2406 ulint heap_status = REC_STATUS_ORDINARY
2407 | PAGE_HEAP_NO_USER_LOW << REC_HEAP_NO_SHIFT;
2413 d_stream->avail_in -= n_dense * PAGE_ZIP_DIR_SLOT_SIZE;
2415 for (slot = 0; slot < n_dense; slot++) {
2416 rec_t* rec = recs[slot];
2419 d_stream->avail_out = rec - REC_N_NEW_EXTRA_BYTES
2420 - d_stream->next_out;
2422 if (UNIV_LIKELY(d_stream->avail_out)) {
2423 switch (inflate(d_stream, Z_SYNC_FLUSH)) {
2425 page_zip_decompress_heap_no(
2426 d_stream, rec, heap_status);
2430 if (!d_stream->avail_out) {
2436 " inflate(Z_SYNC_FLUSH)=%s\n",
2442 if (!page_zip_decompress_heap_no(
2443 d_stream, rec, heap_status)) {
2454 if (UNIV_UNLIKELY(d_stream->avail_out > UNIV_PAGE_SIZE
2455 - PAGE_ZIP_START - PAGE_DIR)) {
2458 " avail_out = %u\n",
2459 d_stream->avail_out));
2463 if (UNIV_UNLIKELY(inflate(d_stream, Z_FINISH) != Z_STREAM_END)) {
2465 " inflate(Z_FINISH)=%s\n",
2468 inflateEnd(d_stream);
2476 if (UNIV_UNLIKELY(inflateEnd(d_stream) != Z_OK)) {
2484 memset(d_stream->next_out, 0,
2485 page_dir_get_nth_slot(page,
2487 - d_stream->next_out);
2491 page_zip->m_start = PAGE_DATA + d_stream->total_in;
2496 const byte* mod_log_ptr;
2497 mod_log_ptr = page_zip_apply_log(d_stream->next_in,
2498 d_stream->avail_in + 1,
2500 ULINT_UNDEFINED, heap_status,
2503 if (UNIV_UNLIKELY(!mod_log_ptr)) {
2506 page_zip->
m_end = mod_log_ptr - page_zip->
data;
2507 page_zip->
m_nonempty = mod_log_ptr != d_stream->next_in;
2510 if (UNIV_UNLIKELY(page_zip_get_trailer_len(page_zip, FALSE)
2513 page_zip_fail((
"page_zip_decompress_sec: %lu + %lu >= %lu\n",
2514 (ulong) page_zip_get_trailer_len(
2516 (ulong) page_zip->
m_end,
2533 page_zip_decompress_clust_ext(
2537 const ulint* offsets,
2546 if (UNIV_UNLIKELY(i == trx_id_col)) {
2548 dst = rec_get_nth_field(rec, offsets, i, &len);
2549 if (UNIV_UNLIKELY(len < DATA_TRX_ID_LEN
2550 + DATA_ROLL_PTR_LEN)) {
2553 " len[%lu] = %lu\n",
2554 (ulong) i, (ulong) len));
2561 " DB_TRX_ID at %lu is ext\n",
2566 d_stream->avail_out = dst - d_stream->next_out;
2568 switch (inflate(d_stream, Z_SYNC_FLUSH)) {
2572 if (!d_stream->avail_out) {
2578 " 1 inflate(Z_SYNC_FLUSH)=%s\n",
2583 ut_ad(d_stream->next_out == dst);
2588 memset(dst, 0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
2590 d_stream->next_out += DATA_TRX_ID_LEN
2591 + DATA_ROLL_PTR_LEN;
2593 dst = rec_get_nth_field(rec, offsets, i, &len);
2594 ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE);
2597 d_stream->avail_out = dst - d_stream->next_out;
2598 switch (inflate(d_stream, Z_SYNC_FLUSH)) {
2602 if (!d_stream->avail_out) {
2608 " 2 inflate(Z_SYNC_FLUSH)=%s\n",
2613 ut_ad(d_stream->next_out == dst);
2626 memset(d_stream->next_out, 0,
2627 BTR_EXTERN_FIELD_REF_SIZE);
2641 page_zip_decompress_clust(
2655 ulint heap_status = REC_STATUS_ORDINARY
2656 | PAGE_HEAP_NO_USER_LOW << REC_HEAP_NO_SHIFT;
2657 const byte* storage;
2658 const byte* externs;
2663 d_stream->avail_in -= n_dense * (PAGE_ZIP_DIR_SLOT_SIZE
2665 + DATA_ROLL_PTR_LEN);
2668 for (slot = 0; slot < n_dense; slot++) {
2669 rec_t* rec = recs[slot];
2671 d_stream->avail_out = rec - REC_N_NEW_EXTRA_BYTES
2672 - d_stream->next_out;
2674 ut_ad(d_stream->avail_out < UNIV_PAGE_SIZE
2675 - PAGE_ZIP_START - PAGE_DIR);
2676 err = inflate(d_stream, Z_SYNC_FLUSH);
2679 page_zip_decompress_heap_no(
2680 d_stream, rec, heap_status);
2684 if (UNIV_LIKELY(!d_stream->avail_out)) {
2690 " 1 inflate(Z_SYNC_FLUSH)=%s\n",
2695 if (!page_zip_decompress_heap_no(
2696 d_stream, rec, heap_status)) {
2701 offsets = rec_get_offsets(rec, index, offsets,
2702 ULINT_UNDEFINED, &heap);
2712 (!page_zip_decompress_clust_ext(
2713 d_stream, rec, offsets, trx_id_col))) {
2720 byte* dst = rec_get_nth_field(rec, offsets,
2722 if (UNIV_UNLIKELY(len < DATA_TRX_ID_LEN
2723 + DATA_ROLL_PTR_LEN)) {
2726 " len = %lu\n", (ulong) len));
2730 d_stream->avail_out = dst - d_stream->next_out;
2732 switch (inflate(d_stream, Z_SYNC_FLUSH)) {
2736 if (!d_stream->avail_out) {
2742 " 2 inflate(Z_SYNC_FLUSH)=%s\n",
2747 ut_ad(d_stream->next_out == dst);
2752 memset(dst, 0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
2754 d_stream->next_out += DATA_TRX_ID_LEN
2755 + DATA_ROLL_PTR_LEN;
2759 d_stream->avail_out = rec_get_end(rec, offsets)
2760 - d_stream->next_out;
2762 switch (inflate(d_stream, Z_SYNC_FLUSH)) {
2766 if (!d_stream->avail_out) {
2772 " 3 inflate(Z_SYNC_FLUSH)=%s\n",
2783 if (UNIV_UNLIKELY(d_stream->avail_out > UNIV_PAGE_SIZE
2784 - PAGE_ZIP_START - PAGE_DIR)) {
2787 " avail_out = %u\n",
2788 d_stream->avail_out));
2792 if (UNIV_UNLIKELY(inflate(d_stream, Z_FINISH) != Z_STREAM_END)) {
2794 " inflate(Z_FINISH)=%s\n",
2797 inflateEnd(d_stream);
2805 if (UNIV_UNLIKELY(inflateEnd(d_stream) != Z_OK)) {
2813 memset(d_stream->next_out, 0,
2814 page_dir_get_nth_slot(page,
2816 - d_stream->next_out);
2820 page_zip->m_start = PAGE_DATA + d_stream->total_in;
2825 const byte* mod_log_ptr;
2826 mod_log_ptr = page_zip_apply_log(d_stream->next_in,
2827 d_stream->avail_in + 1,
2829 trx_id_col, heap_status,
2832 if (UNIV_UNLIKELY(!mod_log_ptr)) {
2835 page_zip->
m_end = mod_log_ptr - page_zip->
data;
2836 page_zip->
m_nonempty = mod_log_ptr != d_stream->next_in;
2839 if (UNIV_UNLIKELY(page_zip_get_trailer_len(page_zip, TRUE)
2842 page_zip_fail((
"page_zip_decompress_clust: %lu + %lu >= %lu\n",
2843 (ulong) page_zip_get_trailer_len(
2845 (ulong) page_zip->
m_end,
2852 externs = storage - n_dense
2853 * (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
2857 for (slot = 0; slot < n_dense; slot++) {
2861 rec_t* rec = recs[slot];
2864 offsets = rec_get_offsets(rec, index, offsets,
2865 ULINT_UNDEFINED, &heap);
2867 dst = rec_get_nth_field(rec, offsets,
2869 ut_ad(len >= DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
2870 storage -= DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
2871 memcpy(dst, storage,
2872 DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
2886 dst = rec_get_nth_field(rec, offsets, i, &len);
2888 if (UNIV_UNLIKELY(len < BTR_EXTERN_FIELD_REF_SIZE)) {
2897 if (UNIV_LIKELY(exists)) {
2903 (externs < page_zip->data
2904 + page_zip->
m_end)) {
2906 "decompress_clust: "
2908 (
const void*) externs,
2916 memcpy(dst, externs,
2917 BTR_EXTERN_FIELD_REF_SIZE);
2924 BTR_EXTERN_FIELD_REF_SIZE);
2953 ulint trx_id_col = ULINT_UNDEFINED;
2956 #ifndef UNIV_HOTBACKUP
2960 ut_ad(page_zip_simple_validate(page_zip));
2961 UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
2966 if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
2974 heap =
mem_heap_create(n_dense * (3 *
sizeof *recs) + UNIV_PAGE_SIZE);
2976 recs =
static_cast<rec_t**
>(
2981 memcpy(page, page_zip->
data, PAGE_DATA);
2984 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
2988 ut_a(!memcmp(PAGE_HEADER + PAGE_LEVEL + page,
2989 PAGE_HEADER + PAGE_LEVEL + page_zip->
data,
2990 PAGE_DATA - (PAGE_HEADER + PAGE_LEVEL)));
2995 memcpy(PAGE_HEADER + page, PAGE_HEADER + page_zip->
data,
2996 PAGE_LEVEL - PAGE_N_DIR_SLOTS);
2998 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
3000 ut_a(!memcmp(page, page_zip->
data, PAGE_DATA));
3004 #ifdef UNIV_ZIP_DEBUG
3006 memset(PAGE_DATA + page, 0x55, UNIV_PAGE_SIZE - PAGE_DATA);
3008 UNIV_MEM_INVALID(PAGE_DATA + page, UNIV_PAGE_SIZE - PAGE_DATA);
3011 if (UNIV_UNLIKELY(!page_zip_dir_decode(page_zip, page, recs,
3012 recs + n_dense, n_dense))) {
3019 memcpy(page + (PAGE_NEW_INFIMUM - REC_N_NEW_EXTRA_BYTES),
3020 infimum_extra,
sizeof infimum_extra);
3027 & PAGE_ZIP_DIR_SLOT_MASK);
3029 memcpy(page + PAGE_NEW_INFIMUM, infimum_data,
sizeof infimum_data);
3030 memcpy(page + (PAGE_NEW_SUPREMUM - REC_N_NEW_EXTRA_BYTES + 1),
3031 supremum_extra_data,
sizeof supremum_extra_data);
3035 d_stream.next_in = page_zip->
data + PAGE_DATA;
3039 d_stream.next_out = page + PAGE_ZIP_START;
3040 d_stream.avail_out = UNIV_PAGE_SIZE - PAGE_ZIP_START;
3042 if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT)
3048 if (UNIV_UNLIKELY(inflate(&d_stream, Z_BLOCK) != Z_OK)) {
3051 " 1 inflate(Z_BLOCK)=%s\n", d_stream.msg));
3055 if (UNIV_UNLIKELY(inflate(&d_stream, Z_BLOCK) != Z_OK)) {
3058 " 2 inflate(Z_BLOCK)=%s\n", d_stream.msg));
3062 index = page_zip_fields_decode(
3063 page + PAGE_ZIP_START, d_stream.next_out,
3066 if (UNIV_UNLIKELY(!index)) {
3073 d_stream.next_out = page + PAGE_ZIP_START;
3077 ulint n = 1 + 1 + REC_OFFS_HEADER_SIZE
3080 offsets =
static_cast<ulint*
>(
3092 (!page_zip_decompress_node_ptrs(page_zip, &d_stream,
3093 recs, n_dense, index,
3099 ? REC_INFO_MIN_REC_FLAG : 0;
3101 if (UNIV_UNLIKELY(!page_zip_set_extra_bytes(page_zip, page,
3105 }
else if (UNIV_LIKELY(trx_id_col == ULINT_UNDEFINED)) {
3107 if (UNIV_UNLIKELY(!page_zip_decompress_sec(page_zip, &d_stream,
3113 if (UNIV_UNLIKELY(!page_zip_set_extra_bytes(page_zip,
3116 page_zip_fields_free(index);
3122 if (UNIV_UNLIKELY(!page_zip_decompress_clust(page_zip,
3130 if (UNIV_UNLIKELY(!page_zip_set_extra_bytes(page_zip,
3137 UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
3139 page_zip_fields_free(index);
3141 #ifndef UNIV_HOTBACKUP
3164 #ifdef UNIV_ZIP_DEBUG
3169 page_zip_hexdump_func(
3175 const byte* s =
static_cast<const byte*
>(
buf);
3177 const ulint width = 32;
3179 fprintf(stderr,
"%s:\n", name);
3181 for (addr = 0; addr <
size; addr += width) {
3184 fprintf(stderr,
"%04lx ", (ulong) addr);
3186 i =
ut_min(width, size - addr);
3189 fprintf(stderr,
"%02x", *s++);
3199 #define page_zip_hexdump(buf, size) page_zip_hexdump_func(#buf, buf, size)
3202 UNIV_INTERN ibool page_zip_validate_header_only = FALSE;
3209 page_zip_validate_low(
3218 byte* temp_page_buf;
3228 page_zip_hexdump(page_zip,
sizeof *page_zip);
3230 page_zip_hexdump(page, UNIV_PAGE_SIZE);
3236 if (page_zip_validate_header_only) {
3242 temp_page_buf =
static_cast<byte*
>(
ut_malloc(2 * UNIV_PAGE_SIZE));
3243 temp_page =
static_cast<byte*
>(
ut_align(temp_page_buf, UNIV_PAGE_SIZE));
3245 #ifdef UNIV_DEBUG_VALGRIND
3250 (void) VALGRIND_GET_VBITS(page, temp_page, UNIV_PAGE_SIZE);
3251 UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
3252 # if UNIV_WORD_SIZE == 4
3253 VALGRIND_GET_VBITS(page_zip, &temp_page_zip,
sizeof temp_page_zip);
3257 UNIV_MEM_ASSERT_RW(page_zip,
sizeof *page_zip);
3259 (void) VALGRIND_GET_VBITS(page_zip->
data, temp_page,
3264 temp_page_zip = *page_zip;
3267 fputs(
"page_zip_validate(): failed to decompress\n", stderr);
3276 if (page_zip->m_start != temp_page_zip.m_start) {
3278 page_zip->m_start, temp_page_zip.m_start));
3282 if (page_zip->
m_end != temp_page_zip.
m_end) {
3293 if (memcmp(page + PAGE_HEADER, temp_page + PAGE_HEADER,
3305 byte info_bits_diff;
3308 ut_a(offset >= PAGE_NEW_SUPREMUM);
3313 if (info_bits_diff == REC_INFO_MIN_REC_FLAG) {
3316 if (!memcmp(page + PAGE_HEADER,
3317 temp_page + PAGE_HEADER,
3318 UNIV_PAGE_SIZE - PAGE_HEADER
3326 "%lu,%lu,0x%02lx)\n",
3327 sloppy ?
"ignored, " :
"",
3330 (ulong) page[offset]));
3340 while (rec || trec) {
3343 "PAGE_FREE list: %u!=%u\n",
3358 page + PAGE_NEW_INFIMUM, TRUE);
3360 temp_page + PAGE_NEW_INFIMUM, TRUE);
3365 "record list: 0x%02x!=0x%02x\n",
3374 offsets = rec_get_offsets(
3375 rec, index, offsets,
3376 ULINT_UNDEFINED, &heap);
3382 (
"page_zip_validate: "
3383 "record content: 0x%02x",
3392 }
while (rec || trec);
3401 page_zip_hexdump(page_zip,
sizeof *page_zip);
3403 page_zip_hexdump(page, UNIV_PAGE_SIZE);
3404 page_zip_hexdump(temp_page, UNIV_PAGE_SIZE);
3421 return(page_zip_validate_low(page_zip, page, index,
3432 page_zip_header_cmp(
3454 page_zip_write_rec_ext(
3460 const ulint* offsets,
3467 const byte* start =
rec;
3470 byte* externs = storage;
3473 ut_ad(rec_offs_validate(rec, index, offsets));
3478 externs -= (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
3484 - (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
3485 - n_ext * BTR_EXTERN_FIELD_REF_SIZE
3486 < externs - BTR_EXTERN_FIELD_REF_SIZE * page_zip->
n_blobs);
3489 ulint blob_no = page_zip_get_n_prev_extern(
3490 page_zip, rec, index);
3491 byte* ext_end = externs - page_zip->
n_blobs
3493 ut_ad(blob_no <= page_zip->n_blobs);
3499 * BTR_EXTERN_FIELD_REF_SIZE);
3500 memmove(ext_end - n_ext
3501 * BTR_EXTERN_FIELD_REF_SIZE,
3506 ut_a(blob_no + n_ext <= page_zip->n_blobs);
3512 if (UNIV_UNLIKELY(i == trx_id_col)) {
3518 src = rec_get_nth_field(rec, offsets,
3520 ut_ad(len == DATA_TRX_ID_LEN);
3521 ut_ad(src + DATA_TRX_ID_LEN
3522 == rec_get_nth_field(
3525 ut_ad(len == DATA_ROLL_PTR_LEN);
3529 memcpy(data, start, src - start);
3530 data += src - start;
3531 start = src + (DATA_TRX_ID_LEN
3532 + DATA_ROLL_PTR_LEN);
3535 memcpy(storage - (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
3537 src, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
3540 src = rec_get_nth_field(rec, offsets,
3545 >= BTR_EXTERN_FIELD_REF_SIZE);
3549 memcpy(data, start, src - start);
3550 data += src - start;
3555 ut_ad(data < externs);
3556 memcpy(externs, src, BTR_EXTERN_FIELD_REF_SIZE);
3564 memcpy(data, start, len);
3580 const ulint* offsets,
3590 ut_ad(page_zip_simple_validate(page_zip));
3594 ut_ad(rec_offs_validate(rec, index, offsets));
3596 ut_ad(page_zip->m_start >= PAGE_DATA);
3600 ut_ad(page_zip_header_cmp(page_zip, page));
3612 *slot |= PAGE_ZIP_DIR_SLOT_DEL >> 8;
3614 *slot &= ~(PAGE_ZIP_DIR_SLOT_DEL >> 8);
3617 ut_ad(rec_get_start((rec_t*) rec, offsets) >= page + PAGE_ZIP_START);
3618 ut_ad(rec_get_end((rec_t*) rec, offsets) <= page + UNIV_PAGE_SIZE
3619 - PAGE_DIR - PAGE_DIR_SLOT_SIZE
3623 ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
3627 data = page_zip->
data + page_zip->
m_end;
3633 if (UNIV_UNLIKELY(heap_no - 1 >= 64)) {
3634 *data++ = (byte) (0x80 | (heap_no - 1) >> 7);
3637 *data++ = (byte) ((heap_no - 1) << 1);
3642 const byte* b = rec - REC_N_NEW_EXTRA_BYTES;
3649 while (b != start) {
3666 ut_ad(trx_id_col != ULINT_UNDEFINED);
3671 data = page_zip_write_rec_ext(
3673 rec, index, offsets, create,
3674 trx_id_col, heap_no, storage, data);
3678 = rec_get_nth_field(rec, offsets,
3680 ut_ad(len == DATA_TRX_ID_LEN);
3681 ut_ad(src + DATA_TRX_ID_LEN
3682 == rec_get_nth_field(
3684 trx_id_col + 1, &len));
3685 ut_ad(len == DATA_ROLL_PTR_LEN);
3689 memcpy(data, rec, src - rec);
3694 - (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
3697 DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
3699 src += DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
3706 memcpy(data, src, len);
3713 == ULINT_UNDEFINED);
3720 memcpy(data, rec, len);
3733 ut_ad(data + len < storage - REC_NODE_PTR_SIZE
3736 memcpy(data, rec, len);
3740 memcpy(storage - REC_NODE_PTR_SIZE
3748 page_zip->
m_end = data - page_zip->
data;
3751 #ifdef UNIV_ZIP_DEBUG
3771 ut_ad(!page == !page_zip);
3774 (end_ptr < ptr + (2 + 2 + BTR_EXTERN_FIELD_REF_SIZE))) {
3782 if (UNIV_UNLIKELY(offset < PAGE_ZIP_START)
3783 || UNIV_UNLIKELY(offset >= UNIV_PAGE_SIZE)
3784 || UNIV_UNLIKELY(z_offset >= UNIV_PAGE_SIZE)) {
3792 if (UNIV_UNLIKELY(!page_zip)
3798 #ifdef UNIV_ZIP_DEBUG
3799 ut_a(page_zip_validate(page_zip, page, NULL));
3802 memcpy(page + offset,
3803 ptr + 4, BTR_EXTERN_FIELD_REF_SIZE);
3804 memcpy(page_zip->
data + z_offset,
3805 ptr + 4, BTR_EXTERN_FIELD_REF_SIZE);
3807 #ifdef UNIV_ZIP_DEBUG
3808 ut_a(page_zip_validate(page_zip, page, NULL));
3812 return(ptr + (2 + 2 + BTR_EXTERN_FIELD_REF_SIZE));
3826 const ulint* offsets,
3839 ut_ad(page_zip_simple_validate(page_zip));
3843 ut_ad(rec_offs_validate(rec, NULL, offsets));
3847 ut_ad(page_zip->m_start >= PAGE_DATA);
3848 ut_ad(page_zip_header_cmp(page_zip, page));
3858 blob_no = page_zip_get_n_prev_extern(page_zip, rec, index)
3860 ut_a(blob_no < page_zip->n_blobs);
3864 * (PAGE_ZIP_DIR_SLOT_SIZE
3865 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
3867 field = rec_get_nth_field(rec, offsets, n, &len);
3869 externs -= (blob_no + 1) * BTR_EXTERN_FIELD_REF_SIZE;
3872 memcpy(externs, field, BTR_EXTERN_FIELD_REF_SIZE);
3874 #ifdef UNIV_ZIP_DEBUG
3875 ut_a(page_zip_validate(page_zip, page, index));
3879 #ifndef UNIV_HOTBACKUP
3881 mtr, 11 + 2 + 2 + BTR_EXTERN_FIELD_REF_SIZE);
3882 if (UNIV_UNLIKELY(!log_ptr)) {
3892 memcpy(log_ptr, externs, BTR_EXTERN_FIELD_REF_SIZE);
3914 ut_ad(!page == !page_zip);
3916 if (UNIV_UNLIKELY(end_ptr < ptr + (2 + 2 + REC_NODE_PTR_SIZE))) {
3924 if (UNIV_UNLIKELY(offset < PAGE_ZIP_START)
3925 || UNIV_UNLIKELY(offset >= UNIV_PAGE_SIZE)
3926 || UNIV_UNLIKELY(z_offset >= UNIV_PAGE_SIZE)) {
3939 if (UNIV_UNLIKELY(!page_zip)
3945 #ifdef UNIV_ZIP_DEBUG
3946 ut_a(page_zip_validate(page_zip, page, NULL));
3950 storage = page_zip->
data + z_offset;
3954 heap_no = 1 + (storage_end - storage) / REC_NODE_PTR_SIZE;
3956 if (UNIV_UNLIKELY((storage_end - storage) % REC_NODE_PTR_SIZE)
3957 || UNIV_UNLIKELY(heap_no < PAGE_HEAP_NO_USER_LOW)
3963 memcpy(field, ptr + 4, REC_NODE_PTR_SIZE);
3964 memcpy(storage, ptr + 4, REC_NODE_PTR_SIZE);
3966 #ifdef UNIV_ZIP_DEBUG
3967 ut_a(page_zip_validate(page_zip, page, NULL));
3971 return(ptr + (2 + 2 + REC_NODE_PTR_SIZE));
3994 ut_ad(page_zip_simple_validate(page_zip));
3999 ut_ad(page_zip->m_start >= PAGE_DATA);
4000 ut_ad(page_zip_header_cmp(page_zip, page));
4005 UNIV_MEM_ASSERT_RW(rec, size);
4009 field = rec + size - REC_NODE_PTR_SIZE;
4011 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
4012 ut_a(!memcmp(storage, field, REC_NODE_PTR_SIZE));
4014 #if REC_NODE_PTR_SIZE != 4
4015 # error "REC_NODE_PTR_SIZE != 4"
4018 memcpy(storage, field, REC_NODE_PTR_SIZE);
4021 #ifndef UNIV_HOTBACKUP
4023 11 + 2 + 2 + REC_NODE_PTR_SIZE);
4024 if (UNIV_UNLIKELY(!log_ptr)) {
4034 memcpy(log_ptr, field, REC_NODE_PTR_SIZE);
4035 log_ptr += REC_NODE_PTR_SIZE;
4049 const ulint* offsets,
4064 ut_ad(page_zip_simple_validate(page_zip));
4067 ut_ad(rec_offs_validate(rec, NULL, offsets));
4070 ut_ad(page_zip->m_start >= PAGE_DATA);
4071 ut_ad(page_zip_header_cmp(page_zip, page));
4079 * (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4081 #if DATA_TRX_ID + 1 != DATA_ROLL_PTR
4082 # error "DATA_TRX_ID + 1 != DATA_ROLL_PTR"
4084 field = rec_get_nth_field(rec, offsets, trx_id_col, &len);
4085 ut_ad(len == DATA_TRX_ID_LEN);
4086 ut_ad(field + DATA_TRX_ID_LEN
4087 == rec_get_nth_field(rec, offsets, trx_id_col + 1, &len));
4088 ut_ad(len == DATA_ROLL_PTR_LEN);
4089 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
4090 ut_a(!memcmp(storage, field, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN));
4092 #if DATA_TRX_ID_LEN != 6
4093 # error "DATA_TRX_ID_LEN != 6"
4096 #if DATA_ROLL_PTR_LEN != 7
4097 # error "DATA_ROLL_PTR_LEN != 7"
4100 memcpy(storage, field, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4118 const ulint* offsets)
4127 ut_ad(rec_offs_validate(rec, index, offsets));
4130 ut_ad(page_zip_header_cmp(page_zip, page));
4133 ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
4147 field = rec_get_nth_field(rec, offsets,
4150 ut_ad(len == REC_NODE_PTR_SIZE);
4153 memset(field, 0, REC_NODE_PTR_SIZE);
4154 memset(storage - (heap_no - 1) * REC_NODE_PTR_SIZE,
4155 0, REC_NODE_PTR_SIZE);
4160 const ulint trx_id_pos
4162 dict_table_get_sys_col(
4163 index->
table, DATA_TRX_ID), index);
4165 field = rec_get_nth_field(rec, offsets, trx_id_pos, &len);
4166 ut_ad(len == DATA_TRX_ID_LEN);
4168 memset(field, 0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4169 memset(storage - (heap_no - 1)
4170 * (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN),
4171 0, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4180 field = rec_get_nth_field(
4181 rec, offsets, i, &len);
4183 == BTR_EXTERN_FIELD_REF_SIZE);
4185 - BTR_EXTERN_FIELD_REF_SIZE,
4186 0, BTR_EXTERN_FIELD_REF_SIZE);
4194 #ifdef UNIV_ZIP_DEBUG
4195 ut_a(page_zip_validate(page_zip, page, index));
4214 *slot |= (PAGE_ZIP_DIR_SLOT_DEL >> 8);
4216 *slot &= ~(PAGE_ZIP_DIR_SLOT_DEL >> 8);
4218 #ifdef UNIV_ZIP_DEBUG
4238 *slot |= (PAGE_ZIP_DIR_SLOT_OWNED >> 8);
4240 *slot &= ~(PAGE_ZIP_DIR_SLOT_OWNED >> 8);
4251 const byte* prev_rec,
4252 const byte* free_rec,
4260 ut_ad(prev_rec != rec);
4262 ut_ad(page_zip_simple_validate(page_zip));
4273 if (UNIV_LIKELY(!free_rec)) {
4278 start += PAGE_ZIP_DIR_SLOT_SIZE;
4288 - (PAGE_HEAP_NO_USER_LOW + 1);
4290 if (UNIV_LIKELY_NULL(free_rec)) {
4297 + PAGE_HEAP_NO_USER_LOW);
4298 ut_ad(rec >= free_rec);
4301 slot_free += PAGE_ZIP_DIR_SLOT_SIZE;
4306 + PAGE_HEAP_NO_USER_LOW);
4310 - PAGE_ZIP_DIR_SLOT_SIZE * n_dense;
4314 memmove(slot_free - PAGE_ZIP_DIR_SLOT_SIZE, slot_free,
4315 slot_rec - slot_free);
4332 const ulint* offsets,
4341 ut_ad(rec_offs_validate(rec, index, offsets));
4357 if (UNIV_UNLIKELY(!free)) {
4360 - PAGE_ZIP_DIR_SLOT_SIZE
4362 - PAGE_HEAP_NO_USER_LOW);
4366 ut_a(slot_free < slot_rec);
4368 slot_free += PAGE_ZIP_DIR_SLOT_SIZE;
4371 if (UNIV_LIKELY(slot_rec > slot_free)) {
4372 memmove(slot_free + PAGE_ZIP_DIR_SLOT_SIZE,
4374 slot_rec - slot_free);
4387 if (UNIV_UNLIKELY(n_ext)) {
4393 blob_no = page_zip_get_n_prev_extern(page_zip, rec, index);
4394 ut_a(blob_no + n_ext <= page_zip->n_blobs);
4398 * (PAGE_ZIP_DIR_SLOT_SIZE
4399 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4401 ext_end = externs - page_zip->
n_blobs
4407 memmove(ext_end + n_ext * BTR_EXTERN_FIELD_REF_SIZE, ext_end,
4409 * BTR_EXTERN_FIELD_REF_SIZE);
4410 memset(ext_end, 0, n_ext * BTR_EXTERN_FIELD_REF_SIZE);
4416 rec[-REC_N_NEW_EXTRA_BYTES] = 0;
4418 page_zip_clear_rec(page_zip, rec, index, offsets);
4440 - (PAGE_HEAP_NO_USER_LOW + 1);
4443 - PAGE_ZIP_DIR_SLOT_SIZE * n_dense;
4447 stored = dir - n_dense * REC_NODE_PTR_SIZE;
4448 }
else if (is_clustered) {
4453 stored = dir - n_dense
4454 * (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4458 - (PAGE_ZIP_DIR_SLOT_SIZE
4459 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN),
4460 PAGE_ZIP_DIR_SLOT_SIZE
4461 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
4462 memmove(externs - (PAGE_ZIP_DIR_SLOT_SIZE
4463 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN),
4464 externs, stored - externs);
4469 PAGE_ZIP_DIR_SLOT_SIZE);
4474 memmove(stored - PAGE_ZIP_DIR_SLOT_SIZE, stored, dir - stored);
4492 ut_ad(ptr && end_ptr);
4493 ut_ad(!page == !page_zip);
4495 if (UNIV_UNLIKELY(end_ptr < ptr + (1 + 1))) {
4500 offset = (ulint) *ptr++;
4501 len = (ulint) *ptr++;
4503 if (UNIV_UNLIKELY(!len) || UNIV_UNLIKELY(offset + len >= PAGE_DATA)) {
4510 if (UNIV_UNLIKELY(end_ptr < ptr + len)) {
4516 if (UNIV_UNLIKELY(!page_zip)) {
4520 #ifdef UNIV_ZIP_DEBUG
4521 ut_a(page_zip_validate(page_zip, page, NULL));
4524 memcpy(page + offset, ptr, len);
4525 memcpy(page_zip->
data + offset, ptr, len);
4527 #ifdef UNIV_ZIP_DEBUG
4528 ut_a(page_zip_validate(page_zip, page, NULL));
4535 #ifndef UNIV_HOTBACKUP
4546 byte* log_ptr =
mlog_open(mtr, 11 + 1 + 1);
4549 ut_ad(offset < PAGE_DATA);
4550 ut_ad(offset + length < PAGE_DATA);
4552 # error "PAGE_DATA > 255"
4554 ut_ad(length < 256);
4557 if (UNIV_UNLIKELY(!log_ptr)) {
4564 *log_ptr++ = (byte) offset;
4565 *log_ptr++ = (byte) length;
4594 #ifndef UNIV_HOTBACKUP
4598 page_t* page = buf_block_get_frame(block);
4603 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
4607 UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
4613 #ifndef UNIV_HOTBACKUP
4618 ut_ad(block == back_block1);
4619 temp_block = back_block2;
4621 temp_page = temp_block->
frame;
4626 btr_blob_dbg_remove(page, index,
"zip_reorg");
4637 page_get_infimum_rec(temp_page),
4644 ut_ad(max_trx_id != 0);
4652 #ifndef UNIV_HOTBACKUP
4660 #ifndef UNIV_HOTBACKUP
4666 #ifndef UNIV_HOTBACKUP
4685 ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
4686 ut_ad(mtr_memo_contains_page(mtr, src, MTR_MEMO_PAGE_X_FIX));
4688 #ifdef UNIV_ZIP_DEBUG
4693 ut_a(page_zip_validate_low(src_zip, src, index, TRUE));
4696 if (UNIV_UNLIKELY(src_zip->
n_blobs)) {
4706 UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
4708 UNIV_MEM_ASSERT_RW(src, UNIV_PAGE_SIZE);
4715 #if PAGE_MAX_TRX_ID + 8 != PAGE_HEADER_PRIV_END
4716 # error "PAGE_MAX_TRX_ID + 8 != PAGE_HEADER_PRIV_END"
4718 memcpy(PAGE_HEADER + page, PAGE_HEADER + src,
4719 PAGE_HEADER_PRIV_END);
4720 memcpy(PAGE_DATA + page, PAGE_DATA + src,
4722 memcpy(PAGE_HEADER + page_zip->
data, PAGE_HEADER + src_zip->
data,
4723 PAGE_HEADER_PRIV_END);
4724 memcpy(PAGE_DATA + page_zip->
data, PAGE_DATA + src_zip->
data,
4731 memcpy(page_zip, src_zip,
sizeof *page_zip);
4732 page_zip->
data = data;
4744 if (UNIV_LIKELY(offs != PAGE_NEW_SUPREMUM)) {
4745 rec_t* rec = page + offs;
4746 ut_a(rec[-REC_N_NEW_EXTRA_BYTES]
4747 & REC_INFO_MIN_REC_FLAG);
4748 rec[-REC_N_NEW_EXTRA_BYTES] &= ~ REC_INFO_MIN_REC_FLAG;
4752 #ifdef UNIV_ZIP_DEBUG
4753 ut_a(page_zip_validate(page_zip, page, index));
4755 btr_blob_dbg_add(page, index,
"page_zip_copy_recs");
4757 page_zip_compress_write_log(page_zip, page, index, mtr);
4776 ut_ad(ptr && end_ptr);
4777 ut_ad(!page == !page_zip);
4779 if (UNIV_UNLIKELY(ptr + (2 + 2) > end_ptr)) {
4789 if (UNIV_UNLIKELY(ptr + 8 + size + trailer_size > end_ptr)) {
4795 if (UNIV_UNLIKELY(!page_zip)
4810 - trailer_size, ptr + 8 + size, trailer_size);
4819 return(ptr + 8 + size + trailer_size);
4835 const Bytef* s =
static_cast<const byte*
>(data);
4852 return((ulint) crc32);
4863 return((ulint) adler);
4888 ib_uint32_t crc32 = 0 ;
4889 ib_uint32_t innodb = 0 ;
4897 ut_d(ulint i;
for (i = 0; i <
size; i++) {
4898 ut_a(*((
const char*) data + i) == 0); });
4904 data, size, static_cast<srv_checksum_algorithm_t>(
4907 if (stored == calc) {
4915 return(stored == calc);
4938 return(stored == crc32 || stored == innodb);