~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/trx/trx0sys.c

  • Committer: Stewart Smith
  • Author(s): Marko Mäkelä, Stewart Smith
  • Date: 2010-11-17 05:52:09 UTC
  • mto: (2021.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1971.
  • Revision ID: stewart@flamingspork.com-20101117055209-69m035q6h7e1txrc
Merge Revision revid:marko.makela@oracle.com-20100629113248-fvl48lnzr44z94gg from MySQL InnoDB

Original revid:marko.makela@oracle.com-20100629113248-fvl48lnzr44z94gg

Original Authors: Marko Mkel <marko.makela@oracle.com>
Original commit message:
Bug#52199 utf32: mbminlen=4, mbmaxlen=4, type->mbminlen=0, type->mbmaxlen=4

Merge and adjust a forgotten change to fix this bug.
rb://393 approved by Jimmy Yang
  ------------------------------------------------------------------------
  r3794 | marko | 2009-01-07 14:14:53 +0000 (Wed, 07 Jan 2009) | 18 lines

  branches/6.0: Allow the minimum length of a multi-byte character to be
  up to 4 bytes. (Bug #35391)

  dtype_t, dict_col_t: Replace mbminlen:2, mbmaxlen:3 with mbminmaxlen:5.
  In this way, the 5 bits can hold two values of 0..4, and the storage size
  of the fields will not cross the 64-bit boundary.  Encode the values as
  DATA_MBMAX * mbmaxlen + mbminlen.  Define the auxiliary macros
  DB_MBMINLEN(mbminmaxlen), DB_MBMAXLEN(mbminmaxlen), and
  DB_MINMAXLEN(mbminlen, mbmaxlen).

  Try to trim and pad UTF-16 and UTF-32 with spaces as appropriate.

  Alexander Barkov suggested the use of cs->cset->fill(cs, buff, len, 0x20).
  ha_innobase::store_key_val_for_row() now does that, but the added function
  row_mysql_pad_col() does not, because it doesn't have the MySQL TABLE object.

  rb://49 approved by Heikki Tuuri
  ------------------------------------------------------------------------

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1996, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
90
90
UNIV_INTERN char        trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
91
91
/** Binlog file position, or -1 if unknown */
92
92
UNIV_INTERN ib_int64_t  trx_sys_mysql_bin_log_pos       = -1;
93
 
 
94
 
UNIV_INTERN drizzled::atomic<uint64_t> trx_sys_commit_id;
95
 
 
96
93
/* @} */
97
94
#endif /* !UNIV_HOTBACKUP */
98
95
 
181
178
        byte*   doublewrite)    /*!< in: pointer to the doublewrite buf
182
179
                                header on trx sys page */
183
180
{
184
 
  trx_doublewrite = static_cast<trx_doublewrite_t *>(mem_alloc(sizeof(trx_doublewrite_t)));
 
181
        trx_doublewrite = mem_alloc(sizeof(trx_doublewrite_t));
185
182
 
186
183
        /* Since we now start to use the doublewrite buffer, no need to call
187
184
        fsync() after every write to a data file */
198
195
                doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK1);
199
196
        trx_doublewrite->block2 = mach_read_from_4(
200
197
                doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK2);
201
 
        trx_doublewrite->write_buf_unaligned = static_cast<byte *>(ut_malloc(
202
 
                                                                             (1 + 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE));
 
198
        trx_doublewrite->write_buf_unaligned = ut_malloc(
 
199
                (1 + 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE);
203
200
 
204
 
        trx_doublewrite->write_buf = static_cast<byte *>(ut_align(
205
 
                                                                  trx_doublewrite->write_buf_unaligned, UNIV_PAGE_SIZE));
206
 
        trx_doublewrite->buf_block_arr = static_cast<buf_page_t **>(mem_alloc(
207
 
                                                                             2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * sizeof(void*)));
 
201
        trx_doublewrite->write_buf = ut_align(
 
202
                trx_doublewrite->write_buf_unaligned, UNIV_PAGE_SIZE);
 
203
        trx_doublewrite->buf_block_arr = mem_alloc(
 
204
                2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * sizeof(void*));
208
205
}
209
206
 
210
207
/****************************************************************//**
252
249
{
253
250
        buf_block_t*    block;
254
251
        buf_block_t*    block2;
255
 
#ifdef UNIV_SYNC_DEBUG
256
252
        buf_block_t*    new_block;
257
 
#endif /* UNIV_SYNC_DEBUG */
258
253
        byte*   doublewrite;
259
254
        byte*   fseg_header;
260
255
        ulint   page_no;
357
352
                        the page position in the tablespace, then the page
358
353
                        has not been written to in doublewrite. */
359
354
 
360
 
#ifdef UNIV_SYNC_DEBUG
361
 
                        new_block =
362
 
#endif /* UNIV_SYNC_DEBUG */
363
 
                        buf_page_get(TRX_SYS_SPACE, 0, page_no,
364
 
                                     RW_X_LATCH, &mtr);
 
355
                        new_block = buf_page_get(TRX_SYS_SPACE, 0, page_no,
 
356
                                                 RW_X_LATCH, &mtr);
365
357
                        buf_block_dbg_add_level(new_block,
366
358
                                                SYNC_NO_ORDER_CHECK);
367
359
 
443
435
 
444
436
        /* We do the file i/o past the buffer pool */
445
437
 
446
 
        unaligned_read_buf = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE));
447
 
        read_buf = static_cast<byte *>(ut_align(unaligned_read_buf, UNIV_PAGE_SIZE));
 
438
        unaligned_read_buf = ut_malloc(2 * UNIV_PAGE_SIZE);
 
439
        read_buf = ut_align(unaligned_read_buf, UNIV_PAGE_SIZE);
448
440
 
449
441
        /* Read the trx sys header to check if we are using the doublewrite
450
442
        buffer */
677
669
        mtr_commit(&mtr);
678
670
}
679
671
 
 
672
/*****************************************************************//**
 
673
Updates the offset information about the end of the MySQL binlog entry
 
674
which corresponds to the transaction just being committed. In a MySQL
 
675
replication slave updates the latest master binlog position up to which
 
676
replication has proceeded. */
680
677
UNIV_INTERN
681
678
void
682
 
trx_sys_flush_commit_id(uint64_t commit_id, ulint field, mtr_t* mtr)
 
679
trx_sys_update_mysql_binlog_offset(
 
680
/*===============================*/
 
681
        const char*     file_name,/*!< in: MySQL log file name */
 
682
        ib_int64_t      offset, /*!< in: position in that log file */
 
683
        ulint           field,  /*!< in: offset of the MySQL log info field in
 
684
                                the trx sys header */
 
685
        mtr_t*          mtr)    /*!< in: mtr */
683
686
{
684
 
        trx_sysf_t*     sys_header;
685
 
  
 
687
        trx_sysf_t*     sys_header;
 
688
 
 
689
        if (ut_strlen(file_name) >= TRX_SYS_MYSQL_LOG_NAME_LEN) {
 
690
 
 
691
                /* We cannot fit the name to the 512 bytes we have reserved */
 
692
 
 
693
                return;
 
694
        }
 
695
 
686
696
        sys_header = trx_sysf_get(mtr);
687
697
 
688
 
        mlog_write_ull(sys_header + field + TRX_SYS_DRIZZLE_MAX_COMMIT_ID, 
689
 
                       commit_id, mtr);
 
698
        if (mach_read_from_4(sys_header + field
 
699
                             + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
 
700
            != TRX_SYS_MYSQL_LOG_MAGIC_N) {
 
701
 
 
702
                mlog_write_ulint(sys_header + field
 
703
                                 + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD,
 
704
                                 TRX_SYS_MYSQL_LOG_MAGIC_N,
 
705
                                 MLOG_4BYTES, mtr);
 
706
        }
 
707
 
 
708
        if (0 != strcmp((char*) (sys_header + field + TRX_SYS_MYSQL_LOG_NAME),
 
709
                        file_name)) {
 
710
 
 
711
                mlog_write_string(sys_header + field
 
712
                                  + TRX_SYS_MYSQL_LOG_NAME,
 
713
                                  (byte*) file_name, 1 + ut_strlen(file_name),
 
714
                                  mtr);
 
715
        }
 
716
 
 
717
        if (mach_read_from_4(sys_header + field
 
718
                             + TRX_SYS_MYSQL_LOG_OFFSET_HIGH) > 0
 
719
            || (offset >> 32) > 0) {
 
720
 
 
721
                mlog_write_ulint(sys_header + field
 
722
                                 + TRX_SYS_MYSQL_LOG_OFFSET_HIGH,
 
723
                                 (ulint)(offset >> 32),
 
724
                                 MLOG_4BYTES, mtr);
 
725
        }
 
726
 
 
727
        mlog_write_ulint(sys_header + field
 
728
                         + TRX_SYS_MYSQL_LOG_OFFSET_LOW,
 
729
                         (ulint)(offset & 0xFFFFFFFFUL),
 
730
                         MLOG_4BYTES, mtr);
690
731
}
691
732
 
692
 
 
 
733
/*****************************************************************//**
 
734
Stores the MySQL binlog offset info in the trx system header if
 
735
the magic number shows it valid, and print the info to stderr */
693
736
UNIV_INTERN
694
737
void
695
 
trx_sys_read_commit_id(void)
 
738
trx_sys_print_mysql_binlog_offset(void)
696
739
/*===================================*/
697
740
{
698
 
        trx_sysf_t*     sys_header;
699
 
        mtr_t           mtr;
700
 
 
701
 
        mtr_start(&mtr);
702
 
 
703
 
        sys_header = trx_sysf_get(&mtr);
704
 
 
705
 
        trx_sys_commit_id = mach_read_from_8(sys_header + TRX_SYS_DRIZZLE_LOG_INFO 
706
 
                                             + TRX_SYS_DRIZZLE_MAX_COMMIT_ID);
707
 
 
 
741
        trx_sysf_t*     sys_header;
 
742
        mtr_t           mtr;
 
743
        ulint           trx_sys_mysql_bin_log_pos_high;
 
744
        ulint           trx_sys_mysql_bin_log_pos_low;
 
745
 
 
746
        mtr_start(&mtr);
 
747
 
 
748
        sys_header = trx_sysf_get(&mtr);
 
749
 
 
750
        if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
 
751
                             + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
 
752
            != TRX_SYS_MYSQL_LOG_MAGIC_N) {
 
753
 
 
754
                mtr_commit(&mtr);
 
755
 
 
756
                return;
 
757
        }
 
758
 
 
759
        trx_sys_mysql_bin_log_pos_high = mach_read_from_4(
 
760
                sys_header + TRX_SYS_MYSQL_LOG_INFO
 
761
                + TRX_SYS_MYSQL_LOG_OFFSET_HIGH);
 
762
        trx_sys_mysql_bin_log_pos_low = mach_read_from_4(
 
763
                sys_header + TRX_SYS_MYSQL_LOG_INFO
 
764
                + TRX_SYS_MYSQL_LOG_OFFSET_LOW);
 
765
 
 
766
        trx_sys_mysql_bin_log_pos
 
767
                = (((ib_int64_t)trx_sys_mysql_bin_log_pos_high) << 32)
 
768
                + (ib_int64_t)trx_sys_mysql_bin_log_pos_low;
 
769
 
 
770
        ut_memcpy(trx_sys_mysql_bin_log_name,
 
771
                  sys_header + TRX_SYS_MYSQL_LOG_INFO
 
772
                  + TRX_SYS_MYSQL_LOG_NAME, TRX_SYS_MYSQL_LOG_NAME_LEN);
 
773
 
 
774
        fprintf(stderr,
 
775
                "InnoDB: Last MySQL binlog file position %lu %lu,"
 
776
                " file name %s\n",
 
777
                trx_sys_mysql_bin_log_pos_high, trx_sys_mysql_bin_log_pos_low,
 
778
                trx_sys_mysql_bin_log_name);
 
779
 
 
780
        mtr_commit(&mtr);
 
781
}
 
782
 
 
783
/*****************************************************************//**
 
784
Prints to stderr the MySQL master log offset info in the trx system header if
 
785
the magic number shows it valid. */
 
786
UNIV_INTERN
 
787
void
 
788
trx_sys_print_mysql_master_log_pos(void)
 
789
/*====================================*/
 
790
{
 
791
        trx_sysf_t*     sys_header;
 
792
        mtr_t           mtr;
 
793
 
 
794
        mtr_start(&mtr);
 
795
 
 
796
        sys_header = trx_sysf_get(&mtr);
 
797
 
 
798
        if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
 
799
                             + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
 
800
            != TRX_SYS_MYSQL_LOG_MAGIC_N) {
 
801
 
 
802
                mtr_commit(&mtr);
 
803
 
 
804
                return;
 
805
        }
 
806
 
 
807
        fprintf(stderr,
 
808
                "InnoDB: In a MySQL replication slave the last"
 
809
                " master binlog file\n"
 
810
                "InnoDB: position %lu %lu, file name %s\n",
 
811
                (ulong) mach_read_from_4(sys_header
 
812
                                         + TRX_SYS_MYSQL_MASTER_LOG_INFO
 
813
                                         + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
 
814
                (ulong) mach_read_from_4(sys_header
 
815
                                         + TRX_SYS_MYSQL_MASTER_LOG_INFO
 
816
                                         + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
 
817
                sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
 
818
                + TRX_SYS_MYSQL_LOG_NAME);
 
819
        /* Copy the master log position info to global variables we can
 
820
        use in ha_innobase.cc to initialize glob_mi to right values */
 
821
 
 
822
        ut_memcpy(trx_sys_mysql_master_log_name,
 
823
                  sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
 
824
                  + TRX_SYS_MYSQL_LOG_NAME,
 
825
                  TRX_SYS_MYSQL_LOG_NAME_LEN);
 
826
 
 
827
        trx_sys_mysql_master_log_pos
 
828
                = (((ib_int64_t) mach_read_from_4(
 
829
                            sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
 
830
                            + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)
 
831
                + ((ib_int64_t) mach_read_from_4(
 
832
                           sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
 
833
                           + TRX_SYS_MYSQL_LOG_OFFSET_LOW));
708
834
        mtr_commit(&mtr);
709
835
}
710
836
 
834
960
 
835
961
        mutex_enter(&kernel_mutex);
836
962
 
837
 
        trx_sys = static_cast<trx_sys_t *>(mem_alloc(sizeof(trx_sys_t)));
 
963
        trx_sys = mem_alloc(sizeof(trx_sys_t));
838
964
 
839
965
        sys_header = trx_sysf_get(&mtr);
840
966
 
887
1013
                        (ulong) rows_to_undo, unit);
888
1014
 
889
1015
                fprintf(stderr, "InnoDB: Trx id counter is " TRX_ID_FMT "\n",
890
 
                        trx_sys->max_trx_id);
 
1016
                        (ullint) trx_sys->max_trx_id);
891
1017
        }
892
1018
 
893
1019
        UT_LIST_INIT(trx_sys->view_list);
1210
1336
}
1211
1337
 
1212
1338
#else /* !UNIV_HOTBACKUP */
 
1339
/*****************************************************************//**
 
1340
Prints to stderr the MySQL binlog info in the system header if the
 
1341
magic number shows it valid. */
 
1342
UNIV_INTERN
 
1343
void
 
1344
trx_sys_print_mysql_binlog_offset_from_page(
 
1345
/*========================================*/
 
1346
        const byte*     page)   /*!< in: buffer containing the trx
 
1347
                                system header page, i.e., page number
 
1348
                                TRX_SYS_PAGE_NO in the tablespace */
 
1349
{
 
1350
        const trx_sysf_t*       sys_header;
 
1351
 
 
1352
        sys_header = page + TRX_SYS;
 
1353
 
 
1354
        if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
 
1355
                             + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
 
1356
            == TRX_SYS_MYSQL_LOG_MAGIC_N) {
 
1357
 
 
1358
                fprintf(stderr,
 
1359
                        "ibbackup: Last MySQL binlog file position %lu %lu,"
 
1360
                        " file name %s\n",
 
1361
                        (ulong) mach_read_from_4(
 
1362
                                sys_header + TRX_SYS_MYSQL_LOG_INFO
 
1363
                                + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
 
1364
                        (ulong) mach_read_from_4(
 
1365
                                sys_header + TRX_SYS_MYSQL_LOG_INFO
 
1366
                                + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
 
1367
                        sys_header + TRX_SYS_MYSQL_LOG_INFO
 
1368
                        + TRX_SYS_MYSQL_LOG_NAME);
 
1369
        }
 
1370
}
 
1371
 
1213
1372
 
1214
1373
/* THESE ARE COPIED FROM NON-HOTBACKUP PART OF THE INNODB SOURCE TREE
1215
1374
   (This code duplicaton should be fixed at some point!)
1431
1590
                        "InnoDB: Error: all read views were not closed"
1432
1591
                        " before shutdown:\n"
1433
1592
                        "InnoDB: %lu read views open \n",
1434
 
                        static_cast<ulint>(UT_LIST_GET_LEN(trx_sys->view_list)) - 1);
 
1593
                        UT_LIST_GET_LEN(trx_sys->view_list) - 1);
1435
1594
        }
1436
1595
 
1437
1596
        sess_close(trx_dummy_sess);