~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/fsp/fsp0fsp.c

Imported InnoDB plugin with changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include "fut0fut.h"
20
20
#include "ut0byte.h"
21
21
#include "srv0srv.h"
22
 
#include "page0types.h"
 
22
#include "page0zip.h"
23
23
#include "ibuf0ibuf.h"
24
24
#include "btr0btr.h"
25
25
#include "btr0sea.h"
60
60
                                        about the first extent, but have not
61
61
                                        physically allocted those pages to the
62
62
                                        file */
63
 
#define FSP_LOWEST_NO_WRITE     16      /* The lowest page offset for which
64
 
                                        the page has not been written to disk
65
 
                                        (if it has been written, we know that
66
 
                                        the OS has really reserved the
67
 
                                        physical space for the page) */
 
63
#define FSP_SPACE_FLAGS         16      /* table->flags & ~DICT_TF_COMPACT */
68
64
#define FSP_FRAG_N_USED         20      /* number of used pages in the
69
65
                                        FSP_FREE_FRAG list */
70
66
#define FSP_FREE                24      /* list of free extents */
139
135
        (16 + 3 * FLST_BASE_NODE_SIZE                   \
140
136
         + FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
141
137
 
142
 
#define FSP_SEG_INODES_PER_PAGE                                         \
143
 
        ((UNIV_PAGE_SIZE - FSEG_ARR_OFFSET - 10) / FSEG_INODE_SIZE)
 
138
#define FSP_SEG_INODES_PER_PAGE(zip_size)               \
 
139
        (((zip_size ? zip_size : UNIV_PAGE_SIZE)        \
 
140
          - FSEG_ARR_OFFSET - 10) / FSEG_INODE_SIZE)
144
141
                                /* Number of segment inodes which fit on a
145
142
                                single page */
146
143
 
219
216
fsp_free_extent(
220
217
/*============*/
221
218
        ulint           space,  /* in: space id */
 
219
        ulint           zip_size,/* in: compressed page size in bytes
 
220
                                or 0 for uncompressed pages */
222
221
        ulint           page,   /* in: page offset in the extent */
223
222
        mtr_t*          mtr);   /* in: mtr */
224
223
/**************************************************************************
229
228
/*=============*/
230
229
        fseg_inode_t*   seg_inode, /* in: segment inode */
231
230
        ulint           space,  /* in: space id */
 
231
        ulint           zip_size,/* in: compressed page size in bytes
 
232
                                or 0 for uncompressed pages */
232
233
        ulint           page,   /* in: page offset in the extent */
233
234
        mtr_t*          mtr);   /* in: mtr handle */
234
235
/**************************************************************************
251
252
/*================*/
252
253
        fseg_inode_t*   seg_inode,/* in: segment inode */
253
254
        ulint           space,  /* in: space id */
 
255
        ulint           zip_size,/* in: compressed page size in bytes
 
256
                                or 0 for uncompressed pages */
254
257
        ulint           page,   /* in: page offset */
255
258
        mtr_t*          mtr);   /* in: mtr */
256
259
/**************************************************************************
264
267
                                /* out: the first extent descriptor, or NULL if
265
268
                                none */
266
269
        fseg_inode_t*   inode,  /* in: segment inode */
 
270
        ulint           space,  /* in: space id */
 
271
        ulint           zip_size,/* in: compressed page size in bytes
 
272
                                or 0 for uncompressed pages */
267
273
        mtr_t*          mtr);   /* in: mtr */
268
274
/**************************************************************************
269
275
Puts new extents to the free list if
293
299
                                /* out: the allocated page number, FIL_NULL
294
300
                                if no page could be allocated */
295
301
        ulint           space,  /* in: space */
 
302
        ulint           zip_size,/* in: compressed page size in bytes
 
303
                                or 0 for uncompressed pages */
296
304
        fseg_inode_t*   seg_inode, /* in: segment inode */
297
305
        ulint           hint,   /* in: hint of which page would be desirable */
298
306
        byte            direction, /* in: if the new page is needed because
305
313
 
306
314
/**************************************************************************
307
315
Reads the file space size stored in the header page. */
308
 
 
 
316
UNIV_INTERN
309
317
ulint
310
318
fsp_get_size_low(
311
319
/*=============*/
323
331
/*=================*/
324
332
                        /* out: pointer to the space header, page x-locked */
325
333
        ulint   id,     /* in: space id */
 
334
        ulint   zip_size,/* in: compressed page size in bytes
 
335
                        or 0 for uncompressed pages */
326
336
        mtr_t*  mtr)    /* in: mtr */
327
337
{
 
338
        buf_block_t*    block;
328
339
        fsp_header_t*   header;
329
340
 
330
 
        ut_ad(mtr);
 
341
        ut_ad(ut_is_2pow(zip_size));
 
342
        ut_ad(zip_size <= UNIV_PAGE_SIZE);
 
343
        ut_ad(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE);
 
344
        ut_ad(id || !zip_size);
331
345
 
332
 
        header = FSP_HEADER_OFFSET + buf_page_get(id, 0, RW_X_LATCH, mtr);
 
346
        block = buf_page_get(id, zip_size, 0, RW_X_LATCH, mtr);
 
347
        header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
333
348
#ifdef UNIV_SYNC_DEBUG
334
 
        buf_page_dbg_add_level(header, SYNC_FSP_PAGE);
 
349
        buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
335
350
#endif /* UNIV_SYNC_DEBUG */
 
351
        ut_ad(id == mach_read_from_4(FSP_SPACE_ID + header));
 
352
        ut_ad(zip_size == dict_table_flags_to_zip_size(
 
353
                      mach_read_from_4(FSP_SPACE_FLAGS + header)));
336
354
        return(header);
337
355
}
338
356
 
353
371
        ulint   byte_index;
354
372
        ulint   bit_index;
355
373
 
356
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
357
 
                                MTR_MEMO_PAGE_X_FIX));
 
374
        ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
358
375
        ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT));
359
376
        ut_ad(offset < FSP_EXTENT_SIZE);
360
377
 
386
403
        ulint   bit_index;
387
404
        ulint   descr_byte;
388
405
 
389
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
390
 
                                MTR_MEMO_PAGE_X_FIX));
 
406
        ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
391
407
        ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT));
392
408
        ut_ad(offset < FSP_EXTENT_SIZE);
393
409
 
425
441
        ut_ad(descr && mtr);
426
442
        ut_ad(val <= TRUE);
427
443
        ut_ad(hint < FSP_EXTENT_SIZE);
428
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
429
 
                                MTR_MEMO_PAGE_X_FIX));
 
444
        ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
430
445
        for (i = hint; i < FSP_EXTENT_SIZE; i++) {
431
446
                if (val == xdes_get_bit(descr, bit, i, mtr)) {
432
447
 
464
479
        ut_ad(descr && mtr);
465
480
        ut_ad(val <= TRUE);
466
481
        ut_ad(hint < FSP_EXTENT_SIZE);
467
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
468
 
                                MTR_MEMO_PAGE_X_FIX));
 
482
        ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
469
483
        for (i = hint + 1; i > 0; i--) {
470
484
                if (val == xdes_get_bit(descr, bit, i - 1, mtr)) {
471
485
 
497
511
        ulint   count   = 0;
498
512
 
499
513
        ut_ad(descr && mtr);
500
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
501
 
                                MTR_MEMO_PAGE_X_FIX));
 
514
        ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
502
515
        for (i = 0; i < FSP_EXTENT_SIZE; i++) {
503
516
                if (FALSE == xdes_get_bit(descr, XDES_FREE_BIT, i, mtr)) {
504
517
                        count++;
557
570
        ut_ad(descr && mtr);
558
571
        ut_ad(state >= XDES_FREE);
559
572
        ut_ad(state <= XDES_FSEG);
560
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
561
 
                                MTR_MEMO_PAGE_X_FIX));
 
573
        ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
562
574
 
563
575
        mlog_write_ulint(descr + XDES_STATE, state, MLOG_4BYTES, mtr);
564
576
}
573
585
        xdes_t* descr,  /* in: descriptor */
574
586
        mtr_t*  mtr)    /* in: mtr handle */
575
587
{
 
588
        ulint   state;
 
589
 
576
590
        ut_ad(descr && mtr);
577
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
578
 
                                MTR_MEMO_PAGE_X_FIX));
 
591
        ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
579
592
 
580
 
        return(mtr_read_ulint(descr + XDES_STATE, MLOG_4BYTES, mtr));
 
593
        state = mtr_read_ulint(descr + XDES_STATE, MLOG_4BYTES, mtr);
 
594
        ut_ad(state - 1 < XDES_FSEG);
 
595
        return(state);
581
596
}
582
597
 
583
598
/**************************************************************************
592
607
        ulint   i;
593
608
 
594
609
        ut_ad(descr && mtr);
595
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
596
 
                                MTR_MEMO_PAGE_X_FIX));
 
610
        ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
597
611
        ut_ad((XDES_SIZE - XDES_BITMAP) % 4 == 0);
598
612
 
599
613
        for (i = XDES_BITMAP; i < XDES_SIZE; i += 4) {
610
624
xdes_calc_descriptor_page(
611
625
/*======================*/
612
626
                                /* out: descriptor page offset */
 
627
        ulint   zip_size,       /* in: compressed page size in bytes;
 
628
                                0 for uncompressed pages */
613
629
        ulint   offset)         /* in: page offset */
614
630
{
615
631
#if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
616
 
                + (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE) * XDES_SIZE
617
 
# error
618
 
#endif
 
632
                + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
 
633
# error
 
634
#endif
 
635
#if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
 
636
                + (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
 
637
# error
 
638
#endif
 
639
        ut_ad(ut_is_2pow(zip_size));
619
640
 
620
 
        return(ut_2pow_round(offset, XDES_DESCRIBED_PER_PAGE));
 
641
        if (!zip_size) {
 
642
                return(ut_2pow_round(offset, UNIV_PAGE_SIZE));
 
643
        } else {
 
644
                ut_ad(zip_size > XDES_ARR_OFFSET
 
645
                      + (zip_size / FSP_EXTENT_SIZE) * XDES_SIZE);
 
646
                return(ut_2pow_round(offset, zip_size));
 
647
        }
621
648
}
622
649
 
623
650
/************************************************************************
627
654
xdes_calc_descriptor_index(
628
655
/*=======================*/
629
656
                                /* out: descriptor index */
 
657
        ulint   zip_size,       /* in: compressed page size in bytes;
 
658
                                0 for uncompressed pages */
630
659
        ulint   offset)         /* in: page offset */
631
660
{
632
 
        return(ut_2pow_remainder(offset, XDES_DESCRIBED_PER_PAGE)
633
 
               / FSP_EXTENT_SIZE);
 
661
        ut_ad(ut_is_2pow(zip_size));
 
662
 
 
663
        if (!zip_size) {
 
664
                return(ut_2pow_remainder(offset, UNIV_PAGE_SIZE)
 
665
                       / FSP_EXTENT_SIZE);
 
666
        } else {
 
667
                return(ut_2pow_remainder(offset, zip_size) / FSP_EXTENT_SIZE);
 
668
        }
634
669
}
635
670
 
636
671
/************************************************************************
656
691
{
657
692
        ulint   limit;
658
693
        ulint   size;
 
694
        ulint   zip_size;
659
695
        ulint   descr_page_no;
660
696
        page_t* descr_page;
661
697
 
662
698
        ut_ad(mtr);
663
 
        ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space),
 
699
        ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
664
700
                                MTR_MEMO_X_LOCK));
 
701
        ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_S_FIX)
 
702
              || mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
665
703
        /* Read free limit and space size */
666
 
        limit = mtr_read_ulint(sp_header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr);
667
 
        size  = mtr_read_ulint(sp_header + FSP_SIZE, MLOG_4BYTES, mtr);
 
704
        limit = mach_read_from_4(sp_header + FSP_FREE_LIMIT);
 
705
        size  = mach_read_from_4(sp_header + FSP_SIZE);
 
706
        zip_size = dict_table_flags_to_zip_size(
 
707
                mach_read_from_4(sp_header + FSP_SPACE_FLAGS));
668
708
 
669
709
        /* If offset is >= size or > limit, return NULL */
670
710
 
679
719
                fsp_fill_free_list(FALSE, space, sp_header, mtr);
680
720
        }
681
721
 
682
 
        descr_page_no = xdes_calc_descriptor_page(offset);
 
722
        descr_page_no = xdes_calc_descriptor_page(zip_size, offset);
683
723
 
684
724
        if (descr_page_no == 0) {
685
725
                /* It is on the space header page */
686
726
 
687
 
                descr_page = buf_frame_align(sp_header);
 
727
                descr_page = page_align(sp_header);
688
728
        } else {
689
 
                descr_page = buf_page_get(space, descr_page_no, RW_X_LATCH,
690
 
                                          mtr);
 
729
                buf_block_t*    block;
 
730
 
 
731
                block = buf_page_get(space, zip_size, descr_page_no,
 
732
                                     RW_X_LATCH, mtr);
691
733
#ifdef UNIV_SYNC_DEBUG
692
 
                buf_page_dbg_add_level(descr_page, SYNC_FSP_PAGE);
 
734
                buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
693
735
#endif /* UNIV_SYNC_DEBUG */
 
736
                descr_page = buf_block_get_frame(block);
694
737
        }
695
738
 
696
739
        return(descr_page + XDES_ARR_OFFSET
697
 
               + XDES_SIZE * xdes_calc_descriptor_index(offset));
 
740
               + XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset));
698
741
}
699
742
 
700
743
/************************************************************************
712
755
                        page does not exist in the space or if offset > free
713
756
                        limit */
714
757
        ulint   space,  /* in: space id */
 
758
        ulint   zip_size,/* in: compressed page size in bytes
 
759
                        or 0 for uncompressed pages */
715
760
        ulint   offset, /* in: page offset; if equal to the free limit,
716
761
                        we try to add new extents to the space free list */
717
762
        mtr_t*  mtr)    /* in: mtr handle */
718
763
{
 
764
        buf_block_t*    block;
719
765
        fsp_header_t*   sp_header;
720
766
 
721
 
        sp_header = FSP_HEADER_OFFSET
722
 
                + buf_page_get(space, 0, RW_X_LATCH, mtr);
 
767
        block = buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
723
768
#ifdef UNIV_SYNC_DEBUG
724
 
        buf_page_dbg_add_level(sp_header, SYNC_FSP_PAGE);
 
769
        buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
725
770
#endif /* UNIV_SYNC_DEBUG */
 
771
        sp_header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
726
772
        return(xdes_get_descriptor_with_space_hdr(sp_header, space, offset,
727
773
                                                  mtr));
728
774
}
737
783
/*====================*/
738
784
                                /* out: pointer to the extent descriptor */
739
785
        ulint           space,  /* in: space id */
 
786
        ulint           zip_size,/* in: compressed page size in bytes
 
787
                                or 0 for uncompressed pages */
740
788
        fil_addr_t      lst_node,/* in: file address of the list node
741
789
                                contained in the descriptor */
742
790
        mtr_t*          mtr)    /* in: mtr handle */
744
792
        xdes_t* descr;
745
793
 
746
794
        ut_ad(mtr);
747
 
        ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space),
 
795
        ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
748
796
                                MTR_MEMO_X_LOCK));
749
 
        descr = fut_get_ptr(space, lst_node, RW_X_LATCH, mtr) - XDES_FLST_NODE;
 
797
        descr = fut_get_ptr(space, zip_size, lst_node, RW_X_LATCH, mtr)
 
798
                - XDES_FLST_NODE;
750
799
 
751
800
        return(descr);
752
801
}
753
802
 
754
803
/************************************************************************
755
 
Gets pointer to the next descriptor in a descriptor list and x-locks its
756
 
page. */
757
 
UNIV_INLINE
758
 
xdes_t*
759
 
xdes_lst_get_next(
760
 
/*==============*/
761
 
        xdes_t* descr,  /* in: pointer to a descriptor */
762
 
        mtr_t*  mtr)    /* in: mtr handle */
763
 
{
764
 
        ulint   space;
765
 
 
766
 
        ut_ad(mtr && descr);
767
 
 
768
 
        space = buf_frame_get_space_id(descr);
769
 
 
770
 
        return(xdes_lst_get_descriptor(
771
 
                       space,
772
 
                       flst_get_next_addr(descr + XDES_FLST_NODE, mtr), mtr));
773
 
}
774
 
 
775
 
/************************************************************************
776
804
Returns page offset of the first page in extent described by a descriptor. */
777
805
UNIV_INLINE
778
806
ulint
783
811
{
784
812
        ut_ad(descr);
785
813
 
786
 
        return(buf_frame_get_page_no(descr)
787
 
               + ((descr - buf_frame_align(descr) - XDES_ARR_OFFSET)
788
 
                  / XDES_SIZE)
 
814
        return(page_get_page_no(page_align(descr))
 
815
               + ((page_offset(descr) - XDES_ARR_OFFSET) / XDES_SIZE)
789
816
               * FSP_EXTENT_SIZE);
790
817
}
791
818
 
795
822
void
796
823
fsp_init_file_page_low(
797
824
/*===================*/
798
 
        byte*   ptr)    /* in: pointer to a page */
 
825
        buf_block_t*    block)  /* in: pointer to a page */
799
826
{
800
 
        page_t* page;
801
 
        page = buf_frame_align(ptr);
802
 
 
803
 
        buf_block_align(page)->check_index_page_at_flush = FALSE;
 
827
        page_t*         page    = buf_block_get_frame(block);
 
828
        page_zip_des_t* page_zip= buf_block_get_page_zip(block);
 
829
 
 
830
        block->check_index_page_at_flush = FALSE;
 
831
 
 
832
        if (UNIV_LIKELY_NULL(page_zip)) {
 
833
                memset(page, 0, UNIV_PAGE_SIZE);
 
834
                memset(page_zip->data, 0, page_zip_get_size(page_zip));
 
835
                mach_write_to_4(page + FIL_PAGE_OFFSET,
 
836
                                buf_block_get_page_no(block));
 
837
                mach_write_to_4(page
 
838
                                + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
 
839
                                buf_block_get_space(block));
 
840
                memcpy(page_zip->data + FIL_PAGE_OFFSET,
 
841
                       page + FIL_PAGE_OFFSET, 4);
 
842
                memcpy(page_zip->data + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
 
843
                       page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 4);
 
844
                return;
 
845
        }
804
846
 
805
847
#ifdef UNIV_BASIC_LOG_DEBUG
806
848
        memset(page, 0xff, UNIV_PAGE_SIZE);
807
849
#endif
808
 
        mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
809
 
                        ut_dulint_zero);
810
 
        mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero);
 
850
        mach_write_to_4(page + FIL_PAGE_OFFSET, buf_block_get_page_no(block));
 
851
        memset(page + FIL_PAGE_LSN, 0, 8);
 
852
        mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
 
853
                        buf_block_get_space(block));
 
854
        memset(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, 0, 8);
811
855
}
812
856
 
813
857
/***************************************************************
816
860
void
817
861
fsp_init_file_page(
818
862
/*===============*/
819
 
        page_t* page,   /* in: page */
820
 
        mtr_t*  mtr)    /* in: mtr */
 
863
        buf_block_t*    block,  /* in: pointer to a page */
 
864
        mtr_t*          mtr)    /* in: mtr */
821
865
{
822
 
        fsp_init_file_page_low(page);
 
866
        fsp_init_file_page_low(block);
823
867
 
824
 
        mlog_write_initial_log_record(page, MLOG_INIT_FILE_PAGE, mtr);
 
868
        mlog_write_initial_log_record(buf_block_get_frame(block),
 
869
                                      MLOG_INIT_FILE_PAGE, mtr);
825
870
}
826
871
 
827
872
/***************************************************************
828
873
Parses a redo log record of a file page init. */
829
 
 
 
874
UNIV_INTERN
830
875
byte*
831
876
fsp_parse_init_file_page(
832
877
/*=====================*/
833
 
                        /* out: end of log record or NULL */
834
 
        byte*   ptr,    /* in: buffer */
835
 
        byte*   end_ptr __attribute__((unused)), /* in: buffer end */
836
 
        page_t* page)   /* in: page or NULL */
 
878
                                /* out: end of log record or NULL */
 
879
        byte*           ptr,    /* in: buffer */
 
880
        byte*           end_ptr __attribute__((unused)), /* in: buffer end */
 
881
        buf_block_t*    block)  /* in: block or NULL */
837
882
{
838
883
        ut_ad(ptr && end_ptr);
839
884
 
840
 
        if (page) {
841
 
                fsp_init_file_page_low(page);
 
885
        if (block) {
 
886
                fsp_init_file_page_low(block);
842
887
        }
843
888
 
844
889
        return(ptr);
846
891
 
847
892
/**************************************************************************
848
893
Initializes the fsp system. */
849
 
 
 
894
UNIV_INTERN
850
895
void
851
896
fsp_init(void)
852
897
/*==========*/
855
900
}
856
901
 
857
902
/**************************************************************************
858
 
Writes the space id to a tablespace header. This function is used past the
859
 
buffer pool when we in fil0fil.c create a new single-table tablespace. */
860
 
 
 
903
Writes the space id and compressed page size to a tablespace header.
 
904
This function is used past the buffer pool when we in fil0fil.c create
 
905
a new single-table tablespace. */
 
906
UNIV_INTERN
861
907
void
862
 
fsp_header_write_space_id(
863
 
/*======================*/
864
 
        page_t* page,           /* in: first page in the space */
865
 
        ulint   space_id)       /* in: space id */
 
908
fsp_header_init_fields(
 
909
/*===================*/
 
910
        page_t* page,           /* in/out: first page in the space */
 
911
        ulint   space_id,       /* in: space id */
 
912
        ulint   flags)          /* in: tablespace flags (FSP_SPACE_FLAGS):
 
913
                                0, or table->flags if newer than COMPACT */
866
914
{
867
 
        mach_write_to_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID, space_id);
 
915
        /* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
 
916
        ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
 
917
        ROW_FORMAT=REDUNDANT (table->flags == 0).  For any other
 
918
        format, the tablespace flags should equal table->flags. */
 
919
        ut_a(flags != DICT_TF_COMPACT);
 
920
 
 
921
        mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page,
 
922
                        space_id);
 
923
        mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page,
 
924
                        flags);
868
925
}
869
926
 
870
927
/**************************************************************************
871
928
Initializes the space header of a new created space and creates also the
872
929
insert buffer tree root if space == 0. */
873
 
 
 
930
UNIV_INTERN
874
931
void
875
932
fsp_header_init(
876
933
/*============*/
877
 
        ulint   space,  /* in: space id */
878
 
        ulint   size,   /* in: current size in blocks */
879
 
        mtr_t*  mtr)    /* in: mini-transaction handle */
 
934
        ulint   space,          /* in: space id */
 
935
        ulint   size,           /* in: current size in blocks */
 
936
        mtr_t*  mtr)            /* in: mini-transaction handle */
880
937
{
881
938
        fsp_header_t*   header;
 
939
        buf_block_t*    block;
882
940
        page_t*         page;
 
941
        ulint           flags;
 
942
        ulint           zip_size;
883
943
 
884
944
        ut_ad(mtr);
885
945
 
886
 
        mtr_x_lock(fil_space_get_latch(space), mtr);
 
946
        mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
887
947
 
888
 
        page = buf_page_create(space, 0, mtr);
889
 
        buf_page_get(space, 0, RW_X_LATCH, mtr);
 
948
        zip_size = dict_table_flags_to_zip_size(flags);
 
949
        block = buf_page_create(space, 0, zip_size, mtr);
 
950
        buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
890
951
#ifdef UNIV_SYNC_DEBUG
891
 
        buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
 
952
        buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
892
953
#endif /* UNIV_SYNC_DEBUG */
893
954
 
894
955
        /* The prior contents of the file page should be ignored */
895
956
 
896
 
        fsp_init_file_page(page, mtr);
 
957
        fsp_init_file_page(block, mtr);
 
958
        page = buf_block_get_frame(block);
897
959
 
898
960
        mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_FSP_HDR,
899
961
                         MLOG_2BYTES, mtr);
905
967
 
906
968
        mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr);
907
969
        mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr);
908
 
        mlog_write_ulint(header + FSP_LOWEST_NO_WRITE, 0, MLOG_4BYTES, mtr);
 
970
        mlog_write_ulint(header + FSP_SPACE_FLAGS, flags,
 
971
                         MLOG_4BYTES, mtr);
909
972
        mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr);
910
973
 
911
974
        flst_init(header + FSP_FREE, mtr);
917
980
        mlog_write_dulint(header + FSP_SEG_ID, ut_dulint_create(0, 1), mtr);
918
981
        if (space == 0) {
919
982
                fsp_fill_free_list(FALSE, space, header, mtr);
920
 
                btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, space,
921
 
                           ut_dulint_add(DICT_IBUF_ID_MIN, space), FALSE, mtr);
 
983
                btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
 
984
                           0, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
 
985
                           srv_sys->dummy_ind1, mtr);
922
986
        } else {
923
987
                fsp_fill_free_list(TRUE, space, header, mtr);
924
988
        }
926
990
 
927
991
/**************************************************************************
928
992
Reads the space id from the first page of a tablespace. */
929
 
 
 
993
UNIV_INTERN
930
994
ulint
931
995
fsp_header_get_space_id(
932
996
/*====================*/
933
 
                        /* out: space id, ULINT UNDEFINED if error */
934
 
        page_t* page)   /* in: first page of a tablespace */
 
997
                                /* out: space id, ULINT UNDEFINED if error */
 
998
        const page_t*   page)   /* in: first page of a tablespace */
935
999
{
936
1000
        ulint   fsp_id;
937
1001
        ulint   id;
953
1017
}
954
1018
 
955
1019
/**************************************************************************
 
1020
Reads the space flags from the first page of a tablespace. */
 
1021
UNIV_INTERN
 
1022
ulint
 
1023
fsp_header_get_flags(
 
1024
/*=================*/
 
1025
                                /* out: flags */
 
1026
        const page_t*   page)   /* in: first page of a tablespace */
 
1027
{
 
1028
        ut_ad(!page_offset(page));
 
1029
 
 
1030
        return(mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page));
 
1031
}
 
1032
 
 
1033
/**************************************************************************
 
1034
Reads the compressed page size from the first page of a tablespace. */
 
1035
UNIV_INTERN
 
1036
ulint
 
1037
fsp_header_get_zip_size(
 
1038
/*====================*/
 
1039
                                /* out: compressed page size in bytes,
 
1040
                                or 0 if uncompressed */
 
1041
        const page_t*   page)   /* in: first page of a tablespace */
 
1042
{
 
1043
        ulint   flags = fsp_header_get_flags(page);
 
1044
 
 
1045
        return(dict_table_flags_to_zip_size(flags));
 
1046
}
 
1047
 
 
1048
/**************************************************************************
956
1049
Increases the space size field of a space. */
957
 
 
 
1050
UNIV_INTERN
958
1051
void
959
1052
fsp_header_inc_size(
960
1053
/*================*/
964
1057
{
965
1058
        fsp_header_t*   header;
966
1059
        ulint           size;
 
1060
        ulint           flags;
967
1061
 
968
1062
        ut_ad(mtr);
969
1063
 
970
 
        mtr_x_lock(fil_space_get_latch(space), mtr);
 
1064
        mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
971
1065
 
972
 
        header = fsp_get_space_header(space, mtr);
 
1066
        header = fsp_get_space_header(space,
 
1067
                                      dict_table_flags_to_zip_size(flags),
 
1068
                                      mtr);
973
1069
 
974
1070
        size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
975
1071
 
978
1074
}
979
1075
 
980
1076
/**************************************************************************
981
 
Gets the current free limit of a tablespace. The free limit means the
982
 
place of the first page which has never been put to the the free list
983
 
for allocation. The space above that address is initialized to zero.
984
 
Sets also the global variable log_fsp_current_free_limit. */
985
 
 
 
1077
Gets the current free limit of the system tablespace.  The free limit
 
1078
means the place of the first page which has never been put to the the
 
1079
free list for allocation.  The space above that address is initialized
 
1080
to zero.  Sets also the global variable log_fsp_current_free_limit. */
 
1081
UNIV_INTERN
986
1082
ulint
987
 
fsp_header_get_free_limit(
988
 
/*======================*/
 
1083
fsp_header_get_free_limit(void)
 
1084
/*===========================*/
989
1085
                        /* out: free limit in megabytes */
990
 
        ulint   space)  /* in: space id, must be 0 */
991
1086
{
992
1087
        fsp_header_t*   header;
993
1088
        ulint           limit;
994
1089
        mtr_t           mtr;
995
1090
 
996
 
        ut_a(space == 0); /* We have only one log_fsp_current_... variable */
997
 
 
998
1091
        mtr_start(&mtr);
999
1092
 
1000
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
1093
        mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
1001
1094
 
1002
 
        header = fsp_get_space_header(space, &mtr);
 
1095
        header = fsp_get_space_header(0, 0, &mtr);
1003
1096
 
1004
1097
        limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, &mtr);
1005
1098
 
1006
 
        limit = limit / ((1024 * 1024) / UNIV_PAGE_SIZE);
 
1099
        limit /= ((1024 * 1024) / UNIV_PAGE_SIZE);
1007
1100
 
1008
1101
        log_fsp_current_free_limit_set_and_checkpoint(limit);
1009
1102
 
1013
1106
}
1014
1107
 
1015
1108
/**************************************************************************
1016
 
Gets the size of the tablespace from the tablespace header. If we do not
1017
 
have an auto-extending data file, this should be equal to the size of the
1018
 
data files. If there is an auto-extending data file, this can be smaller. */
1019
 
 
 
1109
Gets the size of the system tablespace from the tablespace header.  If
 
1110
we do not have an auto-extending data file, this should be equal to
 
1111
the size of the data files.  If there is an auto-extending data file,
 
1112
this can be smaller. */
 
1113
UNIV_INTERN
1020
1114
ulint
1021
 
fsp_header_get_tablespace_size(
1022
 
/*===========================*/
 
1115
fsp_header_get_tablespace_size(void)
 
1116
/*================================*/
1023
1117
                        /* out: size in pages */
1024
 
        ulint   space)  /* in: space id, must be 0 */
1025
1118
{
1026
1119
        fsp_header_t*   header;
1027
1120
        ulint           size;
1028
1121
        mtr_t           mtr;
1029
1122
 
1030
 
        ut_a(space == 0); /* We have only one log_fsp_current_... variable */
1031
 
 
1032
1123
        mtr_start(&mtr);
1033
1124
 
1034
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
1125
        mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
1035
1126
 
1036
 
        header = fsp_get_space_header(space, &mtr);
 
1127
        header = fsp_get_space_header(0, 0, &mtr);
1037
1128
 
1038
1129
        size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr);
1039
1130
 
1092
1183
        mtr_t*          mtr)            /* in: mtr */
1093
1184
{
1094
1185
        ulint   size;
 
1186
        ulint   zip_size;
1095
1187
        ulint   new_size;
1096
1188
        ulint   old_size;
1097
1189
        ulint   size_increase;
1106
1198
        }
1107
1199
 
1108
1200
        size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
 
1201
        zip_size = dict_table_flags_to_zip_size(
 
1202
                mach_read_from_4(header + FSP_SPACE_FLAGS));
1109
1203
 
1110
1204
        old_size = size;
1111
1205
 
1112
 
        if (space == 0 && srv_last_file_size_max != 0) {
1113
 
                if (srv_last_file_size_max
1114
 
                    < srv_data_file_sizes[srv_n_data_files - 1]) {
1115
 
 
1116
 
                        fprintf(stderr,
1117
 
                                "InnoDB: Error: Last data file size is %lu,"
1118
 
                                " max size allowed %lu\n",
1119
 
                                (ulong) srv_data_file_sizes[
1120
 
                                        srv_n_data_files - 1],
1121
 
                                (ulong) srv_last_file_size_max);
1122
 
                }
1123
 
 
1124
 
                size_increase = srv_last_file_size_max
1125
 
                        - srv_data_file_sizes[srv_n_data_files - 1];
1126
 
                if (size_increase > SRV_AUTO_EXTEND_INCREMENT) {
 
1206
        if (space == 0) {
 
1207
                if (!srv_last_file_size_max) {
1127
1208
                        size_increase = SRV_AUTO_EXTEND_INCREMENT;
 
1209
                } else {
 
1210
                        if (srv_last_file_size_max
 
1211
                            < srv_data_file_sizes[srv_n_data_files - 1]) {
 
1212
 
 
1213
                                fprintf(stderr,
 
1214
                                        "InnoDB: Error: Last data file size"
 
1215
                                        " is %lu, max size allowed %lu\n",
 
1216
                                        (ulong) srv_data_file_sizes[
 
1217
                                                srv_n_data_files - 1],
 
1218
                                        (ulong) srv_last_file_size_max);
 
1219
                        }
 
1220
 
 
1221
                        size_increase = srv_last_file_size_max
 
1222
                                - srv_data_file_sizes[srv_n_data_files - 1];
 
1223
                        if (size_increase > SRV_AUTO_EXTEND_INCREMENT) {
 
1224
                                size_increase = SRV_AUTO_EXTEND_INCREMENT;
 
1225
                        }
1128
1226
                }
1129
1227
        } else {
1130
 
                if (space == 0) {
1131
 
                        size_increase = SRV_AUTO_EXTEND_INCREMENT;
1132
 
                } else {
1133
 
                        /* We extend single-table tablespaces first one extent
1134
 
                        at a time, but for bigger tablespaces more. It is not
1135
 
                        enough to extend always by one extent, because some
1136
 
                        extents are frag page extents. */
1137
 
 
1138
 
                        if (size < FSP_EXTENT_SIZE) {
1139
 
                                /* Let us first extend the file to 64 pages */
1140
 
                                success = fsp_try_extend_data_file_with_pages(
1141
 
                                        space, FSP_EXTENT_SIZE - 1,
1142
 
                                        header, mtr);
1143
 
                                if (!success) {
1144
 
                                        new_size = mtr_read_ulint(
1145
 
                                                header + FSP_SIZE,
1146
 
                                                MLOG_4BYTES, mtr);
1147
 
 
1148
 
                                        *actual_increase = new_size - old_size;
1149
 
 
1150
 
                                        return(FALSE);
1151
 
                                }
1152
 
 
1153
 
                                size = FSP_EXTENT_SIZE;
1154
 
                        }
1155
 
 
1156
 
                        if (size < 32 * FSP_EXTENT_SIZE) {
1157
 
                                size_increase = FSP_EXTENT_SIZE;
1158
 
                        } else {
1159
 
                                /* Below in fsp_fill_free_list() we assume
1160
 
                                that we add at most FSP_FREE_ADD extents at
1161
 
                                a time */
1162
 
                                size_increase = FSP_FREE_ADD * FSP_EXTENT_SIZE;
1163
 
                        }
 
1228
                /* We extend single-table tablespaces first one extent
 
1229
                at a time, but for bigger tablespaces more. It is not
 
1230
                enough to extend always by one extent, because some
 
1231
                extents are frag page extents. */
 
1232
                ulint   extent_size;    /* one megabyte, in pages */
 
1233
 
 
1234
                if (!zip_size) {
 
1235
                        extent_size = FSP_EXTENT_SIZE;
 
1236
                } else {
 
1237
                        extent_size = FSP_EXTENT_SIZE
 
1238
                                * UNIV_PAGE_SIZE / zip_size;
 
1239
                }
 
1240
 
 
1241
                if (size < extent_size) {
 
1242
                        /* Let us first extend the file to extent_size */
 
1243
                        success = fsp_try_extend_data_file_with_pages(
 
1244
                                space, extent_size - 1, header, mtr);
 
1245
                        if (!success) {
 
1246
                                new_size = mtr_read_ulint(header + FSP_SIZE,
 
1247
                                                          MLOG_4BYTES, mtr);
 
1248
 
 
1249
                                *actual_increase = new_size - old_size;
 
1250
 
 
1251
                                return(FALSE);
 
1252
                        }
 
1253
 
 
1254
                        size = extent_size;
 
1255
                }
 
1256
 
 
1257
                if (size < 32 * extent_size) {
 
1258
                        size_increase = extent_size;
 
1259
                } else {
 
1260
                        /* Below in fsp_fill_free_list() we assume
 
1261
                        that we add at most FSP_FREE_ADD extents at
 
1262
                        a time */
 
1263
                        size_increase = FSP_FREE_ADD * extent_size;
1164
1264
                }
1165
1265
        }
1166
1266
 
1174
1274
        /* We ignore any fragments of a full megabyte when storing the size
1175
1275
        to the space header */
1176
1276
 
1177
 
        mlog_write_ulint(header + FSP_SIZE,
1178
 
                         ut_calc_align_down(actual_size,
1179
 
                                            (1024 * 1024) / UNIV_PAGE_SIZE),
1180
 
                         MLOG_4BYTES, mtr);
1181
 
        new_size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
 
1277
        if (!zip_size) {
 
1278
                new_size = ut_calc_align_down(actual_size,
 
1279
                                              (1024 * 1024) / UNIV_PAGE_SIZE);
 
1280
        } else {
 
1281
                new_size = ut_calc_align_down(actual_size,
 
1282
                                              (1024 * 1024) / zip_size);
 
1283
        }
 
1284
        mlog_write_ulint(header + FSP_SIZE, new_size, MLOG_4BYTES, mtr);
1182
1285
 
1183
1286
        *actual_increase = new_size - old_size;
1184
1287
 
1204
1307
{
1205
1308
        ulint   limit;
1206
1309
        ulint   size;
 
1310
        ulint   zip_size;
1207
1311
        xdes_t* descr;
1208
1312
        ulint   count           = 0;
1209
1313
        ulint   frag_n_used;
1210
 
        page_t* descr_page;
1211
 
        page_t* ibuf_page;
1212
1314
        ulint   actual_increase;
1213
1315
        ulint   i;
1214
1316
        mtr_t   ibuf_mtr;
1219
1321
        size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
1220
1322
        limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr);
1221
1323
 
 
1324
        zip_size = dict_table_flags_to_zip_size(
 
1325
                mach_read_from_4(FSP_SPACE_FLAGS + header));
 
1326
        ut_a(ut_is_2pow(zip_size));
 
1327
        ut_a(zip_size <= UNIV_PAGE_SIZE);
 
1328
        ut_a(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE);
 
1329
 
1222
1330
        if (space == 0 && srv_auto_extend_last_data_file
1223
1331
            && size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {
1224
1332
 
1240
1348
        while ((init_space && i < 1)
1241
1349
               || ((i + FSP_EXTENT_SIZE <= size) && (count < FSP_FREE_ADD))) {
1242
1350
 
 
1351
                ibool   init_xdes;
 
1352
                if (zip_size) {
 
1353
                        init_xdes = ut_2pow_remainder(i, zip_size) == 0;
 
1354
                } else {
 
1355
                        init_xdes = ut_2pow_remainder(i, UNIV_PAGE_SIZE) == 0;
 
1356
                }
 
1357
 
1243
1358
                mlog_write_ulint(header + FSP_FREE_LIMIT, i + FSP_EXTENT_SIZE,
1244
1359
                                 MLOG_4BYTES, mtr);
1245
1360
 
1246
1361
                /* Update the free limit info in the log system and make
1247
1362
                a checkpoint */
1248
1363
                if (space == 0) {
 
1364
                        ut_a(!zip_size);
1249
1365
                        log_fsp_current_free_limit_set_and_checkpoint(
1250
1366
                                (i + FSP_EXTENT_SIZE)
1251
1367
                                / ((1024 * 1024) / UNIV_PAGE_SIZE));
1252
1368
                }
1253
1369
 
1254
 
                if (0 == i % XDES_DESCRIBED_PER_PAGE) {
 
1370
                if (UNIV_UNLIKELY(init_xdes)) {
 
1371
 
 
1372
                        buf_block_t*    block;
1255
1373
 
1256
1374
                        /* We are going to initialize a new descriptor page
1257
1375
                        and a new ibuf bitmap page: the prior contents of the
1258
1376
                        pages should be ignored. */
1259
1377
 
1260
1378
                        if (i > 0) {
1261
 
                                descr_page = buf_page_create(space, i, mtr);
1262
 
                                buf_page_get(space, i, RW_X_LATCH, mtr);
 
1379
                                block = buf_page_create(
 
1380
                                        space, i, zip_size, mtr);
 
1381
                                buf_page_get(space, zip_size, i,
 
1382
                                             RW_X_LATCH, mtr);
1263
1383
#ifdef UNIV_SYNC_DEBUG
1264
 
                                buf_page_dbg_add_level(descr_page,
1265
 
                                                       SYNC_FSP_PAGE);
 
1384
                                buf_block_dbg_add_level(block,
 
1385
                                                        SYNC_FSP_PAGE);
1266
1386
#endif /* UNIV_SYNC_DEBUG */
1267
 
                                fsp_init_file_page(descr_page, mtr);
1268
 
                                mlog_write_ulint(descr_page + FIL_PAGE_TYPE,
 
1387
                                fsp_init_file_page(block, mtr);
 
1388
                                mlog_write_ulint(buf_block_get_frame(block)
 
1389
                                                 + FIL_PAGE_TYPE,
1269
1390
                                                 FIL_PAGE_TYPE_XDES,
1270
1391
                                                 MLOG_2BYTES, mtr);
1271
1392
                        }
1277
1398
 
1278
1399
                        mtr_start(&ibuf_mtr);
1279
1400
 
1280
 
                        ibuf_page = buf_page_create(space,
 
1401
                        block = buf_page_create(space,
1281
1402
                                                    i + FSP_IBUF_BITMAP_OFFSET,
1282
 
                                                    &ibuf_mtr);
1283
 
                        buf_page_get(space, i + FSP_IBUF_BITMAP_OFFSET,
 
1403
                                                    zip_size, &ibuf_mtr);
 
1404
                        buf_page_get(space, zip_size,
 
1405
                                     i + FSP_IBUF_BITMAP_OFFSET,
1284
1406
                                     RW_X_LATCH, &ibuf_mtr);
1285
1407
#ifdef UNIV_SYNC_DEBUG
1286
 
                        buf_page_dbg_add_level(ibuf_page, SYNC_FSP_PAGE);
 
1408
                        buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1287
1409
#endif /* UNIV_SYNC_DEBUG */
1288
 
                        fsp_init_file_page(ibuf_page, &ibuf_mtr);
 
1410
                        fsp_init_file_page(block, &ibuf_mtr);
1289
1411
 
1290
 
                        ibuf_bitmap_page_init(ibuf_page, &ibuf_mtr);
 
1412
                        ibuf_bitmap_page_init(block, &ibuf_mtr);
1291
1413
 
1292
1414
                        mtr_commit(&ibuf_mtr);
1293
1415
                }
1296
1418
                                                           mtr);
1297
1419
                xdes_init(descr, mtr);
1298
1420
 
1299
 
#if XDES_DESCRIBED_PER_PAGE % FSP_EXTENT_SIZE
1300
 
# error "XDES_DESCRIBED_PER_PAGE % FSP_EXTENT_SIZE != 0"
 
1421
#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
 
1422
# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
 
1423
#endif
 
1424
#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
 
1425
# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
1301
1426
#endif
1302
1427
 
1303
 
                if (0 == i % XDES_DESCRIBED_PER_PAGE) {
 
1428
                if (UNIV_UNLIKELY(init_xdes)) {
1304
1429
 
1305
1430
                        /* The first page in the extent is a descriptor page
1306
1431
                        and the second is an ibuf bitmap page: mark them
1336
1461
                        /* out: extent descriptor, NULL if cannot be
1337
1462
                        allocated */
1338
1463
        ulint   space,  /* in: space id */
 
1464
        ulint   zip_size,/* in: compressed page size in bytes
 
1465
                        or 0 for uncompressed pages */
1339
1466
        ulint   hint,   /* in: hint of which extent would be desirable: any
1340
1467
                        page offset in the extent goes; the hint must not
1341
1468
                        be > FSP_FREE_LIMIT */
1347
1474
 
1348
1475
        ut_ad(mtr);
1349
1476
 
1350
 
        header = fsp_get_space_header(space, mtr);
 
1477
        header = fsp_get_space_header(space, zip_size, mtr);
1351
1478
 
1352
1479
        descr = xdes_get_descriptor_with_space_hdr(header, space, hint, mtr);
1353
1480
 
1368
1495
                        return(NULL);   /* No free extents left */
1369
1496
                }
1370
1497
 
1371
 
                descr = xdes_lst_get_descriptor(space, first, mtr);
 
1498
                descr = xdes_lst_get_descriptor(space, zip_size, first, mtr);
1372
1499
        }
1373
1500
 
1374
1501
        flst_remove(header + FSP_FREE, descr + XDES_FLST_NODE, mtr);
1385
1512
                        /* out: the page offset, FIL_NULL if no page could
1386
1513
                        be allocated */
1387
1514
        ulint   space,  /* in: space id */
 
1515
        ulint   zip_size,/* in: compressed page size in bytes
 
1516
                        or 0 for uncompressed pages */
1388
1517
        ulint   hint,   /* in: hint of which page would be desirable */
1389
1518
        mtr_t*  mtr)    /* in: mtr handle */
1390
1519
{
1391
1520
        fsp_header_t*   header;
1392
1521
        fil_addr_t      first;
1393
1522
        xdes_t*         descr;
1394
 
        page_t*         page;
 
1523
        buf_block_t*    block;
1395
1524
        ulint           free;
1396
1525
        ulint           frag_n_used;
1397
1526
        ulint           page_no;
1400
1529
 
1401
1530
        ut_ad(mtr);
1402
1531
 
1403
 
        header = fsp_get_space_header(space, mtr);
 
1532
        header = fsp_get_space_header(space, zip_size, mtr);
1404
1533
 
1405
1534
        /* Get the hinted descriptor */
1406
1535
        descr = xdes_get_descriptor_with_space_hdr(header, space, hint, mtr);
1419
1548
                        FREE_FRAG list. But we will allocate our page from the
1420
1549
                        the free extent anyway. */
1421
1550
 
1422
 
                        descr = fsp_alloc_free_extent(space, hint, mtr);
 
1551
                        descr = fsp_alloc_free_extent(space, zip_size,
 
1552
                                                      hint, mtr);
1423
1553
 
1424
1554
                        if (descr == NULL) {
1425
1555
                                /* No free space left */
1431
1561
                        flst_add_last(header + FSP_FREE_FRAG,
1432
1562
                                      descr + XDES_FLST_NODE, mtr);
1433
1563
                } else {
1434
 
                        descr = xdes_lst_get_descriptor(space, first, mtr);
 
1564
                        descr = xdes_lst_get_descriptor(space, zip_size,
 
1565
                                                        first, mtr);
1435
1566
                }
1436
1567
 
1437
1568
                /* Reset the hint */
1502
1633
        be obtained immediately with buf_page_get without need for a disk
1503
1634
        read. */
1504
1635
 
1505
 
        buf_page_create(space, page_no, mtr);
 
1636
        buf_page_create(space, page_no, zip_size, mtr);
1506
1637
 
1507
 
        page = buf_page_get(space, page_no, RW_X_LATCH, mtr);
 
1638
        block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
1508
1639
#ifdef UNIV_SYNC_DEBUG
1509
 
        buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
 
1640
        buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1510
1641
#endif /* UNIV_SYNC_DEBUG */
1511
1642
 
1512
1643
        /* Prior contents of the page should be ignored */
1513
 
        fsp_init_file_page(page, mtr);
 
1644
        fsp_init_file_page(block, mtr);
1514
1645
 
1515
1646
        return(page_no);
1516
1647
}
1522
1653
fsp_free_page(
1523
1654
/*==========*/
1524
1655
        ulint   space,  /* in: space id */
 
1656
        ulint   zip_size,/* in: compressed page size in bytes
 
1657
                        or 0 for uncompressed pages */
1525
1658
        ulint   page,   /* in: page offset */
1526
1659
        mtr_t*  mtr)    /* in: mtr handle */
1527
1660
{
1534
1667
 
1535
1668
        /* fprintf(stderr, "Freeing page %lu in space %lu\n", page, space); */
1536
1669
 
1537
 
        header = fsp_get_space_header(space, mtr);
 
1670
        header = fsp_get_space_header(space, zip_size, mtr);
1538
1671
 
1539
1672
        descr = xdes_get_descriptor_with_space_hdr(header, space, page, mtr);
1540
1673
 
1599
1732
                /* The extent has become free: move it to another list */
1600
1733
                flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE,
1601
1734
                            mtr);
1602
 
                fsp_free_extent(space, page, mtr);
 
1735
                fsp_free_extent(space, zip_size, page, mtr);
1603
1736
        }
1604
1737
}
1605
1738
 
1610
1743
fsp_free_extent(
1611
1744
/*============*/
1612
1745
        ulint   space,  /* in: space id */
 
1746
        ulint   zip_size,/* in: compressed page size in bytes
 
1747
                        or 0 for uncompressed pages */
1613
1748
        ulint   page,   /* in: page offset in the extent */
1614
1749
        mtr_t*  mtr)    /* in: mtr */
1615
1750
{
1618
1753
 
1619
1754
        ut_ad(mtr);
1620
1755
 
1621
 
        header = fsp_get_space_header(space, mtr);
 
1756
        header = fsp_get_space_header(space, zip_size, mtr);
1622
1757
 
1623
1758
        descr = xdes_get_descriptor_with_space_hdr(header, space, page, mtr);
1624
1759
 
1643
1778
                        /* out: segment inode */
1644
1779
        page_t* page,   /* in: segment inode page */
1645
1780
        ulint   i,      /* in: inode index on page */
1646
 
        mtr_t*  mtr __attribute__((unused))) /* in: mini-transaction handle */
 
1781
        ulint   zip_size __attribute__((unused)),
 
1782
                        /* in: compressed page size, or 0 */
 
1783
        mtr_t*  mtr __attribute__((unused)))
 
1784
                        /* in: mini-transaction handle */
1647
1785
{
1648
 
        ut_ad(i < FSP_SEG_INODES_PER_PAGE);
1649
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
1650
 
                                MTR_MEMO_PAGE_X_FIX));
 
1786
        ut_ad(i < FSP_SEG_INODES_PER_PAGE(zip_size));
 
1787
        ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
1651
1788
 
1652
1789
        return(page + FSEG_ARR_OFFSET + FSEG_INODE_SIZE * i);
1653
1790
}
1661
1798
                        /* out: segment inode index, or ULINT_UNDEFINED
1662
1799
                        if not found */
1663
1800
        page_t* page,   /* in: segment inode page */
 
1801
        ulint   zip_size,/* in: compressed page size, or 0 */
1664
1802
        mtr_t*  mtr)    /* in: mini-transaction handle */
1665
1803
{
1666
1804
        ulint           i;
1667
1805
        fseg_inode_t*   inode;
1668
1806
 
1669
 
        for (i = 0; i < FSP_SEG_INODES_PER_PAGE; i++) {
1670
 
 
1671
 
                inode = fsp_seg_inode_page_get_nth_inode(page, i, mtr);
1672
 
 
1673
 
                if (ut_dulint_cmp(mach_read_from_8(inode + FSEG_ID),
1674
 
                                  ut_dulint_zero) != 0) {
 
1807
        for (i = 0; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
 
1808
 
 
1809
                inode = fsp_seg_inode_page_get_nth_inode(
 
1810
                        page, i, zip_size, mtr);
 
1811
 
 
1812
                if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
1675
1813
                        /* This is used */
1676
1814
 
1677
1815
                        return(i);
1690
1828
                        /* out: segment inode index, or ULINT_UNDEFINED
1691
1829
                        if not found */
1692
1830
        page_t* page,   /* in: segment inode page */
1693
 
        ulint   j,      /* in: search forward starting from this index */
 
1831
        ulint   i,      /* in: search forward starting from this index */
 
1832
        ulint   zip_size,/* in: compressed page size, or 0 */
1694
1833
        mtr_t*  mtr)    /* in: mini-transaction handle */
1695
1834
{
1696
 
        ulint           i;
1697
1835
        fseg_inode_t*   inode;
1698
1836
 
1699
 
        for (i = j; i < FSP_SEG_INODES_PER_PAGE; i++) {
1700
 
 
1701
 
                inode = fsp_seg_inode_page_get_nth_inode(page, i, mtr);
1702
 
 
1703
 
                if (ut_dulint_cmp(mach_read_from_8(inode + FSEG_ID),
1704
 
                                  ut_dulint_zero) == 0) {
 
1837
        for (; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
 
1838
 
 
1839
                inode = fsp_seg_inode_page_get_nth_inode(
 
1840
                        page, i, zip_size, mtr);
 
1841
 
 
1842
                if (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
1705
1843
                        /* This is unused */
1706
1844
 
1707
1845
                        return(i);
1722
1860
        mtr_t*          mtr)            /* in: mini-transaction handle */
1723
1861
{
1724
1862
        fseg_inode_t*   inode;
 
1863
        buf_block_t*    block;
1725
1864
        page_t*         page;
1726
1865
        ulint           page_no;
1727
1866
        ulint           space;
 
1867
        ulint           zip_size;
1728
1868
        ulint           i;
1729
1869
 
1730
 
        space = buf_frame_get_space_id(space_header);
 
1870
        space = page_get_space_id(page_align(space_header));
 
1871
        zip_size = dict_table_flags_to_zip_size(
 
1872
                mach_read_from_4(FSP_SPACE_FLAGS + space_header));
1731
1873
 
1732
 
        page_no = fsp_alloc_free_page(space, 0, mtr);
 
1874
        page_no = fsp_alloc_free_page(space, zip_size, 0, mtr);
1733
1875
 
1734
1876
        if (page_no == FIL_NULL) {
1735
1877
 
1736
1878
                return(FALSE);
1737
1879
        }
1738
1880
 
1739
 
        page = buf_page_get(space, page_no, RW_X_LATCH, mtr);
1740
 
 
1741
 
        buf_block_align(page)->check_index_page_at_flush = FALSE;
 
1881
        block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
 
1882
#ifdef UNIV_SYNC_DEBUG
 
1883
        buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
 
1884
#endif /* UNIV_SYNC_DEBUG */
 
1885
 
 
1886
        block->check_index_page_at_flush = FALSE;
 
1887
 
 
1888
        page = buf_block_get_frame(block);
1742
1889
 
1743
1890
        mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_INODE,
1744
1891
                         MLOG_2BYTES, mtr);
1745
 
#ifdef UNIV_SYNC_DEBUG
1746
 
        buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
1747
 
#endif /* UNIV_SYNC_DEBUG */
1748
 
 
1749
 
        for (i = 0; i < FSP_SEG_INODES_PER_PAGE; i++) {
1750
 
 
1751
 
                inode = fsp_seg_inode_page_get_nth_inode(page, i, mtr);
 
1892
 
 
1893
        for (i = 0; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
 
1894
 
 
1895
                inode = fsp_seg_inode_page_get_nth_inode(page, i,
 
1896
                                                         zip_size, mtr);
1752
1897
 
1753
1898
                mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
1754
1899
        }
1770
1915
        mtr_t*          mtr)            /* in: mini-transaction handle */
1771
1916
{
1772
1917
        ulint           page_no;
 
1918
        buf_block_t*    block;
1773
1919
        page_t*         page;
1774
1920
        fseg_inode_t*   inode;
1775
1921
        ibool           success;
 
1922
        ulint           zip_size;
1776
1923
        ulint           n;
1777
1924
 
1778
1925
        if (flst_get_len(space_header + FSP_SEG_INODES_FREE, mtr) == 0) {
1788
1935
 
1789
1936
        page_no = flst_get_first(space_header + FSP_SEG_INODES_FREE, mtr).page;
1790
1937
 
1791
 
        page = buf_page_get(buf_frame_get_space_id(space_header), page_no,
1792
 
                            RW_X_LATCH, mtr);
 
1938
        zip_size = dict_table_flags_to_zip_size(
 
1939
                mach_read_from_4(FSP_SPACE_FLAGS + space_header));
 
1940
        block = buf_page_get(page_get_space_id(page_align(space_header)),
 
1941
                             zip_size, page_no, RW_X_LATCH, mtr);
1793
1942
#ifdef UNIV_SYNC_DEBUG
1794
 
        buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
 
1943
        buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1795
1944
#endif /* UNIV_SYNC_DEBUG */
 
1945
        page = buf_block_get_frame(block);
1796
1946
 
1797
 
        n = fsp_seg_inode_page_find_free(page, 0, mtr);
 
1947
        n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr);
1798
1948
 
1799
1949
        ut_a(n != ULINT_UNDEFINED);
1800
1950
 
1801
 
        inode = fsp_seg_inode_page_get_nth_inode(page, n, mtr);
 
1951
        inode = fsp_seg_inode_page_get_nth_inode(page, n, zip_size, mtr);
1802
1952
 
1803
1953
        if (ULINT_UNDEFINED == fsp_seg_inode_page_find_free(page, n + 1,
1804
 
                                                            mtr)) {
 
1954
                                                            zip_size, mtr)) {
1805
1955
                /* There are no other unused headers left on the page: move it
1806
1956
                to another list */
1807
1957
 
1822
1972
fsp_free_seg_inode(
1823
1973
/*===============*/
1824
1974
        ulint           space,  /* in: space id */
 
1975
        ulint           zip_size,/* in: compressed page size in bytes
 
1976
                                or 0 for uncompressed pages */
1825
1977
        fseg_inode_t*   inode,  /* in: segment inode */
1826
1978
        mtr_t*          mtr)    /* in: mini-transaction handle */
1827
1979
{
1828
1980
        page_t*         page;
1829
1981
        fsp_header_t*   space_header;
1830
1982
 
1831
 
        page = buf_frame_align(inode);
 
1983
        page = page_align(inode);
1832
1984
 
1833
 
        space_header = fsp_get_space_header(space, mtr);
 
1985
        space_header = fsp_get_space_header(space, zip_size, mtr);
1834
1986
 
1835
1987
        ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
1836
1988
 
1837
 
        if (ULINT_UNDEFINED == fsp_seg_inode_page_find_free(page, 0, mtr)) {
 
1989
        if (ULINT_UNDEFINED
 
1990
            == fsp_seg_inode_page_find_free(page, 0, zip_size, mtr)) {
1838
1991
 
1839
1992
                /* Move the page to another list */
1840
1993
 
1848
2001
        mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
1849
2002
        mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
1850
2003
 
1851
 
        if (ULINT_UNDEFINED == fsp_seg_inode_page_find_used(page, mtr)) {
 
2004
        if (ULINT_UNDEFINED
 
2005
            == fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
1852
2006
 
1853
2007
                /* There are no other used headers left on the page: free it */
1854
2008
 
1855
2009
                flst_remove(space_header + FSP_SEG_INODES_FREE,
1856
2010
                            page + FSEG_INODE_PAGE_NODE, mtr);
1857
2011
 
1858
 
                fsp_free_page(space, buf_frame_get_page_no(page), mtr);
 
2012
                fsp_free_page(space, zip_size, page_get_page_no(page), mtr);
1859
2013
        }
1860
2014
}
1861
2015
 
1867
2021
/*===========*/
1868
2022
                                /* out: segment inode, page x-latched */
1869
2023
        fseg_header_t*  header, /* in: segment header */
 
2024
        ulint           space,  /* in: space id */
 
2025
        ulint           zip_size,/* in: compressed page size in bytes
 
2026
                                or 0 for uncompressed pages */
1870
2027
        mtr_t*          mtr)    /* in: mtr handle */
1871
2028
{
1872
2029
        fil_addr_t      inode_addr;
1874
2031
 
1875
2032
        inode_addr.page = mach_read_from_4(header + FSEG_HDR_PAGE_NO);
1876
2033
        inode_addr.boffset = mach_read_from_2(header + FSEG_HDR_OFFSET);
 
2034
        ut_ad(space == mach_read_from_4(header + FSEG_HDR_SPACE));
1877
2035
 
1878
 
        inode = fut_get_ptr(mach_read_from_4(header + FSEG_HDR_SPACE),
1879
 
                            inode_addr, RW_X_LATCH, mtr);
 
2036
        inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
1880
2037
 
1881
2038
        ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
1882
2039
 
1896
2053
{
1897
2054
        ut_ad(inode && mtr);
1898
2055
        ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
1899
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(inode),
1900
 
                                MTR_MEMO_PAGE_X_FIX));
 
2056
        ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
1901
2057
        return(mach_read_from_4(inode + FSEG_FRAG_ARR
1902
2058
                                + n * FSEG_FRAG_SLOT_SIZE));
1903
2059
}
1915
2071
{
1916
2072
        ut_ad(inode && mtr);
1917
2073
        ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
1918
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(inode),
1919
 
                                MTR_MEMO_PAGE_X_FIX));
 
2074
        ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
1920
2075
 
1921
2076
        mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
1922
2077
                         page_no, MLOG_4BYTES, mtr);
2005
2160
 
2006
2161
/**************************************************************************
2007
2162
Creates a new segment. */
2008
 
 
2009
 
page_t*
 
2163
UNIV_INTERN
 
2164
buf_block_t*
2010
2165
fseg_create_general(
2011
2166
/*================*/
2012
 
                        /* out: the page where the segment header is placed,
 
2167
                        /* out: the block where the segment header is placed,
2013
2168
                        x-latched, NULL if could not create segment
2014
2169
                        because of lack of space */
2015
2170
        ulint   space,  /* in: space id */
2027
2182
                        operation */
2028
2183
        mtr_t*  mtr)    /* in: mtr */
2029
2184
{
 
2185
        ulint           flags;
 
2186
        ulint           zip_size;
2030
2187
        fsp_header_t*   space_header;
2031
2188
        fseg_inode_t*   inode;
2032
2189
        dulint          seg_id;
2033
 
        fseg_header_t*  header = 0; /* remove warning */
 
2190
        buf_block_t*    block   = 0; /* remove warning */
 
2191
        fseg_header_t*  header  = 0; /* remove warning */
2034
2192
        rw_lock_t*      latch;
2035
2193
        ibool           success;
2036
2194
        ulint           n_reserved;
2037
 
        page_t*         ret             = NULL;
2038
2195
        ulint           i;
2039
2196
 
2040
2197
        ut_ad(mtr);
 
2198
        ut_ad(byte_offset + FSEG_HEADER_SIZE
 
2199
              <= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);
 
2200
 
 
2201
        latch = fil_space_get_latch(space, &flags);
 
2202
        zip_size = dict_table_flags_to_zip_size(flags);
2041
2203
 
2042
2204
        if (page != 0) {
2043
 
                header = byte_offset + buf_page_get(space, page, RW_X_LATCH,
2044
 
                                                    mtr);
 
2205
                block = buf_page_get(space, zip_size, page, RW_X_LATCH, mtr);
 
2206
                header = byte_offset + buf_block_get_frame(block);
2045
2207
        }
2046
2208
 
2047
2209
        ut_ad(!mutex_own(&kernel_mutex)
2048
 
              || mtr_memo_contains(mtr, fil_space_get_latch(space),
2049
 
                                   MTR_MEMO_X_LOCK));
2050
 
        latch = fil_space_get_latch(space);
 
2210
              || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2051
2211
 
2052
2212
        mtr_x_lock(latch, mtr);
2053
2213
 
2056
2216
                excess pages from the insert buffer free list */
2057
2217
 
2058
2218
                if (space == 0) {
2059
 
                        ibuf_free_excess_pages(space);
 
2219
                        ibuf_free_excess_pages(0);
2060
2220
                }
2061
2221
        }
2062
2222
 
2068
2228
                }
2069
2229
        }
2070
2230
 
2071
 
        space_header = fsp_get_space_header(space, mtr);
 
2231
        space_header = fsp_get_space_header(space, zip_size, mtr);
2072
2232
 
2073
2233
        inode = fsp_alloc_seg_inode(space_header, mtr);
2074
2234
 
2099
2259
        }
2100
2260
 
2101
2261
        if (page == 0) {
2102
 
                page = fseg_alloc_free_page_low(space, inode, 0, FSP_UP, mtr);
 
2262
                page = fseg_alloc_free_page_low(space, zip_size,
 
2263
                                                inode, 0, FSP_UP, mtr);
2103
2264
 
2104
2265
                if (page == FIL_NULL) {
2105
2266
 
2106
 
                        fsp_free_seg_inode(space, inode, mtr);
 
2267
                        fsp_free_seg_inode(space, zip_size, inode, mtr);
2107
2268
 
2108
2269
                        goto funct_exit;
2109
2270
                }
2110
2271
 
2111
 
                header = byte_offset
2112
 
                        + buf_page_get(space, page, RW_X_LATCH, mtr);
 
2272
                block = buf_page_get(space, zip_size, page, RW_X_LATCH, mtr);
 
2273
                header = byte_offset + buf_block_get_frame(block);
2113
2274
                mlog_write_ulint(header - byte_offset + FIL_PAGE_TYPE,
2114
2275
                                 FIL_PAGE_TYPE_SYS, MLOG_2BYTES, mtr);
2115
2276
        }
2116
2277
 
2117
2278
        mlog_write_ulint(header + FSEG_HDR_OFFSET,
2118
 
                         inode - buf_frame_align(inode), MLOG_2BYTES, mtr);
 
2279
                         page_offset(inode), MLOG_2BYTES, mtr);
2119
2280
 
2120
2281
        mlog_write_ulint(header + FSEG_HDR_PAGE_NO,
2121
 
                         buf_frame_get_page_no(inode), MLOG_4BYTES, mtr);
 
2282
                         page_get_page_no(page_align(inode)),
 
2283
                         MLOG_4BYTES, mtr);
2122
2284
 
2123
2285
        mlog_write_ulint(header + FSEG_HDR_SPACE, space, MLOG_4BYTES, mtr);
2124
2286
 
2125
 
        ret = buf_frame_align(header);
2126
 
 
2127
2287
funct_exit:
2128
2288
        if (!has_done_reservation) {
2129
2289
 
2130
2290
                fil_space_release_free_extents(space, n_reserved);
2131
2291
        }
2132
2292
 
2133
 
        return(ret);
 
2293
        return(block);
2134
2294
}
2135
2295
 
2136
2296
/**************************************************************************
2137
2297
Creates a new segment. */
2138
 
 
2139
 
page_t*
 
2298
UNIV_INTERN
 
2299
buf_block_t*
2140
2300
fseg_create(
2141
2301
/*========*/
2142
 
                        /* out: the page where the segment header is placed,
 
2302
                        /* out: the block where the segment header is placed,
2143
2303
                        x-latched, NULL if could not create segment
2144
2304
                        because of lack of space */
2145
2305
        ulint   space,  /* in: space id */
2169
2329
        ulint   ret;
2170
2330
 
2171
2331
        ut_ad(inode && used && mtr);
2172
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(inode),
2173
 
                                MTR_MEMO_PAGE_X_FIX));
 
2332
        ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
2174
2333
 
2175
2334
        *used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr)
2176
2335
                + FSP_EXTENT_SIZE * flst_get_len(inode + FSEG_FULL, mtr)
2187
2346
/**************************************************************************
2188
2347
Calculates the number of pages reserved by a segment, and how many pages are
2189
2348
currently used. */
2190
 
 
 
2349
UNIV_INTERN
2191
2350
ulint
2192
2351
fseg_n_reserved_pages(
2193
2352
/*==================*/
2199
2358
        ulint           ret;
2200
2359
        fseg_inode_t*   inode;
2201
2360
        ulint           space;
 
2361
        ulint           flags;
 
2362
        ulint           zip_size;
 
2363
        rw_lock_t*      latch;
2202
2364
 
2203
 
        space = buf_frame_get_space_id(header);
 
2365
        space = page_get_space_id(page_align(header));
 
2366
        latch = fil_space_get_latch(space, &flags);
 
2367
        zip_size = dict_table_flags_to_zip_size(flags);
2204
2368
 
2205
2369
        ut_ad(!mutex_own(&kernel_mutex)
2206
 
              || mtr_memo_contains(mtr, fil_space_get_latch(space),
2207
 
                                   MTR_MEMO_X_LOCK));
2208
 
 
2209
 
        mtr_x_lock(fil_space_get_latch(space), mtr);
2210
 
 
2211
 
        inode = fseg_inode_get(header, mtr);
 
2370
              || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
 
2371
 
 
2372
        mtr_x_lock(latch, mtr);
 
2373
 
 
2374
        inode = fseg_inode_get(header, space, zip_size, mtr);
2212
2375
 
2213
2376
        ret = fseg_n_reserved_pages_low(inode, used, mtr);
2214
2377
 
2226
2389
/*================*/
2227
2390
        fseg_inode_t*   inode,  /* in: segment inode */
2228
2391
        ulint           space,  /* in: space id */
 
2392
        ulint           zip_size,/* in: compressed page size in bytes
 
2393
                                or 0 for uncompressed pages */
2229
2394
        ulint           hint,   /* in: hint which extent would be good as
2230
2395
                                the first extent */
2231
2396
        mtr_t*          mtr)    /* in: mtr */
2254
2419
        }
2255
2420
 
2256
2421
        for (i = 0; i < FSEG_FREE_LIST_MAX_LEN; i++) {
2257
 
                descr = xdes_get_descriptor(space, hint, mtr);
 
2422
                descr = xdes_get_descriptor(space, zip_size, hint, mtr);
2258
2423
 
2259
2424
                if ((descr == NULL)
2260
2425
                    || (XDES_FREE != xdes_get_state(descr, mtr))) {
2264
2429
                        return;
2265
2430
                }
2266
2431
 
2267
 
                descr = fsp_alloc_free_extent(space, hint, mtr);
 
2432
                descr = fsp_alloc_free_extent(space, zip_size, hint, mtr);
2268
2433
 
2269
2434
                xdes_set_state(descr, XDES_FSEG, mtr);
2270
2435
 
2289
2454
                                not be allocated */
2290
2455
        fseg_inode_t*   inode,  /* in: segment inode */
2291
2456
        ulint           space,  /* in: space id */
 
2457
        ulint           zip_size,/* in: compressed page size in bytes
 
2458
                                or 0 for uncompressed pages */
2292
2459
        mtr_t*          mtr)    /* in: mtr */
2293
2460
{
2294
2461
        xdes_t*         descr;
2300
2467
 
2301
2468
                first = flst_get_first(inode + FSEG_FREE, mtr);
2302
2469
 
2303
 
                descr = xdes_lst_get_descriptor(space, first, mtr);
 
2470
                descr = xdes_lst_get_descriptor(space, zip_size, first, mtr);
2304
2471
        } else {
2305
2472
                /* Segment free list was empty, allocate from space */
2306
 
                descr = fsp_alloc_free_extent(space, 0, mtr);
 
2473
                descr = fsp_alloc_free_extent(space, zip_size, 0, mtr);
2307
2474
 
2308
2475
                if (descr == NULL) {
2309
2476
 
2317
2484
                flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
2318
2485
 
2319
2486
                /* Try to fill the segment free list */
2320
 
                fseg_fill_free_list(inode, space,
 
2487
                fseg_fill_free_list(inode, space, zip_size,
2321
2488
                                    xdes_get_offset(descr) + FSP_EXTENT_SIZE,
2322
2489
                                    mtr);
2323
2490
        }
2336
2503
                                /* out: the allocated page number, FIL_NULL
2337
2504
                                if no page could be allocated */
2338
2505
        ulint           space,  /* in: space */
 
2506
        ulint           zip_size,/* in: compressed page size in bytes
 
2507
                                or 0 for uncompressed pages */
2339
2508
        fseg_inode_t*   seg_inode, /* in: segment inode */
2340
2509
        ulint           hint,   /* in: hint of which page would be desirable */
2341
2510
        byte            direction, /* in: if the new page is needed because
2354
2523
        ulint           ret_page;       /* the allocated page offset, FIL_NULL
2355
2524
                                        if could not be allocated */
2356
2525
        xdes_t*         ret_descr;      /* the extent of the allocated page */
2357
 
        page_t*         page;
2358
2526
        ibool           frag_page_allocated = FALSE;
2359
2527
        ibool           success;
2360
2528
        ulint           n;
2365
2533
              == FSEG_MAGIC_N_VALUE);
2366
2534
        seg_id = mtr_read_dulint(seg_inode + FSEG_ID, mtr);
2367
2535
 
2368
 
        ut_ad(ut_dulint_cmp(seg_id, ut_dulint_zero) > 0);
 
2536
        ut_ad(!ut_dulint_is_zero(seg_id));
2369
2537
 
2370
2538
        reserved = fseg_n_reserved_pages_low(seg_inode, &used, mtr);
2371
2539
 
2372
 
        space_header = fsp_get_space_header(space, mtr);
 
2540
        space_header = fsp_get_space_header(space, zip_size, mtr);
2373
2541
 
2374
2542
        descr = xdes_get_descriptor_with_space_hdr(space_header, space,
2375
2543
                                                   hint, mtr);
2377
2545
                /* Hint outside space or too high above free limit: reset
2378
2546
                hint */
2379
2547
                hint = 0;
2380
 
                descr = xdes_get_descriptor(space, hint, mtr);
 
2548
                descr = xdes_get_descriptor(space, zip_size, hint, mtr);
2381
2549
        }
2382
2550
 
2383
2551
        /* In the big if-else below we look for ret_page and ret_descr */
2401
2569
                =========================================================
2402
2570
                the hinted page
2403
2571
                ===============*/
2404
 
                ret_descr = fsp_alloc_free_extent(space, hint, mtr);
 
2572
                ret_descr = fsp_alloc_free_extent(space, zip_size, hint, mtr);
2405
2573
 
2406
2574
                ut_a(ret_descr == descr);
2407
2575
 
2411
2579
                              ret_descr + XDES_FLST_NODE, mtr);
2412
2580
 
2413
2581
                /* Try to fill the segment free list */
2414
 
                fseg_fill_free_list(seg_inode, space,
 
2582
                fseg_fill_free_list(seg_inode, space, zip_size,
2415
2583
                                    hint + FSP_EXTENT_SIZE, mtr);
2416
2584
                ret_page = hint;
2417
2585
                /*-----------------------------------------------------------*/
2419
2587
                   && ((reserved - used) < reserved / FSEG_FILLFACTOR)
2420
2588
                   && (used >= FSEG_FRAG_LIMIT)
2421
2589
                   && (!!(ret_descr
2422
 
                          = fseg_alloc_free_extent(seg_inode, space, mtr)))) {
 
2590
                          = fseg_alloc_free_extent(seg_inode,
 
2591
                                                   space, zip_size, mtr)))) {
2423
2592
 
2424
2593
                /* 3. We take any free extent (which was already assigned above
2425
2594
                ===============================================================
2464
2633
                        return(FIL_NULL);
2465
2634
                }
2466
2635
 
2467
 
                ret_descr = xdes_lst_get_descriptor(space, first, mtr);
 
2636
                ret_descr = xdes_lst_get_descriptor(space, zip_size,
 
2637
                                                    first, mtr);
2468
2638
                ret_page = xdes_get_offset(ret_descr)
2469
2639
                        + xdes_find_bit(ret_descr, XDES_FREE_BIT, TRUE,
2470
2640
                                        0, mtr);
2472
2642
        } else if (used < FSEG_FRAG_LIMIT) {
2473
2643
                /* 6. We allocate an individual page from the space
2474
2644
                ===================================================*/
2475
 
                ret_page = fsp_alloc_free_page(space, hint, mtr);
 
2645
                ret_page = fsp_alloc_free_page(space, zip_size, hint, mtr);
2476
2646
                ret_descr = NULL;
2477
2647
 
2478
2648
                frag_page_allocated = TRUE;
2490
2660
        } else {
2491
2661
                /* 7. We allocate a new extent and take its first page
2492
2662
                ======================================================*/
2493
 
                ret_descr = fseg_alloc_free_extent(seg_inode, space, mtr);
 
2663
                ret_descr = fseg_alloc_free_extent(seg_inode,
 
2664
                                                   space, zip_size, mtr);
2494
2665
 
2495
2666
                if (ret_descr == NULL) {
2496
2667
                        ret_page = FIL_NULL;
2536
2707
                /* Initialize the allocated page to buffer pool, so that it
2537
2708
                can be obtained immediately with buf_page_get without need
2538
2709
                for a disk read */
2539
 
 
2540
 
                page = buf_page_create(space, ret_page, mtr);
2541
 
 
2542
 
                ut_a(page == buf_page_get(space, ret_page, RW_X_LATCH, mtr));
2543
 
 
 
2710
                buf_block_t*    block;
 
2711
                ulint           zip_size = dict_table_flags_to_zip_size(
 
2712
                        mach_read_from_4(FSP_SPACE_FLAGS + space_header));
 
2713
 
 
2714
                block = buf_page_create(space, ret_page, zip_size, mtr);
2544
2715
#ifdef UNIV_SYNC_DEBUG
2545
 
                buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
 
2716
                buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
2546
2717
#endif /* UNIV_SYNC_DEBUG */
 
2718
                if (UNIV_UNLIKELY(block != buf_page_get(space, zip_size,
 
2719
                                                        ret_page, RW_X_LATCH,
 
2720
                                                        mtr))) {
 
2721
                        ut_error;
 
2722
                }
2547
2723
 
2548
2724
                /* The prior contents of the page should be ignored */
2549
 
                fsp_init_file_page(page, mtr);
 
2725
                fsp_init_file_page(block, mtr);
2550
2726
 
2551
2727
                /* At this point we know the extent and the page offset.
2552
2728
                The extent is still in the appropriate list (FSEG_NOT_FULL
2553
2729
                or FSEG_FREE), and the page is not yet marked as used. */
2554
2730
 
2555
 
                ut_ad(xdes_get_descriptor(space, ret_page, mtr) == ret_descr);
 
2731
                ut_ad(xdes_get_descriptor(space, zip_size, ret_page, mtr)
 
2732
                      == ret_descr);
2556
2733
                ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT,
2557
2734
                                   ret_page % FSP_EXTENT_SIZE, mtr) == TRUE);
2558
2735
 
2559
 
                fseg_mark_page_used(seg_inode, space, ret_page, mtr);
 
2736
                fseg_mark_page_used(seg_inode, space, zip_size, ret_page, mtr);
2560
2737
        }
2561
2738
 
2562
2739
        buf_reset_check_index_page_at_flush(space, ret_page);
2568
2745
Allocates a single free page from a segment. This function implements
2569
2746
the intelligent allocation strategy which tries to minimize file space
2570
2747
fragmentation. */
2571
 
 
 
2748
UNIV_INTERN
2572
2749
ulint
2573
2750
fseg_alloc_free_page_general(
2574
2751
/*=========================*/
2590
2767
{
2591
2768
        fseg_inode_t*   inode;
2592
2769
        ulint           space;
 
2770
        ulint           flags;
 
2771
        ulint           zip_size;
2593
2772
        rw_lock_t*      latch;
2594
2773
        ibool           success;
2595
2774
        ulint           page_no;
2596
2775
        ulint           n_reserved;
2597
2776
 
2598
 
        space = buf_frame_get_space_id(seg_header);
 
2777
        space = page_get_space_id(page_align(seg_header));
 
2778
 
 
2779
        latch = fil_space_get_latch(space, &flags);
 
2780
 
 
2781
        zip_size = dict_table_flags_to_zip_size(flags);
2599
2782
 
2600
2783
        ut_ad(!mutex_own(&kernel_mutex)
2601
 
              || mtr_memo_contains(mtr, fil_space_get_latch(space),
2602
 
                                   MTR_MEMO_X_LOCK));
2603
 
        latch = fil_space_get_latch(space);
 
2784
              || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2604
2785
 
2605
2786
        mtr_x_lock(latch, mtr);
2606
2787
 
2609
2790
                excess pages from the insert buffer free list */
2610
2791
 
2611
2792
                if (space == 0) {
2612
 
                        ibuf_free_excess_pages(space);
 
2793
                        ibuf_free_excess_pages(0);
2613
2794
                }
2614
2795
        }
2615
2796
 
2616
 
        inode = fseg_inode_get(seg_header, mtr);
 
2797
        inode = fseg_inode_get(seg_header, space, zip_size, mtr);
2617
2798
 
2618
2799
        if (!has_done_reservation) {
2619
2800
                success = fsp_reserve_free_extents(&n_reserved, space, 2,
2623
2804
                }
2624
2805
        }
2625
2806
 
2626
 
        page_no = fseg_alloc_free_page_low(buf_frame_get_space_id(inode),
 
2807
        page_no = fseg_alloc_free_page_low(space, zip_size,
2627
2808
                                           inode, hint, direction, mtr);
2628
2809
        if (!has_done_reservation) {
2629
2810
                fil_space_release_free_extents(space, n_reserved);
2636
2817
Allocates a single free page from a segment. This function implements
2637
2818
the intelligent allocation strategy which tries to minimize file space
2638
2819
fragmentation. */
2639
 
 
 
2820
UNIV_INTERN
2640
2821
ulint
2641
2822
fseg_alloc_free_page(
2642
2823
/*=================*/
2720
2901
split or merge in a B-tree. But we do not want to waste disk space if the table
2721
2902
only occupies < 32 pages. That is why we apply different rules in that special
2722
2903
case, just ensuring that there are 3 free pages available. */
2723
 
 
 
2904
UNIV_INTERN
2724
2905
ibool
2725
2906
fsp_reserve_free_extents(
2726
2907
/*=====================*/
2738
2919
        ulint           n_free_list_ext;
2739
2920
        ulint           free_limit;
2740
2921
        ulint           size;
 
2922
        ulint           flags;
 
2923
        ulint           zip_size;
2741
2924
        ulint           n_free;
2742
2925
        ulint           n_free_up;
2743
2926
        ulint           reserve;
2745
2928
        ulint           n_pages_added;
2746
2929
 
2747
2930
        ut_ad(mtr);
2748
 
        ut_ad(!mutex_own(&kernel_mutex)
2749
 
              || mtr_memo_contains(mtr, fil_space_get_latch(space),
2750
 
                                   MTR_MEMO_X_LOCK));
2751
2931
        *n_reserved = n_ext;
2752
2932
 
2753
 
        latch = fil_space_get_latch(space);
 
2933
        latch = fil_space_get_latch(space, &flags);
 
2934
        zip_size = dict_table_flags_to_zip_size(flags);
 
2935
 
 
2936
        ut_ad(!mutex_own(&kernel_mutex)
 
2937
              || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2754
2938
 
2755
2939
        mtr_x_lock(latch, mtr);
2756
2940
 
2757
 
        space_header = fsp_get_space_header(space, mtr);
 
2941
        space_header = fsp_get_space_header(space, zip_size, mtr);
2758
2942
try_again:
2759
2943
        size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, mtr);
2760
2944
 
2777
2961
 
2778
2962
        if (n_free_up > 0) {
2779
2963
                n_free_up--;
2780
 
                n_free_up = n_free_up - n_free_up
2781
 
                        / (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE);
 
2964
                if (!zip_size) {
 
2965
                        n_free_up -= n_free_up
 
2966
                                / (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE);
 
2967
                } else {
 
2968
                        n_free_up -= n_free_up
 
2969
                                / (zip_size / FSP_EXTENT_SIZE);
 
2970
                }
2782
2971
        }
2783
2972
 
2784
2973
        n_free = n_free_list_ext + n_free_up;
2828
3017
will be able to insert new data to the database without running out the
2829
3018
tablespace. Only free extents are taken into account and we also subtract
2830
3019
the safety margin required by the above function fsp_reserve_free_extents. */
2831
 
 
 
3020
UNIV_INTERN
2832
3021
ullint
2833
3022
fsp_get_available_space_in_free_extents(
2834
3023
/*====================================*/
2839
3028
        ulint           n_free_list_ext;
2840
3029
        ulint           free_limit;
2841
3030
        ulint           size;
 
3031
        ulint           flags;
 
3032
        ulint           zip_size;
2842
3033
        ulint           n_free;
2843
3034
        ulint           n_free_up;
2844
3035
        ulint           reserve;
2849
3040
 
2850
3041
        mtr_start(&mtr);
2851
3042
 
2852
 
        latch = fil_space_get_latch(space);
 
3043
        latch = fil_space_get_latch(space, &flags);
 
3044
        zip_size = dict_table_flags_to_zip_size(flags);
2853
3045
 
2854
3046
        mtr_x_lock(latch, &mtr);
2855
3047
 
2856
 
        space_header = fsp_get_space_header(space, &mtr);
 
3048
        space_header = fsp_get_space_header(space, zip_size, &mtr);
2857
3049
 
2858
3050
        size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, &mtr);
2859
3051
 
2879
3071
 
2880
3072
        if (n_free_up > 0) {
2881
3073
                n_free_up--;
2882
 
                n_free_up = n_free_up - n_free_up
2883
 
                        / (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE);
 
3074
                if (!zip_size) {
 
3075
                        n_free_up -= n_free_up
 
3076
                                / (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE);
 
3077
                } else {
 
3078
                        n_free_up -= n_free_up
 
3079
                                / (zip_size / FSP_EXTENT_SIZE);
 
3080
                }
2884
3081
        }
2885
3082
 
2886
3083
        n_free = n_free_list_ext + n_free_up;
2895
3092
                return(0);
2896
3093
        }
2897
3094
 
2898
 
        return((ullint)(n_free - reserve)
2899
 
               * FSP_EXTENT_SIZE
2900
 
               * (UNIV_PAGE_SIZE / 1024));
 
3095
        if (!zip_size) {
 
3096
                return((ullint) (n_free - reserve)
 
3097
                       * FSP_EXTENT_SIZE
 
3098
                       * (UNIV_PAGE_SIZE / 1024));
 
3099
        } else {
 
3100
                return((ullint) (n_free - reserve)
 
3101
                       * FSP_EXTENT_SIZE
 
3102
                       * (zip_size / 1024));
 
3103
        }
2901
3104
}
2902
3105
 
2903
3106
/************************************************************************
2909
3112
/*================*/
2910
3113
        fseg_inode_t*   seg_inode,/* in: segment inode */
2911
3114
        ulint           space,  /* in: space id */
 
3115
        ulint           zip_size,/* in: compressed page size in bytes
 
3116
                                or 0 for uncompressed pages */
2912
3117
        ulint           page,   /* in: page offset */
2913
3118
        mtr_t*          mtr)    /* in: mtr */
2914
3119
{
2917
3122
 
2918
3123
        ut_ad(seg_inode && mtr);
2919
3124
 
2920
 
        descr = xdes_get_descriptor(space, page, mtr);
 
3125
        descr = xdes_get_descriptor(space, zip_size, page, mtr);
2921
3126
 
2922
3127
        ut_ad(mtr_read_ulint(seg_inode + FSEG_ID, MLOG_4BYTES, mtr)
2923
3128
              == mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr));
2963
3168
/*===============*/
2964
3169
        fseg_inode_t*   seg_inode, /* in: segment inode */
2965
3170
        ulint           space,  /* in: space id */
 
3171
        ulint           zip_size,/* in: compressed page size in bytes
 
3172
                                or 0 for uncompressed pages */
2966
3173
        ulint           page,   /* in: page offset */
2967
3174
        mtr_t*          mtr)    /* in: mtr handle */
2968
3175
{
2980
3187
        /* Drop search system page hash index if the page is found in
2981
3188
        the pool and is hashed */
2982
3189
 
2983
 
        btr_search_drop_page_hash_when_freed(space, page);
 
3190
        btr_search_drop_page_hash_when_freed(space, zip_size, page);
2984
3191
 
2985
 
        descr = xdes_get_descriptor(space, page, mtr);
 
3192
        descr = xdes_get_descriptor(space, zip_size, page, mtr);
2986
3193
 
2987
3194
        ut_a(descr);
2988
3195
        if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) {
3022
3229
                        }
3023
3230
                }
3024
3231
 
3025
 
                fsp_free_page(space, page, mtr);
 
3232
                fsp_free_page(space, zip_size, page, mtr);
3026
3233
 
3027
3234
                return;
3028
3235
        }
3088
3295
                /* The extent has become free: free it to space */
3089
3296
                flst_remove(seg_inode + FSEG_NOT_FULL,
3090
3297
                            descr + XDES_FLST_NODE, mtr);
3091
 
                fsp_free_extent(space, page, mtr);
 
3298
                fsp_free_extent(space, zip_size, page, mtr);
3092
3299
        }
3093
3300
}
3094
3301
 
3095
3302
/**************************************************************************
3096
3303
Frees a single page of a segment. */
3097
 
 
 
3304
UNIV_INTERN
3098
3305
void
3099
3306
fseg_free_page(
3100
3307
/*===========*/
3103
3310
        ulint           page,   /* in: page offset */
3104
3311
        mtr_t*          mtr)    /* in: mtr handle */
3105
3312
{
 
3313
        ulint           flags;
 
3314
        ulint           zip_size;
3106
3315
        fseg_inode_t*   seg_inode;
 
3316
        rw_lock_t*      latch;
 
3317
 
 
3318
        latch = fil_space_get_latch(space, &flags);
 
3319
        zip_size = dict_table_flags_to_zip_size(flags);
3107
3320
 
3108
3321
        ut_ad(!mutex_own(&kernel_mutex)
3109
 
              || mtr_memo_contains(mtr, fil_space_get_latch(space),
3110
 
                                   MTR_MEMO_X_LOCK));
3111
 
 
3112
 
        mtr_x_lock(fil_space_get_latch(space), mtr);
3113
 
 
3114
 
        seg_inode = fseg_inode_get(seg_header, mtr);
3115
 
 
3116
 
        fseg_free_page_low(seg_inode, space, page, mtr);
 
3322
              || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
 
3323
 
 
3324
        mtr_x_lock(latch, mtr);
 
3325
 
 
3326
        seg_inode = fseg_inode_get(seg_header, space, zip_size, mtr);
 
3327
 
 
3328
        fseg_free_page_low(seg_inode, space, zip_size, page, mtr);
3117
3329
 
3118
3330
#ifdef UNIV_DEBUG_FILE_ACCESSES
3119
3331
        buf_page_set_file_page_was_freed(space, page);
3128
3340
/*=============*/
3129
3341
        fseg_inode_t*   seg_inode, /* in: segment inode */
3130
3342
        ulint           space,  /* in: space id */
 
3343
        ulint           zip_size,/* in: compressed page size in bytes
 
3344
                                or 0 for uncompressed pages */
3131
3345
        ulint           page,   /* in: a page in the extent */
3132
3346
        mtr_t*          mtr)    /* in: mtr handle */
3133
3347
{
3139
3353
 
3140
3354
        ut_ad(seg_inode && mtr);
3141
3355
 
3142
 
        descr = xdes_get_descriptor(space, page, mtr);
 
3356
        descr = xdes_get_descriptor(space, zip_size, page, mtr);
3143
3357
 
3144
3358
        ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
3145
3359
        ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
3154
3368
                        found in the pool and is hashed */
3155
3369
 
3156
3370
                        btr_search_drop_page_hash_when_freed(
3157
 
                                space, first_page_in_extent + i);
 
3371
                                space, zip_size, first_page_in_extent + i);
3158
3372
                }
3159
3373
        }
3160
3374
 
3178
3392
                                 MLOG_4BYTES, mtr);
3179
3393
        }
3180
3394
 
3181
 
        fsp_free_extent(space, page, mtr);
 
3395
        fsp_free_extent(space, zip_size, page, mtr);
3182
3396
 
3183
3397
#ifdef UNIV_DEBUG_FILE_ACCESSES
3184
3398
        for (i = 0; i < FSP_EXTENT_SIZE; i++) {
3194
3408
repeatedly calling this function in different mini-transactions. Doing
3195
3409
the freeing in a single mini-transaction might result in too big a
3196
3410
mini-transaction. */
3197
 
 
 
3411
UNIV_INTERN
3198
3412
ibool
3199
3413
fseg_free_step(
3200
3414
/*===========*/
3210
3424
        xdes_t*         descr;
3211
3425
        fseg_inode_t*   inode;
3212
3426
        ulint           space;
3213
 
 
3214
 
        space = buf_frame_get_space_id(header);
 
3427
        ulint           flags;
 
3428
        ulint           zip_size;
 
3429
        ulint           header_page;
 
3430
        rw_lock_t*      latch;
 
3431
 
 
3432
        space = page_get_space_id(page_align(header));
 
3433
        header_page = page_get_page_no(page_align(header));
 
3434
 
 
3435
        latch = fil_space_get_latch(space, &flags);
 
3436
        zip_size = dict_table_flags_to_zip_size(flags);
3215
3437
 
3216
3438
        ut_ad(!mutex_own(&kernel_mutex)
3217
 
              || mtr_memo_contains(mtr, fil_space_get_latch(space),
3218
 
                                   MTR_MEMO_X_LOCK));
3219
 
 
3220
 
        mtr_x_lock(fil_space_get_latch(space), mtr);
3221
 
 
3222
 
        descr = xdes_get_descriptor(space, buf_frame_get_page_no(header), mtr);
 
3439
              || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
 
3440
 
 
3441
        mtr_x_lock(latch, mtr);
 
3442
 
 
3443
        descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
3223
3444
 
3224
3445
        /* Check that the header resides on a page which has not been
3225
3446
        freed yet */
3226
3447
 
3227
3448
        ut_a(descr);
3228
 
        ut_a(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header)
3229
 
                          % FSP_EXTENT_SIZE, mtr) == FALSE);
3230
 
        inode = fseg_inode_get(header, mtr);
 
3449
        ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
 
3450
                          header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
 
3451
        inode = fseg_inode_get(header, space, zip_size, mtr);
3231
3452
 
3232
 
        descr = fseg_get_first_extent(inode, mtr);
 
3453
        descr = fseg_get_first_extent(inode, space, zip_size, mtr);
3233
3454
 
3234
3455
        if (descr != NULL) {
3235
3456
                /* Free the extent held by the segment */
3236
3457
                page = xdes_get_offset(descr);
3237
3458
 
3238
 
                fseg_free_extent(inode, space, page, mtr);
 
3459
                fseg_free_extent(inode, space, zip_size, page, mtr);
3239
3460
 
3240
3461
                return(FALSE);
3241
3462
        }
3245
3466
 
3246
3467
        if (n == ULINT_UNDEFINED) {
3247
3468
                /* Freeing completed: free the segment inode */
3248
 
                fsp_free_seg_inode(space, inode, mtr);
 
3469
                fsp_free_seg_inode(space, zip_size, inode, mtr);
3249
3470
 
3250
3471
                return(TRUE);
3251
3472
        }
3252
3473
 
3253
 
        fseg_free_page_low(inode, space,
 
3474
        fseg_free_page_low(inode, space, zip_size,
3254
3475
                           fseg_get_nth_frag_page_no(inode, n, mtr), mtr);
3255
3476
 
3256
3477
        n = fseg_find_last_used_frag_page_slot(inode, mtr);
3257
3478
 
3258
3479
        if (n == ULINT_UNDEFINED) {
3259
3480
                /* Freeing completed: free the segment inode */
3260
 
                fsp_free_seg_inode(space, inode, mtr);
 
3481
                fsp_free_seg_inode(space, zip_size, inode, mtr);
3261
3482
 
3262
3483
                return(TRUE);
3263
3484
        }
3268
3489
/**************************************************************************
3269
3490
Frees part of a segment. Differs from fseg_free_step because this function
3270
3491
leaves the header page unfreed. */
3271
 
 
 
3492
UNIV_INTERN
3272
3493
ibool
3273
3494
fseg_free_step_not_header(
3274
3495
/*======================*/
3283
3504
        xdes_t*         descr;
3284
3505
        fseg_inode_t*   inode;
3285
3506
        ulint           space;
 
3507
        ulint           flags;
 
3508
        ulint           zip_size;
3286
3509
        ulint           page_no;
3287
 
 
3288
 
        space = buf_frame_get_space_id(header);
 
3510
        rw_lock_t*      latch;
 
3511
 
 
3512
        space = page_get_space_id(page_align(header));
 
3513
 
 
3514
        latch = fil_space_get_latch(space, &flags);
 
3515
        zip_size = dict_table_flags_to_zip_size(flags);
3289
3516
 
3290
3517
        ut_ad(!mutex_own(&kernel_mutex)
3291
 
              || mtr_memo_contains(mtr, fil_space_get_latch(space),
3292
 
                                   MTR_MEMO_X_LOCK));
3293
 
 
3294
 
        mtr_x_lock(fil_space_get_latch(space), mtr);
3295
 
 
3296
 
        inode = fseg_inode_get(header, mtr);
3297
 
 
3298
 
        descr = fseg_get_first_extent(inode, mtr);
 
3518
              || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
 
3519
 
 
3520
        mtr_x_lock(latch, mtr);
 
3521
 
 
3522
        inode = fseg_inode_get(header, space, zip_size, mtr);
 
3523
 
 
3524
        descr = fseg_get_first_extent(inode, space, zip_size, mtr);
3299
3525
 
3300
3526
        if (descr != NULL) {
3301
3527
                /* Free the extent held by the segment */
3302
3528
                page = xdes_get_offset(descr);
3303
3529
 
3304
 
                fseg_free_extent(inode, space, page, mtr);
 
3530
                fseg_free_extent(inode, space, zip_size, page, mtr);
3305
3531
 
3306
3532
                return(FALSE);
3307
3533
        }
3316
3542
 
3317
3543
        page_no = fseg_get_nth_frag_page_no(inode, n, mtr);
3318
3544
 
3319
 
        if (page_no == buf_frame_get_page_no(header)) {
 
3545
        if (page_no == page_get_page_no(page_align(header))) {
3320
3546
 
3321
3547
                return(TRUE);
3322
3548
        }
3323
3549
 
3324
 
        fseg_free_page_low(inode, space, page_no, mtr);
 
3550
        fseg_free_page_low(inode, space, zip_size, page_no, mtr);
3325
3551
 
3326
3552
        return(FALSE);
3327
3553
}
3329
3555
/***********************************************************************
3330
3556
Frees a segment. The freeing is performed in several mini-transactions,
3331
3557
so that there is no danger of bufferfixing too many buffer pages. */
3332
 
 
 
3558
UNIV_INTERN
3333
3559
void
3334
3560
fseg_free(
3335
3561
/*======*/
3336
3562
        ulint   space,  /* in: space id */
 
3563
        ulint   zip_size,/* in: compressed page size in bytes
 
3564
                        or 0 for uncompressed pages */
3337
3565
        ulint   page_no,/* in: page number where the segment header is
3338
3566
                        placed */
3339
3567
        ulint   offset) /* in: byte offset of the segment header on that
3350
3578
        for (;;) {
3351
3579
                mtr_start(&mtr);
3352
3580
 
3353
 
                header = fut_get_ptr(space, addr, RW_X_LATCH, &mtr);
 
3581
                header = fut_get_ptr(space, zip_size, addr, RW_X_LATCH, &mtr);
3354
3582
 
3355
3583
                finished = fseg_free_step(header, &mtr);
3356
3584
 
3374
3602
                                /* out: the first extent descriptor, or NULL if
3375
3603
                                none */
3376
3604
        fseg_inode_t*   inode,  /* in: segment inode */
 
3605
        ulint           space,  /* in: space id */
 
3606
        ulint           zip_size,/* in: compressed page size in bytes
 
3607
                                or 0 for uncompressed pages */
3377
3608
        mtr_t*          mtr)    /* in: mtr */
3378
3609
{
3379
3610
        fil_addr_t      first;
3380
 
        ulint           space;
3381
3611
        xdes_t*         descr;
3382
3612
 
3383
3613
        ut_ad(inode && mtr);
3384
3614
 
3385
 
        space = buf_frame_get_space_id(inode);
 
3615
        ut_ad(space == page_get_space_id(page_align(inode)));
3386
3616
 
3387
3617
        first = fil_addr_null;
3388
3618
 
3403
3633
 
3404
3634
                return(NULL);
3405
3635
        }
3406
 
        descr = xdes_lst_get_descriptor(space, first, mtr);
 
3636
        descr = xdes_lst_get_descriptor(space, zip_size, first, mtr);
3407
3637
 
3408
3638
        return(descr);
3409
3639
}
3426
3656
        ulint           n_used          = 0;
3427
3657
        ulint           n_used2         = 0;
3428
3658
 
3429
 
        ut_ad(mtr_memo_contains(mtr2, buf_block_align(inode),
3430
 
                                MTR_MEMO_PAGE_X_FIX));
 
3659
        ut_ad(mtr_memo_contains_page(mtr2, inode, MTR_MEMO_PAGE_X_FIX));
3431
3660
        ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
3432
3661
 
3433
 
        space = buf_frame_get_space_id(inode);
 
3662
        space = page_get_space_id(page_align(inode));
3434
3663
 
3435
3664
        seg_id = mtr_read_dulint(inode + FSEG_ID, mtr2);
3436
3665
        n_used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED,
3443
3672
        node_addr = flst_get_first(inode + FSEG_FREE, mtr2);
3444
3673
 
3445
3674
        while (!fil_addr_is_null(node_addr)) {
 
3675
                ulint   flags;
 
3676
                ulint   zip_size;
 
3677
 
3446
3678
                mtr_start(&mtr);
3447
 
                mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3679
                mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
 
3680
                zip_size = dict_table_flags_to_zip_size(flags);
3448
3681
 
3449
 
                descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
 
3682
                descr = xdes_lst_get_descriptor(space, zip_size,
 
3683
                                                node_addr, &mtr);
3450
3684
 
3451
3685
                ut_a(xdes_get_n_used(descr, &mtr) == 0);
3452
3686
                ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
3462
3696
        node_addr = flst_get_first(inode + FSEG_NOT_FULL, mtr2);
3463
3697
 
3464
3698
        while (!fil_addr_is_null(node_addr)) {
 
3699
                ulint   flags;
 
3700
                ulint   zip_size;
 
3701
 
3465
3702
                mtr_start(&mtr);
3466
 
                mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3703
                mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
 
3704
                zip_size = dict_table_flags_to_zip_size(flags);
3467
3705
 
3468
 
                descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
 
3706
                descr = xdes_lst_get_descriptor(space, zip_size,
 
3707
                                                node_addr, &mtr);
3469
3708
 
3470
3709
                ut_a(xdes_get_n_used(descr, &mtr) > 0);
3471
3710
                ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE);
3484
3723
        node_addr = flst_get_first(inode + FSEG_FULL, mtr2);
3485
3724
 
3486
3725
        while (!fil_addr_is_null(node_addr)) {
 
3726
                ulint   flags;
 
3727
                ulint   zip_size;
 
3728
 
3487
3729
                mtr_start(&mtr);
3488
 
                mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3730
                mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
 
3731
                zip_size = dict_table_flags_to_zip_size(flags);
3489
3732
 
3490
 
                descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
 
3733
                descr = xdes_lst_get_descriptor(space, zip_size,
 
3734
                                                node_addr, &mtr);
3491
3735
 
3492
3736
                ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE);
3493
3737
                ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
3505
3749
 
3506
3750
/***********************************************************************
3507
3751
Validates a segment. */
3508
 
 
 
3752
UNIV_INTERN
3509
3753
ibool
3510
3754
fseg_validate(
3511
3755
/*==========*/
3512
3756
                                /* out: TRUE if ok */
3513
3757
        fseg_header_t*  header, /* in: segment header */
3514
 
        mtr_t*          mtr2)   /* in: mtr */
 
3758
        mtr_t*          mtr)    /* in: mtr */
3515
3759
{
3516
3760
        fseg_inode_t*   inode;
3517
3761
        ibool           ret;
3518
3762
        ulint           space;
3519
 
 
3520
 
        space = buf_frame_get_space_id(header);
3521
 
 
3522
 
        mtr_x_lock(fil_space_get_latch(space), mtr2);
3523
 
 
3524
 
        inode = fseg_inode_get(header, mtr2);
3525
 
 
3526
 
        ret = fseg_validate_low(inode, mtr2);
 
3763
        ulint           flags;
 
3764
        ulint           zip_size;
 
3765
 
 
3766
        space = page_get_space_id(page_align(header));
 
3767
 
 
3768
        mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
 
3769
        zip_size = dict_table_flags_to_zip_size(flags);
 
3770
 
 
3771
        inode = fseg_inode_get(header, space, zip_size, mtr);
 
3772
 
 
3773
        ret = fseg_validate_low(inode, mtr);
3527
3774
 
3528
3775
        return(ret);
3529
3776
}
3550
3797
        ulint   page_no;
3551
3798
        dulint   d_var;
3552
3799
 
3553
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(inode),
3554
 
                                MTR_MEMO_PAGE_X_FIX));
3555
 
        space = buf_frame_get_space_id(inode);
3556
 
        page_no = buf_frame_get_page_no(inode);
 
3800
        ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
 
3801
        space = page_get_space_id(page_align(inode));
 
3802
        page_no = page_get_page_no(page_align(inode));
3557
3803
 
3558
3804
        reserved = fseg_n_reserved_pages_low(inode, &used, mtr);
3559
3805
 
3581
3827
                (ulong) n_used);
3582
3828
}
3583
3829
 
 
3830
#ifdef UNIV_BTR_PRINT
3584
3831
/***********************************************************************
3585
3832
Writes info of a segment. */
3586
 
 
 
3833
UNIV_INTERN
3587
3834
void
3588
3835
fseg_print(
3589
3836
/*=======*/
3592
3839
{
3593
3840
        fseg_inode_t*   inode;
3594
3841
        ulint           space;
3595
 
 
3596
 
        space = buf_frame_get_space_id(header);
3597
 
 
3598
 
        mtr_x_lock(fil_space_get_latch(space), mtr);
3599
 
 
3600
 
        inode = fseg_inode_get(header, mtr);
 
3842
        ulint           flags;
 
3843
        ulint           zip_size;
 
3844
 
 
3845
        space = page_get_space_id(page_align(header));
 
3846
 
 
3847
        mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
 
3848
        zip_size = dict_table_flags_to_zip_size(flags);
 
3849
 
 
3850
        inode = fseg_inode_get(header, space, zip_size, mtr);
3601
3851
 
3602
3852
        fseg_print_low(inode, mtr);
3603
3853
}
 
3854
#endif /* UNIV_BTR_PRINT */
3604
3855
 
3605
3856
/***********************************************************************
3606
3857
Validates the file space system and its segments. */
3607
 
 
 
3858
UNIV_INTERN
3608
3859
ibool
3609
3860
fsp_validate(
3610
3861
/*=========*/
3614
3865
        fsp_header_t*   header;
3615
3866
        fseg_inode_t*   seg_inode;
3616
3867
        page_t*         seg_inode_page;
 
3868
        rw_lock_t*      latch;
3617
3869
        ulint           size;
 
3870
        ulint           flags;
 
3871
        ulint           zip_size;
3618
3872
        ulint           free_limit;
3619
3873
        ulint           frag_n_used;
3620
3874
        mtr_t           mtr;
3630
3884
        ulint           seg_inode_len_free;
3631
3885
        ulint           seg_inode_len_full;
3632
3886
 
 
3887
        latch = fil_space_get_latch(space, &flags);
 
3888
        zip_size = dict_table_flags_to_zip_size(flags);
 
3889
        ut_a(ut_is_2pow(zip_size));
 
3890
        ut_a(zip_size <= UNIV_PAGE_SIZE);
 
3891
        ut_a(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE);
 
3892
 
3633
3893
        /* Start first a mini-transaction mtr2 to lock out all other threads
3634
3894
        from the fsp system */
3635
3895
        mtr_start(&mtr2);
3636
 
        mtr_x_lock(fil_space_get_latch(space), &mtr2);
 
3896
        mtr_x_lock(latch, &mtr2);
3637
3897
 
3638
3898
        mtr_start(&mtr);
3639
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3899
        mtr_x_lock(latch, &mtr);
3640
3900
 
3641
 
        header = fsp_get_space_header(space, &mtr);
 
3901
        header = fsp_get_space_header(space, zip_size, &mtr);
3642
3902
 
3643
3903
        size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr);
3644
3904
        free_limit = mtr_read_ulint(header + FSP_FREE_LIMIT,
3663
3923
 
3664
3924
        /* Validate FSP_FREE list */
3665
3925
        mtr_start(&mtr);
3666
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3926
        mtr_x_lock(latch, &mtr);
3667
3927
 
3668
 
        header = fsp_get_space_header(space, &mtr);
 
3928
        header = fsp_get_space_header(space, zip_size, &mtr);
3669
3929
        node_addr = flst_get_first(header + FSP_FREE, &mtr);
3670
3930
 
3671
3931
        mtr_commit(&mtr);
3672
3932
 
3673
3933
        while (!fil_addr_is_null(node_addr)) {
3674
3934
                mtr_start(&mtr);
3675
 
                mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3935
                mtr_x_lock(latch, &mtr);
3676
3936
 
3677
3937
                descr_count++;
3678
 
                descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
 
3938
                descr = xdes_lst_get_descriptor(space, zip_size,
 
3939
                                                node_addr, &mtr);
3679
3940
 
3680
3941
                ut_a(xdes_get_n_used(descr, &mtr) == 0);
3681
3942
                ut_a(xdes_get_state(descr, &mtr) == XDES_FREE);
3686
3947
 
3687
3948
        /* Validate FSP_FREE_FRAG list */
3688
3949
        mtr_start(&mtr);
3689
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3950
        mtr_x_lock(latch, &mtr);
3690
3951
 
3691
 
        header = fsp_get_space_header(space, &mtr);
 
3952
        header = fsp_get_space_header(space, zip_size, &mtr);
3692
3953
        node_addr = flst_get_first(header + FSP_FREE_FRAG, &mtr);
3693
3954
 
3694
3955
        mtr_commit(&mtr);
3695
3956
 
3696
3957
        while (!fil_addr_is_null(node_addr)) {
3697
3958
                mtr_start(&mtr);
3698
 
                mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3959
                mtr_x_lock(latch, &mtr);
3699
3960
 
3700
3961
                descr_count++;
3701
 
                descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
 
3962
                descr = xdes_lst_get_descriptor(space, zip_size,
 
3963
                                                node_addr, &mtr);
3702
3964
 
3703
3965
                ut_a(xdes_get_n_used(descr, &mtr) > 0);
3704
3966
                ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE);
3712
3974
 
3713
3975
        /* Validate FSP_FULL_FRAG list */
3714
3976
        mtr_start(&mtr);
3715
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3977
        mtr_x_lock(latch, &mtr);
3716
3978
 
3717
 
        header = fsp_get_space_header(space, &mtr);
 
3979
        header = fsp_get_space_header(space, zip_size, &mtr);
3718
3980
        node_addr = flst_get_first(header + FSP_FULL_FRAG, &mtr);
3719
3981
 
3720
3982
        mtr_commit(&mtr);
3721
3983
 
3722
3984
        while (!fil_addr_is_null(node_addr)) {
3723
3985
                mtr_start(&mtr);
3724
 
                mtr_x_lock(fil_space_get_latch(space), &mtr);
 
3986
                mtr_x_lock(latch, &mtr);
3725
3987
 
3726
3988
                descr_count++;
3727
 
                descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
 
3989
                descr = xdes_lst_get_descriptor(space, zip_size,
 
3990
                                                node_addr, &mtr);
3728
3991
 
3729
3992
                ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE);
3730
3993
                ut_a(xdes_get_state(descr, &mtr) == XDES_FULL_FRAG);
3735
3998
 
3736
3999
        /* Validate segments */
3737
4000
        mtr_start(&mtr);
3738
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4001
        mtr_x_lock(latch, &mtr);
3739
4002
 
3740
 
        header = fsp_get_space_header(space, &mtr);
 
4003
        header = fsp_get_space_header(space, zip_size, &mtr);
3741
4004
 
3742
4005
        node_addr = flst_get_first(header + FSP_SEG_INODES_FULL, &mtr);
3743
4006
 
3747
4010
 
3748
4011
        while (!fil_addr_is_null(node_addr)) {
3749
4012
 
3750
 
                for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) {
3751
 
 
 
4013
                n = 0;
 
4014
                do {
3752
4015
                        mtr_start(&mtr);
3753
 
                        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4016
                        mtr_x_lock(latch, &mtr);
3754
4017
 
3755
4018
                        seg_inode_page = fut_get_ptr(
3756
 
                                space, node_addr, RW_X_LATCH, &mtr)
 
4019
                                space, zip_size, node_addr, RW_X_LATCH, &mtr)
3757
4020
                                - FSEG_INODE_PAGE_NODE;
3758
4021
 
3759
4022
                        seg_inode = fsp_seg_inode_page_get_nth_inode(
3760
 
                                seg_inode_page, n, &mtr);
3761
 
                        ut_a(ut_dulint_cmp(
3762
 
                                     mach_read_from_8(seg_inode + FSEG_ID),
3763
 
                                     ut_dulint_zero) != 0);
 
4023
                                seg_inode_page, n, zip_size, &mtr);
 
4024
                        ut_a(!ut_dulint_is_zero(
 
4025
                                     mach_read_from_8(seg_inode + FSEG_ID)));
3764
4026
                        fseg_validate_low(seg_inode, &mtr);
3765
4027
 
3766
4028
                        descr_count += flst_get_len(seg_inode + FSEG_FREE,
3775
4037
                        next_node_addr = flst_get_next_addr(
3776
4038
                                seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
3777
4039
                        mtr_commit(&mtr);
3778
 
                }
 
4040
                } while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
3779
4041
 
3780
4042
                node_addr = next_node_addr;
3781
4043
        }
3782
4044
 
3783
4045
        mtr_start(&mtr);
3784
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4046
        mtr_x_lock(latch, &mtr);
3785
4047
 
3786
 
        header = fsp_get_space_header(space, &mtr);
 
4048
        header = fsp_get_space_header(space, zip_size, &mtr);
3787
4049
 
3788
4050
        node_addr = flst_get_first(header + FSP_SEG_INODES_FREE, &mtr);
3789
4051
 
3793
4055
 
3794
4056
        while (!fil_addr_is_null(node_addr)) {
3795
4057
 
3796
 
                for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) {
 
4058
                n = 0;
3797
4059
 
 
4060
                do {
3798
4061
                        mtr_start(&mtr);
3799
 
                        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4062
                        mtr_x_lock(latch, &mtr);
3800
4063
 
3801
4064
                        seg_inode_page = fut_get_ptr(
3802
 
                                space, node_addr, RW_X_LATCH, &mtr)
 
4065
                                space, zip_size, node_addr, RW_X_LATCH, &mtr)
3803
4066
                                - FSEG_INODE_PAGE_NODE;
3804
4067
 
3805
4068
                        seg_inode = fsp_seg_inode_page_get_nth_inode(
3806
 
                                seg_inode_page, n, &mtr);
3807
 
                        if (ut_dulint_cmp(
3808
 
                                    mach_read_from_8(seg_inode + FSEG_ID),
3809
 
                                    ut_dulint_zero) != 0) {
 
4069
                                seg_inode_page, n, zip_size, &mtr);
 
4070
                        if (!ut_dulint_is_zero(
 
4071
                                    mach_read_from_8(seg_inode + FSEG_ID))) {
3810
4072
                                fseg_validate_low(seg_inode, &mtr);
3811
4073
 
3812
4074
                                descr_count += flst_get_len(
3822
4084
                        next_node_addr = flst_get_next_addr(
3823
4085
                                seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
3824
4086
                        mtr_commit(&mtr);
3825
 
                }
 
4087
                } while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
3826
4088
 
3827
4089
                node_addr = next_node_addr;
3828
4090
        }
3829
4091
 
3830
4092
        ut_a(descr_count * FSP_EXTENT_SIZE == free_limit);
3831
 
        ut_a(n_used + n_full_frag_pages
3832
 
             == n_used2 + 2* ((free_limit + XDES_DESCRIBED_PER_PAGE - 1)
3833
 
                              / XDES_DESCRIBED_PER_PAGE)
3834
 
             + seg_inode_len_full + seg_inode_len_free);
 
4093
        if (!zip_size) {
 
4094
                ut_a(n_used + n_full_frag_pages
 
4095
                     == n_used2 + 2 * ((free_limit + (UNIV_PAGE_SIZE - 1))
 
4096
                                       / UNIV_PAGE_SIZE)
 
4097
                     + seg_inode_len_full + seg_inode_len_free);
 
4098
        } else {
 
4099
                ut_a(n_used + n_full_frag_pages
 
4100
                     == n_used2 + 2 * ((free_limit + (zip_size - 1))
 
4101
                                       / zip_size)
 
4102
                     + seg_inode_len_full + seg_inode_len_free);
 
4103
        }
3835
4104
        ut_a(frag_n_used == n_used);
3836
4105
 
3837
4106
        mtr_commit(&mtr2);
3841
4110
 
3842
4111
/***********************************************************************
3843
4112
Prints info of a file space. */
3844
 
 
 
4113
UNIV_INTERN
3845
4114
void
3846
4115
fsp_print(
3847
4116
/*======*/
3850
4119
        fsp_header_t*   header;
3851
4120
        fseg_inode_t*   seg_inode;
3852
4121
        page_t*         seg_inode_page;
 
4122
        rw_lock_t*      latch;
 
4123
        ulint           flags;
 
4124
        ulint           zip_size;
3853
4125
        ulint           size;
3854
4126
        ulint           free_limit;
3855
4127
        ulint           frag_n_used;
3866
4138
        mtr_t           mtr;
3867
4139
        mtr_t           mtr2;
3868
4140
 
 
4141
        latch = fil_space_get_latch(space, &flags);
 
4142
        zip_size = dict_table_flags_to_zip_size(flags);
 
4143
 
3869
4144
        /* Start first a mini-transaction mtr2 to lock out all other threads
3870
4145
        from the fsp system */
3871
4146
 
3872
4147
        mtr_start(&mtr2);
3873
4148
 
3874
 
        mtr_x_lock(fil_space_get_latch(space), &mtr2);
 
4149
        mtr_x_lock(latch, &mtr2);
3875
4150
 
3876
4151
        mtr_start(&mtr);
3877
4152
 
3878
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4153
        mtr_x_lock(latch, &mtr);
3879
4154
 
3880
 
        header = fsp_get_space_header(space, &mtr);
 
4155
        header = fsp_get_space_header(space, zip_size, &mtr);
3881
4156
 
3882
4157
        size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr);
3883
4158
 
3900
4175
                "not full frag extents %lu: used pages %lu,"
3901
4176
                " full frag extents %lu\n"
3902
4177
                "first seg id not used %lu %lu\n",
3903
 
                (long) space,
 
4178
                (ulong) space,
3904
4179
                (ulong) size, (ulong) free_limit, (ulong) n_free,
3905
4180
                (ulong) n_free_frag, (ulong) frag_n_used, (ulong) n_full_frag,
3906
4181
                (ulong) seg_id_high, (ulong) seg_id_low);
3910
4185
        /* Print segments */
3911
4186
 
3912
4187
        mtr_start(&mtr);
3913
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4188
        mtr_x_lock(latch, &mtr);
3914
4189
 
3915
 
        header = fsp_get_space_header(space, &mtr);
 
4190
        header = fsp_get_space_header(space, zip_size, &mtr);
3916
4191
 
3917
4192
        node_addr = flst_get_first(header + FSP_SEG_INODES_FULL, &mtr);
3918
4193
 
3920
4195
 
3921
4196
        while (!fil_addr_is_null(node_addr)) {
3922
4197
 
3923
 
                for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) {
 
4198
                n = 0;
 
4199
 
 
4200
                do {
3924
4201
 
3925
4202
                        mtr_start(&mtr);
3926
 
                        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4203
                        mtr_x_lock(latch, &mtr);
3927
4204
 
3928
4205
                        seg_inode_page = fut_get_ptr(
3929
 
                                space, node_addr, RW_X_LATCH, &mtr)
 
4206
                                space, zip_size, node_addr, RW_X_LATCH, &mtr)
3930
4207
                                - FSEG_INODE_PAGE_NODE;
3931
4208
 
3932
4209
                        seg_inode = fsp_seg_inode_page_get_nth_inode(
3933
 
                                seg_inode_page, n, &mtr);
3934
 
                        ut_a(ut_dulint_cmp(
3935
 
                                     mach_read_from_8(seg_inode + FSEG_ID),
3936
 
                                     ut_dulint_zero) != 0);
 
4210
                                seg_inode_page, n, zip_size, &mtr);
 
4211
                        ut_a(!ut_dulint_is_zero(
 
4212
                                     mach_read_from_8(seg_inode + FSEG_ID)));
3937
4213
                        fseg_print_low(seg_inode, &mtr);
3938
4214
 
3939
4215
                        n_segs++;
3941
4217
                        next_node_addr = flst_get_next_addr(
3942
4218
                                seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
3943
4219
                        mtr_commit(&mtr);
3944
 
                }
 
4220
                } while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
3945
4221
 
3946
4222
                node_addr = next_node_addr;
3947
4223
        }
3948
4224
 
3949
4225
        mtr_start(&mtr);
3950
 
        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4226
        mtr_x_lock(latch, &mtr);
3951
4227
 
3952
 
        header = fsp_get_space_header(space, &mtr);
 
4228
        header = fsp_get_space_header(space, zip_size, &mtr);
3953
4229
 
3954
4230
        node_addr = flst_get_first(header + FSP_SEG_INODES_FREE, &mtr);
3955
4231
 
3957
4233
 
3958
4234
        while (!fil_addr_is_null(node_addr)) {
3959
4235
 
3960
 
                for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) {
 
4236
                n = 0;
 
4237
 
 
4238
                do {
3961
4239
 
3962
4240
                        mtr_start(&mtr);
3963
 
                        mtr_x_lock(fil_space_get_latch(space), &mtr);
 
4241
                        mtr_x_lock(latch, &mtr);
3964
4242
 
3965
4243
                        seg_inode_page = fut_get_ptr(
3966
 
                                space, node_addr, RW_X_LATCH, &mtr)
 
4244
                                space, zip_size, node_addr, RW_X_LATCH, &mtr)
3967
4245
                                - FSEG_INODE_PAGE_NODE;
3968
4246
 
3969
4247
                        seg_inode = fsp_seg_inode_page_get_nth_inode(
3970
 
                                seg_inode_page, n, &mtr);
3971
 
                        if (ut_dulint_cmp(
3972
 
                                    mach_read_from_8(seg_inode + FSEG_ID),
3973
 
                                    ut_dulint_zero) != 0) {
 
4248
                                seg_inode_page, n, zip_size, &mtr);
 
4249
                        if (!ut_dulint_is_zero(
 
4250
                                    mach_read_from_8(seg_inode + FSEG_ID))) {
3974
4251
 
3975
4252
                                fseg_print_low(seg_inode, &mtr);
3976
4253
                                n_segs++;
3979
4256
                        next_node_addr = flst_get_next_addr(
3980
4257
                                seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
3981
4258
                        mtr_commit(&mtr);
3982
 
                }
 
4259
                } while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
3983
4260
 
3984
4261
                node_addr = next_node_addr;
3985
4262
        }