1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Applied innodb-5.1-ss269 snapshot.

Fixed BUGS:
  #3300: "UPDATE statement with no index column in where condition locks
    all rows"
    Implement semi-consistent read to reduce lock conflicts at the cost
    of breaking serializability.
    ha_innobase::unlock_row(): reset the "did semi consistent read" flag
    ha_innobase::was_semi_consistent_read(),
    ha_innobase::try_semi_consistent_read(): new methods
    row_prebuilt_t, row_create_prebuilt(): add field row_read_type for
    keeping track of semi-consistent reads
    row_vers_build_for_semi_consistent_read(),
    row_sel_build_committed_vers_for_mysql(): new functions
    row_search_for_mysql(): implement semi-consistent reads

  #9802: "Foreign key checks disallow alter table".
    Added test cases.

  #12456: "Cursor shows incorrect data - DML does not affect,
    probably caching"
    This patch implements a high-granularity read view to be used with
    cursors. In this high-granularity consistent read view modifications 
    done by the creating transaction after the cursor is created or 
   future transactions are not visible. But those modifications that 
   transaction did before the cursor was created are visible.

  #12701: "Support >4GB buffer pool and log files on 64-bit Windows"
    Do not call os_file_create_tmpfile() at runtime. Instead, create all
    tempfiles at startup and guard access to them with mutexes.

  #13778: "If FOREIGN_KEY_CHECKS=0, one can create inconsistent FOREIGN KEYs".
    When FOREIGN_KEY_CHECKS=0 we still need to check that datatypes between
    foreign key references are compatible.

  #14189: "VARBINARY and BINARY variables: trailing space ignored with InnoDB"
    innobase_init(): Assert that
    DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number.
    dtype_get_pad_char(): Do not pad VARBINARY or BINARY columns.
    row_ins_cascade_calc_update_vec(): Refuse ON UPDATE CASCADE when trying
    to change the length of a VARBINARY column that refers to or is referenced
    by a BINARY column. BINARY columns are no longer padded on comparison,
    and thus they cannot be padded on storage either.

  #14747: "Race condition can cause btr_search_drop_page_hash_index() to crash"
    Note that buf_block_t::index should be protected by btr_search_latch
    or an s-latch or x-latch on the index page.
    btr_search_drop_page_hash_index(): Read block->index while holding
    btr_search_latch and use the cached value in the loop.  Remove some
    redundant assertions.

  #15108: "mysqld crashes when innodb_log_file_size is set > 4G"

  #15308: "Problem of Order with Enum Column in Primary Key"

  #15550: "mysqld crashes in printing a FOREIGN KEY error in InnoDB"
    row_ins_foreign_report_add_err(): When printing the parent record,
    use the index in the parent table rather than the index in the child table.

  #15653: "Slow inserts to InnoDB if many thousands of .ibd files"
    Keep track on unflushed modifications to file spaces.  When there are tens
    of thousands of file spaces, flushing all files in fil_flush_file_spaces()
    would be very slow.
    fil_flush_file_spaces(): Only flush unflushed file spaces.
    fil_space_t, fil_system_t: Add a list of unflushed spaces.

  #15991: "innodb-file-per-table + symlink database + rename = cr"
   os_file_handle_error(): Map the error codes EXDEV, ENOTDIR, and EISDIR
   to the new code OS_FILE_PATH_ERROR. Treat this code as OS_FILE_PATH_ERROR.
   This fixes the crash on RENAME TABLE when the .ibd file is a symbolic link
   to a different file system.

  #16157: "InnoDB crashes when main location settings are empty"
    This patch is from Heikki.

  #16298: "InnoDB segfaults in INSERTs in upgrade of 4.0 -> 5.0 tables
    with VARCHAR BINARY"
    dict_load_columns(): Set the charset-collation code
    DATA_MYSQL_BINARY_CHARSET_COLL for those binary string columns
    that lack a charset-collation code, i.e., the tables were created
    with an older version of MySQL/InnoDB than 4.1.2.

  #16229: "MySQL/InnoDB uses full explicit table locks in trigger processing"
    Take a InnoDB table lock only if user has explicitly requested a table
    lock. Added some additional comments to store_lock() and external_lock().

  #16387: "InnoDB crash when dropping a foreign key <table>_ibfk_0"
    Do not mistake TABLENAME_ibfk_0 for auto-generated id.
    dict_table_get_highest_foreign_id(): Ignore foreign constraint
    identifiers starting with the pattern TABLENAME_ibfk_0.

  #16582: "InnoDB: Error in an adaptive hash index pointer to page"
    Account for a race condition when dropping the adaptive hash index
    for a B-tree page.
    btr_search_drop_page_hash_index(): Retry the operation if a hash index
    with different parameters was built meanwhile.  Add diagnostics for the
    case that hash node pointers to the page remain.
    btr_search_info_update_hash(), btr_search_info_update_slow():
    Document the parameter "info" as in/out.

  #16814: "SHOW INNODB STATUS format error in LATEST FOREIGN KEY ERROR
    section"
    Add a missing newline to the LAST FOREIGN KEY ERROR section in SHOW
    INNODB STATUS output.
    dict_foreign_error_report(): Always print a newline after invoking
    dict_print_info_on_foreign_key_in_create_format().

  #16827: "Better InnoDB error message if ibdata files omitted from my.cnf"

  #17126: "CHECK TABLE on InnoDB causes a short hang during check of adaptive
    hash"
    CHECK TABLE blocking other queries, by releasing the btr_search_latch
    periodically during the adaptive hash table validation.

  #17405: "Valgrind: conditional jump or move depends on unititialised values"
    buf_block_init(): Reset magic_n, buf_fix_count and io_fix to avoid
    testing uninitialized variables.
This commit is contained in:
aivanov@mysql.com
2006-03-10 19:22:21 +03:00
parent bdd57aeee0
commit d33b523271
217 changed files with 17729 additions and 14911 deletions

View File

@ -1784,7 +1784,7 @@ innodb_sync_spin_loops 20
show variables like "innodb_thread_concurrency"; show variables like "innodb_thread_concurrency";
Variable_name Value Variable_name Value
innodb_thread_concurrency 20 innodb_thread_concurrency 20
set global innodb_thread_concurrency=1000; set global innodb_thread_concurrency=1001;
show variables like "innodb_thread_concurrency"; show variables like "innodb_thread_concurrency";
Variable_name Value Variable_name Value
innodb_thread_concurrency 1000 innodb_thread_concurrency 1000
@ -2661,6 +2661,32 @@ insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
update t1 set filler = 'boo' where a = 1;
update t2 set filler ='email' where a = 4;
select a,hex(b),hex(c),filler from t1 order by filler;
a hex(b) hex(c) filler
1 61626364656667 61626364656667 boo
4 D0B1 D0B1 eight
4 5B 5B five
4 E880BD E880BD four
4 E880BDD0B1E880BD E880BDD0B1E880BD seven
4 E880BDE880BD E880BDE880BD six
3 71727374757677 71727374757677 three
2 696A6B696C6D6E 696A6B696C6D6E two
select a,hex(b),hex(c),filler from t2 order by filler;
a hex(b) hex(c) filler
4 05630563 05630563 email
4 0563 0563 email
4 05612020 05612020 email
4 01FC 01FC email
4 0120 0120 email
4 00640065 00640065 email
4 00E400E50068 00E400E50068 email
4 0000E400 0000E400 email
4 0000563001FC0563 0000563001FC0563 email
1 0061006200630064006500660067 0061006200630064006500660067 one
3 0071007200730074007500760077 0071007200730074007500760077 three
2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two
drop table t1; drop table t1;
drop table t2; drop table t2;
create table t1 ( create table t1 (
@ -2689,6 +2715,32 @@ insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
update t1 set filler = 'boo' where a = 1;
update t2 set filler ='email' where a = 4;
select a,hex(b),hex(c),filler from t1 order by filler;
a hex(b) hex(c) filler
1 61626364656667 61626364656667 boo
4 D0B1 D0B1 eight
4 5B 5B five
4 E880BD E880BD four
4 E880BDD0B1E880BD E880BDD0B1E880BD seven
4 E880BDE880BD E880BDE880BD six
3 71727374757677 71727374757677 three
2 696A6B696C6D6E 696A6B696C6D6E two
select a,hex(b),hex(c),filler from t2 order by filler;
a hex(b) hex(c) filler
4 05630563 05630563 email
4 0563 0563 email
4 05612020 05612020 email
4 01FC 01FC email
4 0120 0120 email
4 00640065 00640065 email
4 00E400E50068 00E400E50068 email
4 0000E400 0000E400 email
4 0000563001FC0563 0000563001FC0563 email
1 0061006200630064006500660067 0061006200630064006500660067 one
3 0071007200730074007500760077 0071007200730074007500760077 three
2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two
drop table t1; drop table t1;
drop table t2; drop table t2;
create table t1 ( create table t1 (
@ -2717,6 +2769,32 @@ insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
update t1 set filler = 'boo' where a = 1;
update t2 set filler ='email' where a = 4;
select a,hex(b),hex(c),filler from t1 order by filler;
a hex(b) hex(c) filler
1 61626364656667 61626364656667 boo
4 D0B1 D0B1 eight
4 5B 5B five
4 E880BD E880BD four
4 E880BDD0B1E880BD E880BDD0B1E880BD seven
4 E880BDE880BD E880BDE880BD six
3 71727374757677 71727374757677 three
2 696A6B696C6D6E 696A6B696C6D6E two
select a,hex(b),hex(c),filler from t2 order by filler;
a hex(b) hex(c) filler
4 0120 0120 email
4 01FC 01FC email
4 0563 0563 email
4 0000563001FC0563 0000563001FC0563 email
4 0000E400 0000E400 email
4 00640065 00640065 email
4 00E400E50068 00E400E50068 email
4 05612020 05612020 email
4 05630563 05630563 email
1 0061006200630064006500660067 0061006200630064006500660067 one
3 0071007200730074007500760077 0071007200730074007500760077 three
2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two
drop table t1; drop table t1;
drop table t2; drop table t2;
create table t1 ( create table t1 (
@ -2741,9 +2819,92 @@ insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven');
insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight');
insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
update t1 set filler = 'boo' where a = 1;
update t2 set filler ='email' where a = 4;
select a,hex(b),hex(c),filler from t1 order by filler;
a hex(b) hex(c) filler
1 61626364656667 61626364656667 boo
4 D0B1 D0B1 eight
4 5B 5B five
4 E880BD E880BD four
3 71727374757677 71727374757677 three
2 696A6B696C6D6E 696A6B696C6D6E two
select a,hex(b),hex(c),filler from t2 order by filler;
a hex(b) hex(c) filler
4 0000E400 0000E400 email
4 00640065 00640065 email
4 00E400E50068 00E400E50068 email
4 0120 0120 email
4 01FC 01FC email
4 05612020 05612020 email
4 0563 0563 email
1 61626364656667 61626364656667 one
3 71727374757677 71727374757677 three
2 696A6B696C6D6E 696A6B696C6D6E two
drop table t1; drop table t1;
drop table t2; drop table t2;
commit; commit;
set foreign_key_checks=0;
create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
ERROR HY000: Can't create table 'test.t1' (errno: 150)
set foreign_key_checks=1;
drop table t2;
set foreign_key_checks=0;
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
ERROR HY000: Can't create table 'test.t2' (errno: 150)
set foreign_key_checks=1;
drop table t1;
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
create table t1(a varchar(10) primary key) engine = innodb;
alter table t1 modify column a int;
Got one of the listed errors
set foreign_key_checks=1;
drop table t2,t1;
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
alter table t1 convert to character set utf8;
set foreign_key_checks=1;
drop table t2,t1;
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
rename table t3 to t1;
ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
set foreign_key_checks=1;
drop table t2,t3;
create table t1(a int primary key) row_format=redundant engine=innodb;
create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
create table t3(a int primary key) row_format=compact engine=innodb;
create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
insert into t1 values(1);
insert into t3 values(1);
insert into t2 values(2);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
insert into t4 values(2);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
insert into t2 values(1);
insert into t4 values(1);
update t1 set a=2;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
update t2 set a=2;
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
update t3 set a=2;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
update t4 set a=2;
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
truncate t1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
truncate t3;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
truncate t2;
truncate t4;
truncate t1;
truncate t3;
drop table t4,t3,t2,t1;
create table t1 (a varchar(255) character set utf8, create table t1 (a varchar(255) character set utf8,
b varchar(255) character set utf8, b varchar(255) character set utf8,
c varchar(255) character set utf8, c varchar(255) character set utf8,
@ -2757,7 +2918,284 @@ d varchar(255) character set utf8,
e varchar(255) character set utf8, e varchar(255) character set utf8,
key (a,b,c,d,e)) engine=innodb; key (a,b,c,d,e)) engine=innodb;
ERROR 42000: Specified key was too long; max key length is 3072 bytes ERROR 42000: Specified key was too long; max key length is 3072 bytes
End of 5.0 tests create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
insert into t1 values (0x41),(0x4120),(0x4100);
insert into t2 values (0x41),(0x4120),(0x4100);
ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
insert into t2 values (0x41),(0x4120);
insert into t3 values (0x41),(0x4120),(0x4100);
ERROR 23000: Duplicate entry 'A ' for key 'PRIMARY'
insert into t3 values (0x41),(0x4100);
insert into t4 values (0x41),(0x4120),(0x4100);
ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
insert into t4 values (0x41),(0x4100);
select hex(s1) from t1;
hex(s1)
41
4100
4120
select hex(s1) from t2;
hex(s1)
4100
4120
select hex(s1) from t3;
hex(s1)
4100
41
select hex(s1) from t4;
hex(s1)
4100
41
drop table t1,t2,t3,t4;
create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
insert into t2 values(0x42);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
insert into t2 values(0x41);
select hex(s1) from t2;
hex(s1)
4100
update t1 set s1=0x123456 where a=2;
select hex(s1) from t2;
hex(s1)
4100
update t1 set s1=0x12 where a=1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x12345678 where a=1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x123457 where a=1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x1220 where a=1;
select hex(s1) from t2;
hex(s1)
1220
update t1 set s1=0x1200 where a=1;
select hex(s1) from t2;
hex(s1)
1200
update t1 set s1=0x4200 where a=1;
select hex(s1) from t2;
hex(s1)
4200
delete from t1 where a=1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
delete from t1 where a=2;
update t2 set s1=0x4120;
delete from t1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
delete from t1 where a!=3;
select a,hex(s1) from t1;
a hex(s1)
3 4120
select hex(s1) from t2;
hex(s1)
4120
drop table t2,t1;
create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
insert into t1 values(1,0x4100),(2,0x41);
insert into t2 values(0x41);
select hex(s1) from t2;
hex(s1)
41
update t1 set s1=0x1234 where a=1;
select hex(s1) from t2;
hex(s1)
41
update t1 set s1=0x12 where a=2;
select hex(s1) from t2;
hex(s1)
12
delete from t1 where a=1;
delete from t1 where a=2;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
select a,hex(s1) from t1;
a hex(s1)
2 12
select hex(s1) from t2;
hex(s1)
12
drop table t2,t1;
CREATE TABLE t1 (
ind enum('0','1','2') NOT NULL default '0',
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t2 (
ind enum('0','1','2') NOT NULL default '0',
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
INSERT INTO t1 VALUES ('1', ''),('2', '');
INSERT INTO t2 VALUES ('1', ''),('2', '');
SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
hex(ind) hex(string1)
31
32
SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
hex(ind) hex(string1)
0031
0032
drop table t1,t2;
CREATE TABLE t1 (
ind set('0','1','2') NOT NULL default '0',
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t2 (
ind set('0','1','2') NOT NULL default '0',
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
INSERT INTO t1 VALUES ('1', ''),('2', '');
INSERT INTO t2 VALUES ('1', ''),('2', '');
SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
hex(ind) hex(string1)
31
32
SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
hex(ind) hex(string1)
0031
0032
drop table t1,t2;
CREATE TABLE t1 (
ind bit not null,
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t2 (
ind bit not null,
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
insert into t1 values(0,''),(1,'');
insert into t2 values(0,''),(1,'');
select hex(ind),hex(string1) from t1 order by string1;
hex(ind) hex(string1)
0
1
select hex(ind),hex(string1) from t2 order by string1;
hex(ind) hex(string1)
0
1
drop table t1,t2;
create table t2 (
a int, b char(10), filler char(10), primary key(a, b(2))
) character set utf8 engine = innodb;
insert into t2 values (1,'abcdefg','one');
insert into t2 values (2,'ijkilmn','two');
insert into t2 values (3, 'qrstuvw','three');
update t2 set a=5, filler='booo' where a=1;
drop table t2;
create table t2 (
a int, b char(10), filler char(10), primary key(a, b(2))
) character set ucs2 engine = innodb;
insert into t2 values (1,'abcdefg','one');
insert into t2 values (2,'ijkilmn','two');
insert into t2 values (3, 'qrstuvw','three');
update t2 set a=5, filler='booo' where a=1;
drop table t2;
create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8;
insert into t1 values(1,'abcdefg'),(2,'defghijk');
insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
select a,hex(b) from t1 order by b;
a hex(b)
1 61626364656667
2 6465666768696A6B
6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1
7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2
update t1 set b = 'three' where a = 6;
drop table t1;
create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8;
insert into t1 values(1,'abcdefg'),(2,'defghijk');
insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
select a,hex(b) from t1 order by b;
a hex(b)
1 61626364656667
2 6465666768696A6B
6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1
7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2
update t1 set b = 'three' where a = 6;
drop table t1;
CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
CREATE TABLE t2(a INT) ENGINE=InnoDB;
ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL,
KEY `t2_ibfk_0` (`a`),
CONSTRAINT `t2_ibfk_0` FOREIGN KEY (`a`) REFERENCES `t1` (`a`),
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2,t1;
create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
insert into t1(a) values (1),(2),(3);
commit;
set autocommit = 0;
update t1 set b = 5 where a = 2;
create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
set autocommit = 0;
insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
(13),(23),(33),(43),(53),(63),(73),(83),(93),(103),
(14),(24),(34),(44),(54),(64),(74),(84),(94),(104);
commit;
commit;
drop trigger t1t;
drop table t1;
create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
insert into t1(a) values (1),(2),(3);
insert into t2(a) values (1),(2),(3);
insert into t3(a) values (1),(2),(3);
insert into t4(a) values (1),(2),(3);
insert into t3(a) values (5),(7),(8);
insert into t4(a) values (5),(7),(8);
insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
create trigger t1t before insert on t1 for each row begin
INSERT INTO t2 SET a = NEW.a;
end |
create trigger t2t before insert on t2 for each row begin
DELETE FROM t3 WHERE a = NEW.a;
end |
create trigger t3t before delete on t3 for each row begin
UPDATE t4 SET b = b + 1 WHERE a = OLD.a;
end |
create trigger t4t before update on t4 for each row begin
UPDATE t5 SET b = b + 1 where a = NEW.a;
end |
commit;
set autocommit = 0;
update t1 set b = b + 5 where a = 1;
update t2 set b = b + 5 where a = 1;
update t3 set b = b + 5 where a = 1;
update t4 set b = b + 5 where a = 1;
insert into t5(a) values(20);
set autocommit = 0;
insert into t1(a) values(7);
insert into t2(a) values(8);
delete from t2 where a = 3;
update t4 set b = b + 1 where a = 3;
commit;
drop trigger t1t;
drop trigger t2t;
drop trigger t3t;
drop trigger t4t;
drop table t1, t2, t3, t4, t5;
CREATE TABLE t1 ( CREATE TABLE t1 (
field1 varchar(8) NOT NULL DEFAULT '', field1 varchar(8) NOT NULL DEFAULT '',
field2 varchar(8) NOT NULL DEFAULT '', field2 varchar(8) NOT NULL DEFAULT '',

View File

@ -0,0 +1,35 @@
drop table if exists t1,t2;
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
id f_id f
drop table t1,t2;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
a b
1 1
2 2
3 1
4 2
5 1
6 2
update t1 set b = 5 where b = 1;
set autocommit = 0;
select * from t1 where a = 2 and b = 2 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
commit;
commit;
drop table t1;

View File

@ -1273,7 +1273,7 @@ show variables like "innodb_sync_spin_loops";
# Test for innodb_thread_concurrency variable # Test for innodb_thread_concurrency variable
show variables like "innodb_thread_concurrency"; show variables like "innodb_thread_concurrency";
set global innodb_thread_concurrency=1000; set global innodb_thread_concurrency=1001;
show variables like "innodb_thread_concurrency"; show variables like "innodb_thread_concurrency";
set global innodb_thread_concurrency=0; set global innodb_thread_concurrency=0;
show variables like "innodb_thread_concurrency"; show variables like "innodb_thread_concurrency";
@ -1610,6 +1610,10 @@ insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
update t1 set filler = 'boo' where a = 1;
update t2 set filler ='email' where a = 4;
select a,hex(b),hex(c),filler from t1 order by filler;
select a,hex(b),hex(c),filler from t2 order by filler;
drop table t1; drop table t1;
drop table t2; drop table t2;
@ -1639,6 +1643,10 @@ insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
update t1 set filler = 'boo' where a = 1;
update t2 set filler ='email' where a = 4;
select a,hex(b),hex(c),filler from t1 order by filler;
select a,hex(b),hex(c),filler from t2 order by filler;
drop table t1; drop table t1;
drop table t2; drop table t2;
@ -1668,6 +1676,10 @@ insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
update t1 set filler = 'boo' where a = 1;
update t2 set filler ='email' where a = 4;
select a,hex(b),hex(c),filler from t1 order by filler;
select a,hex(b),hex(c),filler from t2 order by filler;
drop table t1; drop table t1;
drop table t2; drop table t2;
@ -1693,10 +1705,102 @@ insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven');
insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight');
insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
update t1 set filler = 'boo' where a = 1;
update t2 set filler ='email' where a = 4;
select a,hex(b),hex(c),filler from t1 order by filler;
select a,hex(b),hex(c),filler from t2 order by filler;
drop table t1; drop table t1;
drop table t2; drop table t2;
commit; commit;
# tests for bugs #9802 and #13778
# test that FKs between invalid types are not accepted
set foreign_key_checks=0;
create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
-- error 1005
create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
set foreign_key_checks=1;
drop table t2;
# test that FKs between different charsets are not accepted in CREATE even
# when f_k_c is 0
set foreign_key_checks=0;
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
-- error 1005
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
set foreign_key_checks=1;
drop table t1;
# test that invalid datatype conversions with ALTER are not allowed
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
create table t1(a varchar(10) primary key) engine = innodb;
-- error 1025,1025
alter table t1 modify column a int;
set foreign_key_checks=1;
drop table t2,t1;
# test that charset conversions with ALTER are allowed when f_k_c is 0
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
alter table t1 convert to character set utf8;
set foreign_key_checks=1;
drop table t2,t1;
# test that RENAME does not allow invalid charsets when f_k_c is 0
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
-- error 1025
rename table t3 to t1;
set foreign_key_checks=1;
drop table t2,t3;
# test that foreign key errors are reported correctly (Bug #15550)
create table t1(a int primary key) row_format=redundant engine=innodb;
create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
create table t3(a int primary key) row_format=compact engine=innodb;
create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
insert into t1 values(1);
insert into t3 values(1);
-- error 1452
insert into t2 values(2);
-- error 1452
insert into t4 values(2);
insert into t2 values(1);
insert into t4 values(1);
-- error 1451
update t1 set a=2;
-- error 1452
update t2 set a=2;
-- error 1451
update t3 set a=2;
-- error 1452
update t4 set a=2;
-- error 1451
truncate t1;
-- error 1451
truncate t3;
truncate t2;
truncate t4;
truncate t1;
truncate t3;
drop table t4,t3,t2,t1;
# #
# Test that we can create a large (>1K) key # Test that we can create a large (>1K) key
# #
@ -1714,7 +1818,272 @@ create table t1 (a varchar(255) character set utf8,
e varchar(255) character set utf8, e varchar(255) character set utf8,
key (a,b,c,d,e)) engine=innodb; key (a,b,c,d,e)) engine=innodb;
--echo End of 5.0 tests
# test the padding of BINARY types and collations (Bug #14189)
create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
insert into t1 values (0x41),(0x4120),(0x4100);
-- error 1062
insert into t2 values (0x41),(0x4120),(0x4100);
insert into t2 values (0x41),(0x4120);
-- error 1062
insert into t3 values (0x41),(0x4120),(0x4100);
insert into t3 values (0x41),(0x4100);
-- error 1062
insert into t4 values (0x41),(0x4120),(0x4100);
insert into t4 values (0x41),(0x4100);
select hex(s1) from t1;
select hex(s1) from t2;
select hex(s1) from t3;
select hex(s1) from t4;
drop table t1,t2,t3,t4;
create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
-- error 1452
insert into t2 values(0x42);
insert into t2 values(0x41);
select hex(s1) from t2;
update t1 set s1=0x123456 where a=2;
select hex(s1) from t2;
-- error 1451
update t1 set s1=0x12 where a=1;
-- error 1451
update t1 set s1=0x12345678 where a=1;
-- error 1451
update t1 set s1=0x123457 where a=1;
update t1 set s1=0x1220 where a=1;
select hex(s1) from t2;
update t1 set s1=0x1200 where a=1;
select hex(s1) from t2;
update t1 set s1=0x4200 where a=1;
select hex(s1) from t2;
-- error 1451
delete from t1 where a=1;
delete from t1 where a=2;
update t2 set s1=0x4120;
-- error 1451
delete from t1;
delete from t1 where a!=3;
select a,hex(s1) from t1;
select hex(s1) from t2;
drop table t2,t1;
create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
insert into t1 values(1,0x4100),(2,0x41);
insert into t2 values(0x41);
select hex(s1) from t2;
update t1 set s1=0x1234 where a=1;
select hex(s1) from t2;
update t1 set s1=0x12 where a=2;
select hex(s1) from t2;
delete from t1 where a=1;
-- error 1451
delete from t1 where a=2;
select a,hex(s1) from t1;
select hex(s1) from t2;
drop table t2,t1;
#
# Test cases for bug #15308 Problem of Order with Enum Column in Primary Key
#
CREATE TABLE t1 (
ind enum('0','1','2') NOT NULL default '0',
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t2 (
ind enum('0','1','2') NOT NULL default '0',
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
INSERT INTO t1 VALUES ('1', ''),('2', '');
INSERT INTO t2 VALUES ('1', ''),('2', '');
SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
drop table t1,t2;
CREATE TABLE t1 (
ind set('0','1','2') NOT NULL default '0',
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t2 (
ind set('0','1','2') NOT NULL default '0',
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
INSERT INTO t1 VALUES ('1', ''),('2', '');
INSERT INTO t2 VALUES ('1', ''),('2', '');
SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
drop table t1,t2;
CREATE TABLE t1 (
ind bit not null,
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t2 (
ind bit not null,
string1 varchar(250) NOT NULL,
PRIMARY KEY (ind)
) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
insert into t1 values(0,''),(1,'');
insert into t2 values(0,''),(1,'');
select hex(ind),hex(string1) from t1 order by string1;
select hex(ind),hex(string1) from t2 order by string1;
drop table t1,t2;
# tests for bug #14056 Column prefix index on UTF-8 primary key column causes 'Can't find record..'
create table t2 (
a int, b char(10), filler char(10), primary key(a, b(2))
) character set utf8 engine = innodb;
insert into t2 values (1,'abcdefg','one');
insert into t2 values (2,'ijkilmn','two');
insert into t2 values (3, 'qrstuvw','three');
update t2 set a=5, filler='booo' where a=1;
drop table t2;
create table t2 (
a int, b char(10), filler char(10), primary key(a, b(2))
) character set ucs2 engine = innodb;
insert into t2 values (1,'abcdefg','one');
insert into t2 values (2,'ijkilmn','two');
insert into t2 values (3, 'qrstuvw','three');
update t2 set a=5, filler='booo' where a=1;
drop table t2;
create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8;
insert into t1 values(1,'abcdefg'),(2,'defghijk');
insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
select a,hex(b) from t1 order by b;
update t1 set b = 'three' where a = 6;
drop table t1;
create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8;
insert into t1 values(1,'abcdefg'),(2,'defghijk');
insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
select a,hex(b) from t1 order by b;
update t1 set b = 'three' where a = 6;
drop table t1;
# Ensure that <tablename>_ibfk_0 is not mistreated as a
# generated foreign key identifier. (Bug #16387)
CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
CREATE TABLE t2(a INT) ENGINE=InnoDB;
ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
SHOW CREATE TABLE t2;
DROP TABLE t2,t1;
#
# Test case for bug #16229: MySQL/InnoDB uses full explicit table locks in trigger processing
#
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
insert into t1(a) values (1),(2),(3);
commit;
connection b;
set autocommit = 0;
update t1 set b = 5 where a = 2;
connection a;
delimiter |;
create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
delimiter ;|
set autocommit = 0;
connection a;
insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
(13),(23),(33),(43),(53),(63),(73),(83),(93),(103),
(14),(24),(34),(44),(54),(64),(74),(84),(94),(104);
connection b;
commit;
connection a;
commit;
drop trigger t1t;
drop table t1;
disconnect a;
disconnect b;
#
# Another trigger test
#
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
insert into t1(a) values (1),(2),(3);
insert into t2(a) values (1),(2),(3);
insert into t3(a) values (1),(2),(3);
insert into t4(a) values (1),(2),(3);
insert into t3(a) values (5),(7),(8);
insert into t4(a) values (5),(7),(8);
insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
delimiter |;
create trigger t1t before insert on t1 for each row begin
INSERT INTO t2 SET a = NEW.a;
end |
create trigger t2t before insert on t2 for each row begin
DELETE FROM t3 WHERE a = NEW.a;
end |
create trigger t3t before delete on t3 for each row begin
UPDATE t4 SET b = b + 1 WHERE a = OLD.a;
end |
create trigger t4t before update on t4 for each row begin
UPDATE t5 SET b = b + 1 where a = NEW.a;
end |
delimiter ;|
commit;
set autocommit = 0;
update t1 set b = b + 5 where a = 1;
update t2 set b = b + 5 where a = 1;
update t3 set b = b + 5 where a = 1;
update t4 set b = b + 5 where a = 1;
insert into t5(a) values(20);
connection b;
set autocommit = 0;
insert into t1(a) values(7);
insert into t2(a) values(8);
delete from t2 where a = 3;
update t4 set b = b + 1 where a = 3;
commit;
drop trigger t1t;
drop trigger t2t;
drop trigger t3t;
drop trigger t4t;
drop table t1, t2, t3, t4, t5;
connection default;
disconnect a;
disconnect b;
# #
# Test that cascading updates leading to duplicate keys give the correct # Test that cascading updates leading to duplicate keys give the correct

View File

@ -0,0 +1 @@
--innodb_locks_unsafe_for_binlog=true

View File

@ -0,0 +1,55 @@
-- source include/have_innodb.inc
#
# Note that these tests uses a innodb_locks_unsafe_for_binlog option.
#
#
# Test cases for a bug #15650
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
drop table t1,t2;
#
# Test case for unlock row bug where unlock releases all locks granted for
# a row. Only the latest lock should be released.
#
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
update t1 set b = 5 where b = 1;
connection b;
set autocommit = 0;
#
# S-lock to records (2,2),(4,2), and (6,2) should not be released in a update
#
--error 1205
select * from t1 where a = 2 and b = 2 for update;
connection a;
commit;
connection b;
commit;
drop table t1;
disconnect a;
disconnect b;

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,12 @@
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /*
This file is based on ha_berkeley.h of MySQL distribution This file is based on ha_berkeley.h of MySQL distribution
@ -34,8 +34,8 @@ typedef struct st_innobase_share {
my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name, my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
uint full_name_len, uint full_name_len,
ulonglong *unused); ulonglong *unused);
/* The class defining a handle to an Innodb table */ /* The class defining a handle to an Innodb table */
class ha_innobase: public handler class ha_innobase: public handler
@ -47,22 +47,20 @@ class ha_innobase: public handler
THD* user_thd; /* the thread handle of the user THD* user_thd; /* the thread handle of the user
currently using the handle; this is currently using the handle; this is
set in external_lock function */ set in external_lock function */
query_id_t last_query_id; /* the latest query id where the query_id_t last_query_id; /* the latest query id where the
handle was used */ handle was used */
THR_LOCK_DATA lock; THR_LOCK_DATA lock;
INNOBASE_SHARE *share; INNOBASE_SHARE *share;
gptr alloc_ptr; byte* upd_buff; /* buffer used in updates */
byte* upd_buff; /* buffer used in updates */ byte* key_val_buff; /* buffer used in converting
byte* key_val_buff; /* buffer used in converting search key values from MySQL format
search key values from MySQL format to Innodb format */
to Innodb format */
ulong upd_and_key_val_buff_len; ulong upd_and_key_val_buff_len;
/* the length of each of the previous /* the length of each of the previous
two buffers */ two buffers */
ulong int_table_flags; ulong int_table_flags;
uint primary_key; uint primary_key;
uint last_dup_key;
ulong start_of_scan; /* this is set to 1 when we are ulong start_of_scan; /* this is set to 1 when we are
starting a table scan but have not starting a table scan but have not
yet fetched any row, else 0 */ yet fetched any row, else 0 */
@ -70,10 +68,9 @@ class ha_innobase: public handler
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX, ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */ or undefined */
uint num_write_row; /* number of write_row() calls */ uint num_write_row; /* number of write_row() calls */
ulong max_supported_row_length(const byte *buf);
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len, uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
const byte* record); const byte* record);
int update_thd(THD* thd); int update_thd(THD* thd);
int change_active_index(uint keynr); int change_active_index(uint keynr);
int general_fetch(byte* buf, uint direction, uint match_mode); int general_fetch(byte* buf, uint direction, uint match_mode);
@ -81,27 +78,27 @@ class ha_innobase: public handler
/* Init values for the class: */ /* Init values for the class: */
public: public:
ha_innobase(TABLE_SHARE *table_arg); ha_innobase(TABLE_SHARE *table_arg);
~ha_innobase() {} ~ha_innobase() {}
/* /*
Get the row type from the storage engine. If this method returns Get the row type from the storage engine. If this method returns
ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used. ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
*/ */
enum row_type get_row_type() const; enum row_type get_row_type() const;
const char* table_type() const { return("InnoDB");} const char* table_type() const { return("InnoDB");}
const char *index_type(uint key_number) { return "BTREE"; } const char *index_type(uint key_number) { return "BTREE"; }
const char** bas_ext() const; const char** bas_ext() const;
ulong table_flags() const { return int_table_flags; } ulong table_flags() const { return int_table_flags; }
ulong index_flags(uint idx, uint part, bool all_parts) const ulong index_flags(uint idx, uint part, bool all_parts) const
{ {
return (HA_READ_NEXT | return (HA_READ_NEXT |
HA_READ_PREV | HA_READ_PREV |
HA_READ_ORDER | HA_READ_ORDER |
HA_READ_RANGE | HA_READ_RANGE |
HA_KEYREAD_ONLY); HA_KEYREAD_ONLY);
} }
uint max_supported_keys() const { return MAX_KEY; } uint max_supported_keys() const { return MAX_KEY; }
/* An InnoDB page must store >= 2 keys; /* An InnoDB page must store >= 2 keys;
a secondary key record must also contain the a secondary key record must also contain the
primary key value: primary key value:
@ -109,116 +106,113 @@ class ha_innobase: public handler
less than 1 / 4 of page size which is 16 kB; less than 1 / 4 of page size which is 16 kB;
but currently MySQL does not work with keys but currently MySQL does not work with keys
whose size is > MAX_KEY_LENGTH */ whose size is > MAX_KEY_LENGTH */
uint max_supported_key_length() const { return 3500; } uint max_supported_key_length() const { return 3500; }
uint max_supported_key_part_length() const; uint max_supported_key_part_length() const;
const key_map *keys_to_use_for_scanning() { return &key_map_full; } const key_map *keys_to_use_for_scanning() { return &key_map_full; }
bool has_transactions() { return 1;} bool has_transactions() { return 1;}
int open(const char *name, int mode, uint test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int close(void); int close(void);
double scan_time(); double scan_time();
double read_time(uint index, uint ranges, ha_rows rows); double read_time(uint index, uint ranges, ha_rows rows);
int write_row(byte * buf); int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data); int update_row(const byte * old_data, byte * new_data);
int delete_row(const byte * buf); int delete_row(const byte * buf);
bool was_semi_consistent_read(); bool was_semi_consistent_read();
void try_semi_consistent_read(bool yes); void try_semi_consistent_read(bool yes);
void unlock_row(); void unlock_row();
int index_init(uint index, bool sorted); int index_init(uint index, bool sorted);
int index_end(); int index_end();
int index_read(byte * buf, const byte * key, int index_read(byte * buf, const byte * key,
uint key_len, enum ha_rkey_function find_flag); uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint index, const byte * key, int index_read_idx(byte * buf, uint index, const byte * key,
uint key_len, enum ha_rkey_function find_flag); uint key_len, enum ha_rkey_function find_flag);
int index_read_last(byte * buf, const byte * key, uint key_len); int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf); int index_next(byte * buf);
int index_next_same(byte * buf, const byte *key, uint keylen); int index_next_same(byte * buf, const byte *key, uint keylen);
int index_prev(byte * buf); int index_prev(byte * buf);
int index_first(byte * buf); int index_first(byte * buf);
int index_last(byte * buf); int index_last(byte * buf);
int rnd_init(bool scan); int rnd_init(bool scan);
int rnd_end(); int rnd_end();
int rnd_next(byte *buf); int rnd_next(byte *buf);
int rnd_pos(byte * buf, byte *pos); int rnd_pos(byte * buf, byte *pos);
void position(const byte *record); void position(const byte *record);
void info(uint); void info(uint);
int analyze(THD* thd,HA_CHECK_OPT* check_opt); int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int optimize(THD* thd,HA_CHECK_OPT* check_opt); int optimize(THD* thd,HA_CHECK_OPT* check_opt);
int discard_or_import_tablespace(my_bool discard); int discard_or_import_tablespace(my_bool discard);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
int transactional_table_lock(THD *thd, int lock_type); int transactional_table_lock(THD *thd, int lock_type);
int start_stmt(THD *thd, thr_lock_type lock_type); int start_stmt(THD *thd, thr_lock_type lock_type);
int ha_retrieve_all_cols() int ha_retrieve_all_cols()
{ {
ha_set_all_bits_in_read_set(); ha_set_all_bits_in_read_set();
return extra(HA_EXTRA_RETRIEVE_ALL_COLS); return extra(HA_EXTRA_RETRIEVE_ALL_COLS);
} }
int ha_retrieve_all_pk() int ha_retrieve_all_pk()
{ {
ha_set_primary_key_in_read_set(); ha_set_primary_key_in_read_set();
return extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); return extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
} }
void position(byte *record); void position(byte *record);
ha_rows records_in_range(uint inx, key_range *min_key, key_range ha_rows records_in_range(uint inx, key_range *min_key, key_range
*max_key); *max_key);
ha_rows estimate_rows_upper_bound(); ha_rows estimate_rows_upper_bound();
int create(const char *name, register TABLE *form, int create(const char *name, register TABLE *form,
HA_CREATE_INFO *create_info); HA_CREATE_INFO *create_info);
int delete_all_rows(); int delete_all_rows();
int delete_table(const char *name); int delete_table(const char *name);
int rename_table(const char* from, const char* to); int rename_table(const char* from, const char* to);
int check(THD* thd, HA_CHECK_OPT* check_opt); int check(THD* thd, HA_CHECK_OPT* check_opt);
char* update_table_comment(const char* comment); char* update_table_comment(const char* comment);
char* get_foreign_key_create_info(); char* get_foreign_key_create_info();
int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
bool can_switch_engines(); bool can_switch_engines();
uint referenced_by_foreign_key(); uint referenced_by_foreign_key();
void free_foreign_key_create_info(char* str); void free_foreign_key_create_info(char* str);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); enum thr_lock_type lock_type);
void init_table_handle_for_HANDLER(); void init_table_handle_for_HANDLER();
ulonglong get_auto_increment(); ulonglong get_auto_increment();
int reset_auto_increment(ulonglong value); int reset_auto_increment(ulonglong value);
virtual bool get_error_message(int error, String *buf); virtual bool get_error_message(int error, String *buf);
uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; } uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; }
/* /*
ask handler about permission to cache table during query registration ask handler about permission to cache table during query registration
*/ */
my_bool register_query_cache_table(THD *thd, char *table_key, my_bool register_query_cache_table(THD *thd, char *table_key,
uint key_length, uint key_length,
qc_engine_callback *call_back, qc_engine_callback *call_back,
ulonglong *engine_data) ulonglong *engine_data)
{ {
*call_back= innobase_query_caching_of_table_permitted; *call_back= innobase_query_caching_of_table_permitted;
*engine_data= 0; *engine_data= 0;
return innobase_query_caching_of_table_permitted(thd, table_key, return innobase_query_caching_of_table_permitted(thd, table_key,
key_length, key_length,
engine_data); engine_data);
} }
static char *get_mysql_bin_log_name(); static char *get_mysql_bin_log_name();
static ulonglong get_mysql_bin_log_pos(); static ulonglong get_mysql_bin_log_pos();
bool primary_key_is_clustered() { return true; } bool primary_key_is_clustered() { return true; }
int cmp_ref(const byte *ref1, const byte *ref2); int cmp_ref(const byte *ref1, const byte *ref2);
bool check_if_incompatible_data(HA_CREATE_INFO *info, bool check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes); uint table_changes);
}; };
extern SHOW_VAR innodb_status_variables[]; extern SHOW_VAR innodb_status_variables[];
extern uint innobase_init_flags, innobase_lock_type;
extern uint innobase_flush_log_at_trx_commit; extern uint innobase_flush_log_at_trx_commit;
extern ulong innobase_cache_size, innobase_fast_shutdown; extern ulong innobase_fast_shutdown;
extern ulong innobase_large_page_size; extern ulong innobase_large_page_size;
extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
extern long innobase_lock_scan_time;
extern long innobase_mirrored_log_groups, innobase_log_files_in_group; extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern longlong innobase_buffer_pool_size, innobase_log_file_size; extern longlong innobase_buffer_pool_size, innobase_log_file_size;
extern long innobase_log_buffer_size; extern long innobase_log_buffer_size;
@ -232,17 +226,18 @@ extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
extern char *innobase_unix_file_flush_method; extern char *innobase_unix_file_flush_method;
/* The following variables have to be my_bool for SHOW VARIABLES to work */ /* The following variables have to be my_bool for SHOW VARIABLES to work */
extern my_bool innobase_log_archive, extern my_bool innobase_log_archive,
innobase_use_doublewrite, innobase_use_doublewrite,
innobase_use_checksums, innobase_use_checksums,
innobase_use_large_pages, innobase_use_large_pages,
innobase_use_native_aio, innobase_use_native_aio,
innobase_file_per_table, innobase_locks_unsafe_for_binlog, innobase_file_per_table, innobase_locks_unsafe_for_binlog,
innobase_create_status_file; innobase_create_status_file;
extern my_bool innobase_very_fast_shutdown; /* set this to 1 just before extern my_bool innobase_very_fast_shutdown; /* set this to 1 just before
calling innobase_end() if you want calling innobase_end() if
InnoDB to shut down without you want InnoDB to shut down
flushing the buffer pool: this without flushing the buffer
is equivalent to a 'crash' */ pool: this is equivalent to
a 'crash' */
extern "C" { extern "C" {
extern ulong srv_max_buf_pool_modified_pct; extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag; extern ulong srv_max_purge_lag;
@ -254,8 +249,6 @@ extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency; extern ulong srv_commit_concurrency;
} }
extern TYPELIB innobase_lock_typelib;
bool innobase_init(void); bool innobase_init(void);
int innobase_end(ha_panic_function type); int innobase_end(ha_panic_function type);
bool innobase_flush_logs(void); bool innobase_flush_logs(void);
@ -267,10 +260,10 @@ uint innobase_get_free_space(void);
*/ */
#if 0 #if 0
int innobase_report_binlog_offset_and_commit( int innobase_report_binlog_offset_and_commit(
THD* thd, THD* thd,
void* trx_handle, void* trx_handle,
char* log_file_name, char* log_file_name,
my_off_t end_offset); my_off_t end_offset);
int innobase_commit_complete(void* trx_handle); int innobase_commit_complete(void* trx_handle);
void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset); void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
#endif #endif
@ -300,9 +293,9 @@ This function is used to recover X/Open XA distributed transactions */
int innobase_xa_recover( int innobase_xa_recover(
/*====================*/ /*====================*/
/* out: number of prepared transactions /* out: number of prepared transactions
stored in xid_list */ stored in xid_list */
XID* xid_list, /* in/out: prepared transactions */ XID* xid_list, /* in/out: prepared transactions */
uint len); /* in: number of slots in xid_list */ uint len); /* in: number of slots in xid_list */
/*********************************************************************** /***********************************************************************
@ -323,16 +316,13 @@ int innobase_rollback_by_xid(
XID *xid); /* in : X/Open XA Transaction Identification */ XID *xid); /* in : X/Open XA Transaction Identification */
int innobase_xa_end(THD *thd);
int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name, int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name,
my_off_t end_offset); my_off_t end_offset);
/*********************************************************************** /***********************************************************************
Create a consistent view for a cursor based on current transaction Create a consistent view for a cursor based on current transaction
which is created if the corresponding MySQL thread still lacks one. which is created if the corresponding MySQL thread still lacks one.
This consistent view is then used inside of MySQL when accessing records This consistent view is then used inside of MySQL when accessing records
using a cursor. */ using a cursor. */
void* void*
@ -342,7 +332,7 @@ innobase_create_cursor_view(void);
/*********************************************************************** /***********************************************************************
Close the given consistent cursor view of a transaction and restore Close the given consistent cursor view of a transaction and restore
global read view to a transaction read view. Transaction is created if the global read view to a transaction read view. Transaction is created if the
corresponding MySQL thread still lacks one. */ corresponding MySQL thread still lacks one. */
void void
@ -351,8 +341,8 @@ innobase_close_cursor_view(
void* curview); /* in: Consistent read view to be closed */ void* curview); /* in: Consistent read view to be closed */
/*********************************************************************** /***********************************************************************
Set the given consistent cursor view to a transaction which is created Set the given consistent cursor view to a transaction which is created
if the corresponding MySQL thread still lacks one. If the given if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is consistent cursor view is NULL global read view of a transaction is
restored to a transaction read view. */ restored to a transaction read view. */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ btr_pcur_create_for_mysql(void)
pcur->btr_cur.index = NULL; pcur->btr_cur.index = NULL;
btr_pcur_init(pcur); btr_pcur_init(pcur);
return(pcur); return(pcur);
} }
@ -53,7 +53,7 @@ btr_pcur_free_for_mysql(
cursor->old_rec = NULL; cursor->old_rec = NULL;
cursor->old_n_fields = 0; cursor->old_n_fields = 0;
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
cursor->latch_mode = BTR_NO_LATCHES; cursor->latch_mode = BTR_NO_LATCHES;
cursor->pos_state = BTR_PCUR_NOT_POSITIONED; cursor->pos_state = BTR_PCUR_NOT_POSITIONED;
@ -79,7 +79,7 @@ btr_pcur_store_position(
dict_tree_t* tree; dict_tree_t* tree;
page_t* page; page_t* page;
ulint offs; ulint offs;
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@ -92,9 +92,9 @@ btr_pcur_store_position(
offs = ut_align_offset(rec, UNIV_PAGE_SIZE); offs = ut_align_offset(rec, UNIV_PAGE_SIZE);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page), ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_S_FIX) MTR_MEMO_PAGE_S_FIX)
|| mtr_memo_contains(mtr, buf_block_align(page), || mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
ut_a(cursor->latch_mode != BTR_NO_LATCHES); ut_a(cursor->latch_mode != BTR_NO_LATCHES);
if (UNIV_UNLIKELY(page_get_n_recs(page) == 0)) { if (UNIV_UNLIKELY(page_get_n_recs(page) == 0)) {
@ -115,7 +115,7 @@ btr_pcur_store_position(
} }
return; return;
} }
if (page_rec_is_supremum_low(offs)) { if (page_rec_is_supremum_low(offs)) {
@ -138,7 +138,7 @@ btr_pcur_store_position(
&cursor->old_rec_buf, &cursor->old_rec_buf,
&cursor->buf_size); &cursor->buf_size);
cursor->block_when_stored = buf_block_align(page); cursor->block_when_stored = buf_block_align(page);
cursor->modify_clock = buf_block_get_modify_clock( cursor->modify_clock = buf_block_get_modify_clock(
cursor->block_when_stored); cursor->block_when_stored);
} }
@ -158,17 +158,17 @@ btr_pcur_copy_stored_position(
mem_free(pcur_receive->old_rec_buf); mem_free(pcur_receive->old_rec_buf);
} }
ut_memcpy((byte*)pcur_receive, (byte*)pcur_donate, sizeof(btr_pcur_t)); ut_memcpy(pcur_receive, pcur_donate, sizeof(btr_pcur_t));
if (pcur_donate->old_rec_buf) { if (pcur_donate->old_rec_buf) {
pcur_receive->old_rec_buf = mem_alloc(pcur_donate->buf_size); pcur_receive->old_rec_buf = mem_alloc(pcur_donate->buf_size);
ut_memcpy(pcur_receive->old_rec_buf, pcur_donate->old_rec_buf, ut_memcpy(pcur_receive->old_rec_buf, pcur_donate->old_rec_buf,
pcur_donate->buf_size); pcur_donate->buf_size);
pcur_receive->old_rec = pcur_receive->old_rec_buf pcur_receive->old_rec = pcur_receive->old_rec_buf
+ (pcur_donate->old_rec - pcur_donate->old_rec_buf); + (pcur_donate->old_rec - pcur_donate->old_rec_buf);
} }
pcur_receive->old_n_fields = pcur_donate->old_n_fields; pcur_receive->old_n_fields = pcur_donate->old_n_fields;
} }
@ -195,7 +195,7 @@ btr_pcur_restore_position(
whose ordering fields are identical to whose ordering fields are identical to
the ones of the original user record */ the ones of the original user record */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /* in: detached persistent cursor */ btr_pcur_t* cursor, /* in: detached persistent cursor */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
dict_tree_t* tree; dict_tree_t* tree;
@ -206,21 +206,21 @@ btr_pcur_restore_position(
mem_heap_t* heap; mem_heap_t* heap;
if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED) if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
|| UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED || UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED
&& cursor->pos_state != BTR_PCUR_IS_POSITIONED)) { && cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t)); ut_print_buf(stderr, cursor, sizeof(btr_pcur_t));
if (cursor->trx_if_known) { if (cursor->trx_if_known) {
trx_print(stderr, cursor->trx_if_known, 0); trx_print(stderr, cursor->trx_if_known, 0);
} }
ut_error; ut_error;
} }
if (UNIV_UNLIKELY(cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE if (UNIV_UNLIKELY(cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) { || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
/* In these cases we do not try an optimistic restoration, /* In these cases we do not try an optimistic restoration,
but always do a search */ but always do a search */
btr_cur_open_at_index_side( btr_cur_open_at_index_side(
cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE, cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
@ -232,7 +232,7 @@ btr_pcur_restore_position(
return(FALSE); return(FALSE);
} }
ut_a(cursor->old_rec); ut_a(cursor->old_rec);
ut_a(cursor->old_n_fields); ut_a(cursor->old_n_fields);
@ -241,10 +241,10 @@ btr_pcur_restore_position(
if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF) if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF)
|| UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) { || UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) {
/* Try optimistic restoration */ /* Try optimistic restoration */
if (UNIV_LIKELY(buf_page_optimistic_get(latch_mode, if (UNIV_LIKELY(buf_page_optimistic_get(latch_mode,
cursor->block_when_stored, page, cursor->block_when_stored, page,
cursor->modify_clock, mtr))) { cursor->modify_clock, mtr))) {
cursor->pos_state = BTR_PCUR_IS_POSITIONED; cursor->pos_state = BTR_PCUR_IS_POSITIONED;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(page, SYNC_TREE_NODE); buf_page_dbg_add_level(page, SYNC_TREE_NODE);
@ -285,14 +285,14 @@ btr_pcur_restore_position(
/* If optimistic restoration did not succeed, open the cursor anew */ /* If optimistic restoration did not succeed, open the cursor anew */
heap = mem_heap_create(256); heap = mem_heap_create(256);
tree = btr_cur_get_tree(btr_pcur_get_btr_cur(cursor)); tree = btr_cur_get_tree(btr_pcur_get_btr_cur(cursor));
tuple = dict_tree_build_data_tuple(tree, cursor->old_rec, tuple = dict_tree_build_data_tuple(tree, cursor->old_rec,
cursor->old_n_fields, heap); cursor->old_n_fields, heap);
/* Save the old search mode of the cursor */ /* Save the old search mode of the cursor */
old_mode = cursor->search_mode; old_mode = cursor->search_mode;
if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) { if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) {
mode = PAGE_CUR_LE; mode = PAGE_CUR_LE;
} else if (cursor->rel_pos == BTR_PCUR_AFTER) { } else if (cursor->rel_pos == BTR_PCUR_AFTER) {
@ -304,13 +304,13 @@ btr_pcur_restore_position(
btr_pcur_open_with_no_init(btr_pcur_get_btr_cur(cursor)->index, tuple, btr_pcur_open_with_no_init(btr_pcur_get_btr_cur(cursor)->index, tuple,
mode, latch_mode, cursor, 0, mtr); mode, latch_mode, cursor, 0, mtr);
/* Restore the old search mode */ /* Restore the old search mode */
cursor->search_mode = old_mode; cursor->search_mode = old_mode;
if (cursor->rel_pos == BTR_PCUR_ON if (cursor->rel_pos == BTR_PCUR_ON
&& btr_pcur_is_on_user_rec(cursor, mtr) && btr_pcur_is_on_user_rec(cursor, mtr)
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor), && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor), rec_get_offsets(btr_pcur_get_rec(cursor),
btr_pcur_get_btr_cur(cursor)->index, btr_pcur_get_btr_cur(cursor)->index,
NULL, ULINT_UNDEFINED, &heap))) { NULL, ULINT_UNDEFINED, &heap))) {
@ -335,7 +335,7 @@ btr_pcur_restore_position(
/* We have to store new position information, modify_clock etc., /* We have to store new position information, modify_clock etc.,
to the cursor because it can now be on a different page, the record to the cursor because it can now be on a different page, the record
under it may have been removed, etc. */ under it may have been removed, etc. */
btr_pcur_store_position(cursor, mtr); btr_pcur_store_position(cursor, mtr);
return(FALSE); return(FALSE);
@ -358,12 +358,12 @@ btr_pcur_release_leaf(
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor)); page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
btr_leaf_page_release(page, cursor->latch_mode, mtr); btr_leaf_page_release(page, cursor->latch_mode, mtr);
cursor->latch_mode = BTR_NO_LATCHES; cursor->latch_mode = BTR_NO_LATCHES;
cursor->pos_state = BTR_PCUR_WAS_POSITIONED; cursor->pos_state = BTR_PCUR_WAS_POSITIONED;
} }
@ -386,25 +386,25 @@ btr_pcur_move_to_next_page(
page_t* page; page_t* page;
page_t* next_page; page_t* next_page;
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
ut_ad(btr_pcur_is_after_last_on_page(cursor, mtr)); ut_ad(btr_pcur_is_after_last_on_page(cursor, mtr));
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
page = btr_pcur_get_page(cursor); page = btr_pcur_get_page(cursor);
next_page_no = btr_page_get_next(page, mtr); next_page_no = btr_page_get_next(page, mtr);
space = buf_frame_get_space_id(page); space = buf_frame_get_space_id(page);
ut_ad(next_page_no != FIL_NULL); ut_ad(next_page_no != FIL_NULL);
next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr); next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr);
ut_a(page_is_comp(next_page) == page_is_comp(page)); ut_a(page_is_comp(next_page) == page_is_comp(page));
buf_block_align(next_page)->check_index_page_at_flush = TRUE; buf_block_align(next_page)->check_index_page_at_flush = TRUE;
btr_leaf_page_release(page, cursor->latch_mode, mtr); btr_leaf_page_release(page, cursor->latch_mode, mtr);
page_cur_set_before_first(next_page, btr_pcur_get_page_cur(cursor)); page_cur_set_before_first(next_page, btr_pcur_get_page_cur(cursor));
page_check_dir(next_page); page_check_dir(next_page);
@ -436,11 +436,11 @@ btr_pcur_move_backward_from_page(
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
ut_ad(btr_pcur_is_before_first_on_page(cursor, mtr)); ut_ad(btr_pcur_is_before_first_on_page(cursor, mtr));
ut_ad(!btr_pcur_is_before_first_in_tree(cursor, mtr)); ut_ad(!btr_pcur_is_before_first_in_tree(cursor, mtr));
latch_mode = cursor->latch_mode; latch_mode = cursor->latch_mode;
if (latch_mode == BTR_SEARCH_LEAF) { if (latch_mode == BTR_SEARCH_LEAF) {
latch_mode2 = BTR_SEARCH_PREV; latch_mode2 = BTR_SEARCH_PREV;
@ -459,7 +459,7 @@ btr_pcur_move_backward_from_page(
mtr_start(mtr); mtr_start(mtr);
btr_pcur_restore_position(latch_mode2, cursor, mtr); btr_pcur_restore_position(latch_mode2, cursor, mtr);
page = btr_pcur_get_page(cursor); page = btr_pcur_get_page(cursor);
@ -467,7 +467,7 @@ btr_pcur_move_backward_from_page(
space = buf_frame_get_space_id(page); space = buf_frame_get_space_id(page);
if (btr_pcur_is_before_first_on_page(cursor, mtr) if (btr_pcur_is_before_first_on_page(cursor, mtr)
&& (prev_page_no != FIL_NULL)) { && (prev_page_no != FIL_NULL)) {
prev_page = btr_pcur_get_btr_cur(cursor)->left_page; prev_page = btr_pcur_get_btr_cur(cursor)->left_page;
@ -476,11 +476,11 @@ btr_pcur_move_backward_from_page(
page_cur_set_after_last(prev_page, page_cur_set_after_last(prev_page,
btr_pcur_get_page_cur(cursor)); btr_pcur_get_page_cur(cursor));
} else if (prev_page_no != FIL_NULL) { } else if (prev_page_no != FIL_NULL) {
/* The repositioned cursor did not end on an infimum record on /* The repositioned cursor did not end on an infimum record on
a page. Cursor repositioning acquired a latch also on the a page. Cursor repositioning acquired a latch also on the
previous page, but we do not need the latch: release it. */ previous page, but we do not need the latch: release it. */
prev_page = btr_pcur_get_btr_cur(cursor)->left_page; prev_page = btr_pcur_get_btr_cur(cursor)->left_page;
btr_leaf_page_release(prev_page, latch_mode, mtr); btr_leaf_page_release(prev_page, latch_mode, mtr);
@ -506,7 +506,7 @@ btr_pcur_move_to_prev(
{ {
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
if (btr_pcur_is_before_first_on_page(cursor, mtr)) { if (btr_pcur_is_before_first_on_page(cursor, mtr)) {
@ -542,14 +542,14 @@ btr_pcur_open_on_user_rec(
ulint mode, /* in: PAGE_CUR_L, ... */ ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF or ulint latch_mode, /* in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */ BTR_MODIFY_LEAF */
btr_pcur_t* cursor, /* in: memory buffer for persistent btr_pcur_t* cursor, /* in: memory buffer for persistent
cursor */ cursor */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
btr_pcur_open(index, tuple, mode, latch_mode, cursor, mtr); btr_pcur_open(index, tuple, mode, latch_mode, cursor, mtr);
if ((mode == PAGE_CUR_GE) || (mode == PAGE_CUR_G)) { if ((mode == PAGE_CUR_GE) || (mode == PAGE_CUR_G)) {
if (btr_pcur_is_after_last_on_page(cursor, mtr)) { if (btr_pcur_is_after_last_on_page(cursor, mtr)) {
btr_pcur_move_to_next_user_rec(cursor, mtr); btr_pcur_move_to_next_user_rec(cursor, mtr);

View File

@ -103,7 +103,7 @@ btr_search_check_free_space_in_heap(void)
table = btr_search_sys->hash_index; table = btr_search_sys->hash_index;
heap = table->heap; heap = table->heap;
/* Note that we peek the value of heap->free_block without reserving /* Note that we peek the value of heap->free_block without reserving
the latch: this is ok, because we will not guarantee that there will the latch: this is ok, because we will not guarantee that there will
be enough free space in the hash table. */ be enough free space in the hash table. */
@ -133,9 +133,9 @@ btr_search_sys_create(
{ {
/* We allocate the search latch from dynamic memory: /* We allocate the search latch from dynamic memory:
see above at the global variable definition */ see above at the global variable definition */
btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t)); btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
rw_lock_create(&btr_search_latch); rw_lock_create(&btr_search_latch);
btr_search_sys = mem_alloc(sizeof(btr_search_sys_t)); btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
@ -169,10 +169,10 @@ btr_search_info_create(
info->last_hash_succ = FALSE; info->last_hash_succ = FALSE;
info->n_hash_succ = 0; info->n_hash_succ = 0;
info->n_hash_fail = 0; info->n_hash_fail = 0;
info->n_patt_succ = 0; info->n_patt_succ = 0;
info->n_searches = 0; info->n_searches = 0;
/* Set some sensible values */ /* Set some sensible values */
info->n_fields = 1; info->n_fields = 1;
@ -191,7 +191,7 @@ static
void void
btr_search_info_update_hash( btr_search_info_update_hash(
/*========================*/ /*========================*/
btr_search_t* info, /* in: search info */ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */ btr_cur_t* cursor) /* in: cursor which was just positioned */
{ {
dict_index_t* index; dict_index_t* index;
@ -223,7 +223,7 @@ btr_search_info_update_hash(
hash prefix */ hash prefix */
if (info->n_fields >= n_unique && cursor->up_match >= n_unique) { if (info->n_fields >= n_unique && cursor->up_match >= n_unique) {
info->n_hash_potential++; info->n_hash_potential++;
return; return;
@ -244,20 +244,20 @@ btr_search_info_update_hash(
if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp > 0) if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp > 0)
|| (info->side == BTR_SEARCH_RIGHT_SIDE && cmp <= 0)) { || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp <= 0)) {
goto set_new_recomm; goto set_new_recomm;
} }
info->n_hash_potential++; info->n_hash_potential++;
return; return;
set_new_recomm: set_new_recomm:
/* We have to set a new recommendation; skip the hash analysis /* We have to set a new recommendation; skip the hash analysis
for a while to avoid unnecessary CPU time usage when there is no for a while to avoid unnecessary CPU time usage when there is no
chance for success */ chance for success */
info->hash_analysis = 0; info->hash_analysis = 0;
cmp = ut_pair_cmp(cursor->up_match, cursor->up_bytes, cmp = ut_pair_cmp(cursor->up_match, cursor->up_bytes,
cursor->low_match, cursor->low_bytes); cursor->low_match, cursor->low_bytes);
if (cmp == 0) { if (cmp == 0) {
@ -282,7 +282,7 @@ set_new_recomm:
info->n_fields = cursor->low_match + 1; info->n_fields = cursor->low_match + 1;
info->n_bytes = 0; info->n_bytes = 0;
} else { } else {
info->n_fields = cursor->low_match; info->n_fields = cursor->low_match;
info->n_bytes = cursor->low_bytes + 1; info->n_bytes = cursor->low_bytes + 1;
} }
@ -300,7 +300,7 @@ set_new_recomm:
info->n_fields = cursor->up_match + 1; info->n_fields = cursor->up_match + 1;
info->n_bytes = 0; info->n_bytes = 0;
} else { } else {
info->n_fields = cursor->up_match; info->n_fields = cursor->up_match;
info->n_bytes = cursor->up_bytes + 1; info->n_bytes = cursor->up_bytes + 1;
} }
@ -308,7 +308,7 @@ set_new_recomm:
info->side = BTR_SEARCH_RIGHT_SIDE; info->side = BTR_SEARCH_RIGHT_SIDE;
} }
} }
/************************************************************************* /*************************************************************************
Updates the block search info on hash successes. NOTE that info and Updates the block search info on hash successes. NOTE that info and
block->n_hash_helps, n_fields, n_bytes, side are NOT protected by any block->n_hash_helps, n_fields, n_bytes, side are NOT protected by any
@ -337,19 +337,19 @@ btr_search_update_block_hash_info(
ut_a(info->magic_n == BTR_SEARCH_MAGIC_N); ut_a(info->magic_n == BTR_SEARCH_MAGIC_N);
if ((block->n_hash_helps > 0) if ((block->n_hash_helps > 0)
&& (info->n_hash_potential > 0) && (info->n_hash_potential > 0)
&& (block->n_fields == info->n_fields) && (block->n_fields == info->n_fields)
&& (block->n_bytes == info->n_bytes) && (block->n_bytes == info->n_bytes)
&& (block->side == info->side)) { && (block->side == info->side)) {
if ((block->is_hashed) if ((block->is_hashed)
&& (block->curr_n_fields == info->n_fields) && (block->curr_n_fields == info->n_fields)
&& (block->curr_n_bytes == info->n_bytes) && (block->curr_n_bytes == info->n_bytes)
&& (block->curr_side == info->side)) { && (block->curr_side == info->side)) {
/* The search would presumably have succeeded using /* The search would presumably have succeeded using
the hash index */ the hash index */
info->last_hash_succ = TRUE; info->last_hash_succ = TRUE;
} }
@ -366,19 +366,19 @@ btr_search_update_block_hash_info(
} }
if ((block->n_hash_helps > page_get_n_recs(block->frame) if ((block->n_hash_helps > page_get_n_recs(block->frame)
/ BTR_SEARCH_PAGE_BUILD_LIMIT) / BTR_SEARCH_PAGE_BUILD_LIMIT)
&& (info->n_hash_potential >= BTR_SEARCH_BUILD_LIMIT)) { && (info->n_hash_potential >= BTR_SEARCH_BUILD_LIMIT)) {
if ((!block->is_hashed) if ((!block->is_hashed)
|| (block->n_hash_helps || (block->n_hash_helps
> 2 * page_get_n_recs(block->frame)) > 2 * page_get_n_recs(block->frame))
|| (block->n_fields != block->curr_n_fields) || (block->n_fields != block->curr_n_fields)
|| (block->n_bytes != block->curr_n_bytes) || (block->n_bytes != block->curr_n_bytes)
|| (block->side != block->curr_side)) { || (block->side != block->curr_side)) {
/* Build a new hash index on the page */ /* Build a new hash index on the page */
return(TRUE); return(TRUE);
} }
} }
@ -415,21 +415,21 @@ btr_search_update_hash_ref(
ut_a(!block->is_hashed || block->index == cursor->index); ut_a(!block->is_hashed || block->index == cursor->index);
if (block->is_hashed if (block->is_hashed
&& (info->n_hash_potential > 0) && (info->n_hash_potential > 0)
&& (block->curr_n_fields == info->n_fields) && (block->curr_n_fields == info->n_fields)
&& (block->curr_n_bytes == info->n_bytes) && (block->curr_n_bytes == info->n_bytes)
&& (block->curr_side == info->side)) { && (block->curr_side == info->side)) {
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint offsets_[REC_OFFS_NORMAL_SIZE];
*offsets_ = (sizeof offsets_) / sizeof *offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_;
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
if (!page_rec_is_user_rec(rec)) { if (!page_rec_is_user_rec(rec)) {
return;
}
return;
}
tree_id = ((cursor->index)->tree)->id; tree_id = ((cursor->index)->tree)->id;
fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, fold = rec_fold(rec, rec_get_offsets(rec, cursor->index,
offsets_, ULINT_UNDEFINED, &heap), offsets_, ULINT_UNDEFINED, &heap),
@ -444,22 +444,22 @@ btr_search_update_hash_ref(
ha_insert_for_fold(btr_search_sys->hash_index, fold, rec); ha_insert_for_fold(btr_search_sys->hash_index, fold, rec);
} }
} }
/************************************************************************* /*************************************************************************
Updates the search info. */ Updates the search info. */
void void
btr_search_info_update_slow( btr_search_info_update_slow(
/*========================*/ /*========================*/
btr_search_t* info, /* in: search info */ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */ btr_cur_t* cursor) /* in: cursor which was just positioned */
{ {
buf_block_t* block; buf_block_t* block;
ibool build_index; ibool build_index;
ulint* params; ulint* params;
ulint* params2; ulint* params2;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX)); ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
@ -480,7 +480,7 @@ btr_search_info_update_slow(
btr_search_check_free_space_in_heap(); btr_search_check_free_space_in_heap();
} }
if (cursor->flag == BTR_CUR_HASH_FAIL) { if (cursor->flag == BTR_CUR_HASH_FAIL) {
/* Update the hash node reference, if appropriate */ /* Update the hash node reference, if appropriate */
@ -511,7 +511,7 @@ btr_search_info_update_slow(
optimizations */ optimizations */
params2 = params + btr_search_this_is_zero; params2 = params + btr_search_this_is_zero;
btr_search_build_page_hash_index(cursor->index, btr_search_build_page_hash_index(cursor->index,
block->frame, block->frame,
params2[0], params2[0],
@ -531,15 +531,15 @@ btr_search_check_guess(
/*===================*/ /*===================*/
/* out: TRUE if success */ /* out: TRUE if success */
btr_cur_t* cursor, /* in: guessed cursor position */ btr_cur_t* cursor, /* in: guessed cursor position */
ibool can_only_compare_to_cursor_rec, ibool can_only_compare_to_cursor_rec,
/* in: if we do not have a latch on the page /* in: if we do not have a latch on the page
of cursor, but only a latch on of cursor, but only a latch on
btr_search_latch, then ONLY the columns btr_search_latch, then ONLY the columns
of the record UNDER the cursor are of the record UNDER the cursor are
protected, not the next or previous record protected, not the next or previous record
in the chain: we cannot look at the next or in the chain: we cannot look at the next or
previous record to check our guess! */ previous record to check our guess! */
dtuple_t* tuple, /* in: data tuple */ dtuple_t* tuple, /* in: data tuple */
ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G, ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
or PAGE_CUR_GE */ or PAGE_CUR_GE */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
@ -556,7 +556,7 @@ btr_search_check_guess(
*offsets_ = (sizeof offsets_) / sizeof *offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_;
n_unique = dict_index_get_n_unique_in_tree(cursor->index); n_unique = dict_index_get_n_unique_in_tree(cursor->index);
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
@ -579,7 +579,7 @@ btr_search_check_guess(
if (match >= n_unique) { if (match >= n_unique) {
success = TRUE; success = TRUE;
goto exit_func; goto exit_func;
} }
} else if (mode == PAGE_CUR_LE) { } else if (mode == PAGE_CUR_LE) {
if (cmp == -1) { if (cmp == -1) {
goto exit_func; goto exit_func;
@ -598,8 +598,8 @@ btr_search_check_guess(
} }
if (can_only_compare_to_cursor_rec) { if (can_only_compare_to_cursor_rec) {
/* Since we could not determine if our guess is right just by /* Since we could not determine if our guess is right just by
looking at the record under the cursor, return FALSE */ looking at the record under the cursor, return FALSE */
goto exit_func; goto exit_func;
} }
@ -610,7 +610,7 @@ btr_search_check_guess(
rec_t* prev_rec; rec_t* prev_rec;
ut_ad(!page_rec_is_infimum(rec)); ut_ad(!page_rec_is_infimum(rec));
prev_rec = page_rec_get_prev(rec); prev_rec = page_rec_get_prev(rec);
if (page_rec_is_infimum(prev_rec)) { if (page_rec_is_infimum(prev_rec)) {
@ -635,7 +635,7 @@ btr_search_check_guess(
rec_t* next_rec; rec_t* next_rec;
ut_ad(!page_rec_is_supremum(rec)); ut_ad(!page_rec_is_supremum(rec));
next_rec = page_rec_get_next(rec); next_rec = page_rec_get_next(rec);
if (page_rec_is_supremum(next_rec)) { if (page_rec_is_supremum(next_rec)) {
@ -676,18 +676,18 @@ both have sensible values. */
ibool ibool
btr_search_guess_on_hash( btr_search_guess_on_hash(
/*=====================*/ /*=====================*/
/* out: TRUE if succeeded */ /* out: TRUE if succeeded */
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
btr_search_t* info, /* in: index search info */ btr_search_t* info, /* in: index search info */
dtuple_t* tuple, /* in: logical record */ dtuple_t* tuple, /* in: logical record */
ulint mode, /* in: PAGE_CUR_L, ... */ ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ...; ulint latch_mode, /* in: BTR_SEARCH_LEAF, ...;
NOTE that only if has_search_latch NOTE that only if has_search_latch
is 0, we will have a latch set on is 0, we will have a latch set on
the cursor page, otherwise we assume the cursor page, otherwise we assume
the caller uses his search latch the caller uses his search latch
to protect the record! */ to protect the record! */
btr_cur_t* cursor, /* out: tree cursor */ btr_cur_t* cursor, /* out: tree cursor */
ulint has_search_latch,/* in: latch mode the caller ulint has_search_latch,/* in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:
RW_S_LATCH, RW_X_LATCH, or 0 */ RW_S_LATCH, RW_X_LATCH, or 0 */
@ -699,7 +699,7 @@ btr_search_guess_on_hash(
ulint fold; ulint fold;
ulint tuple_n_fields; ulint tuple_n_fields;
dulint tree_id; dulint tree_id;
ibool can_only_compare_to_cursor_rec = TRUE; ibool can_only_compare_to_cursor_rec = TRUE;
#ifdef notdefined #ifdef notdefined
btr_cur_t cursor2; btr_cur_t cursor2;
btr_pcur_t pcur; btr_pcur_t pcur;
@ -729,7 +729,7 @@ btr_search_guess_on_hash(
if (UNIV_UNLIKELY(tuple_n_fields == cursor->n_fields) if (UNIV_UNLIKELY(tuple_n_fields == cursor->n_fields)
&& (cursor->n_bytes > 0)) { && (cursor->n_bytes > 0)) {
return(FALSE); return(FALSE);
} }
tree_id = (index->tree)->id; tree_id = (index->tree)->id;
@ -741,7 +741,7 @@ btr_search_guess_on_hash(
cursor->fold = fold; cursor->fold = fold;
cursor->flag = BTR_CUR_HASH; cursor->flag = BTR_CUR_HASH;
if (UNIV_LIKELY(!has_search_latch)) { if (UNIV_LIKELY(!has_search_latch)) {
rw_lock_s_lock(&btr_search_latch); rw_lock_s_lock(&btr_search_latch);
} }
@ -778,7 +778,7 @@ btr_search_guess_on_hash(
if (UNIV_UNLIKELY(block->state == BUF_BLOCK_REMOVE_HASH)) { if (UNIV_UNLIKELY(block->state == BUF_BLOCK_REMOVE_HASH)) {
if (UNIV_LIKELY(!has_search_latch)) { if (UNIV_LIKELY(!has_search_latch)) {
btr_leaf_page_release(page, latch_mode, mtr); btr_leaf_page_release(page, latch_mode, mtr);
} }
@ -798,29 +798,29 @@ btr_search_guess_on_hash(
record to determine if our guess for the cursor position is record to determine if our guess for the cursor position is
right. */ right. */
if (UNIV_EXPECT(ut_dulint_cmp(tree_id, btr_page_get_index_id(page)), 0) if (UNIV_EXPECT(ut_dulint_cmp(tree_id, btr_page_get_index_id(page)), 0)
|| !btr_search_check_guess(cursor, can_only_compare_to_cursor_rec, || !btr_search_check_guess(cursor,
tuple, mode, mtr)) { can_only_compare_to_cursor_rec, tuple, mode, mtr)) {
if (UNIV_LIKELY(!has_search_latch)) { if (UNIV_LIKELY(!has_search_latch)) {
btr_leaf_page_release(page, latch_mode, mtr); btr_leaf_page_release(page, latch_mode, mtr);
} }
goto failure; goto failure;
} }
if (UNIV_LIKELY(info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5)) { if (UNIV_LIKELY(info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5)) {
info->n_hash_potential++; info->n_hash_potential++;
} }
#ifdef notdefined #ifdef notdefined
/* These lines of code can be used in a debug version to check /* These lines of code can be used in a debug version to check
the correctness of the searched cursor position: */ the correctness of the searched cursor position: */
info->last_hash_succ = FALSE; info->last_hash_succ = FALSE;
/* Currently, does not work if the following fails: */ /* Currently, does not work if the following fails: */
ut_ad(!has_search_latch); ut_ad(!has_search_latch);
btr_leaf_page_release(page, latch_mode, mtr); btr_leaf_page_release(page, latch_mode, mtr);
btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode, btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
@ -831,7 +831,7 @@ btr_search_guess_on_hash(
/* If mode is PAGE_CUR_GE, then the binary search /* If mode is PAGE_CUR_GE, then the binary search
in the index tree may actually take us to the supremum in the index tree may actually take us to the supremum
of the previous page */ of the previous page */
info->last_hash_succ = FALSE; info->last_hash_succ = FALSE;
btr_pcur_open_on_user_rec(index, tuple, mode, latch_mode, btr_pcur_open_on_user_rec(index, tuple, mode, latch_mode,
@ -854,14 +854,14 @@ btr_search_guess_on_hash(
&& buf_block_peek_if_too_old(block)) { && buf_block_peek_if_too_old(block)) {
buf_page_make_young(page); buf_page_make_young(page);
} }
/* Increment the page get statistics though we did not really /* Increment the page get statistics though we did not really
fix the page: for user info only */ fix the page: for user info only */
buf_pool->n_page_gets++; buf_pool->n_page_gets++;
return(TRUE); return(TRUE);
/*-------------------------------------------*/ /*-------------------------------------------*/
failure_unlock: failure_unlock:
@ -889,7 +889,8 @@ Drops a page hash index. */
void void
btr_search_drop_page_hash_index( btr_search_drop_page_hash_index(
/*============================*/ /*============================*/
page_t* page) /* in: index page, s- or x-latched */ page_t* page) /* in: index page, s- or x-latched, or an index page
for which we know that block->buf_fix_count == 0 */
{ {
hash_table_t* table; hash_table_t* table;
buf_block_t* block; buf_block_t* block;
@ -904,18 +905,19 @@ btr_search_drop_page_hash_index(
ulint* folds; ulint* folds;
ulint i; ulint i;
mem_heap_t* heap; mem_heap_t* heap;
dict_index_t* index;
ulint* offsets; ulint* offsets;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX)); ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
retry:
rw_lock_s_lock(&btr_search_latch); rw_lock_s_lock(&btr_search_latch);
block = buf_block_align(page); block = buf_block_align(page);
if (!block->is_hashed) { if (UNIV_LIKELY(!block->is_hashed)) {
rw_lock_s_unlock(&btr_search_latch); rw_lock_s_unlock(&btr_search_latch);
@ -926,17 +928,22 @@ btr_search_drop_page_hash_index(
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED) ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
|| rw_lock_own(&(block->lock), RW_LOCK_EX) || rw_lock_own(&(block->lock), RW_LOCK_EX)
|| (block->buf_fix_count == 0)); || (block->buf_fix_count == 0));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
n_fields = block->curr_n_fields; n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes; n_bytes = block->curr_n_bytes;
index = block->index;
/* NOTE: The fields of block must not be accessed after
releasing btr_search_latch, as the index page might only
be s-latched! */
rw_lock_s_unlock(&btr_search_latch);
ut_a(n_fields + n_bytes > 0); ut_a(n_fields + n_bytes > 0);
rw_lock_s_unlock(&btr_search_latch);
n_recs = page_get_n_recs(page); n_recs = page_get_n_recs(page);
/* Calculate and cache fold values into an array for fast deletion /* Calculate and cache fold values into an array for fast deletion
@ -949,33 +956,21 @@ btr_search_drop_page_hash_index(
rec = page_get_infimum_rec(page); rec = page_get_infimum_rec(page);
rec = page_rec_get_next(rec); rec = page_rec_get_next(rec);
if (!page_rec_is_supremum(rec)) {
ut_a(n_fields <= rec_get_n_fields(rec, block->index));
if (n_bytes > 0) {
ut_a(n_fields < rec_get_n_fields(rec, block->index));
}
}
tree_id = btr_page_get_index_id(page); tree_id = btr_page_get_index_id(page);
ut_a(0 == ut_dulint_cmp(tree_id, index->id));
prev_fold = 0; prev_fold = 0;
heap = NULL; heap = NULL;
offsets = NULL; offsets = NULL;
if (block->index == NULL) {
mem_analyze_corruption((byte*)block);
ut_a(block->index != NULL);
}
while (!page_rec_is_supremum(rec)) { while (!page_rec_is_supremum(rec)) {
/* FIXME: in a mixed tree, not all records may have enough /* FIXME: in a mixed tree, not all records may have enough
ordering fields: */ ordering fields: */
offsets = rec_get_offsets(rec, block->index, offsets = rec_get_offsets(rec, index, offsets,
offsets, n_fields + (n_bytes > 0), &heap); n_fields + (n_bytes > 0), &heap);
ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
if (fold == prev_fold && prev_fold != 0) { if (fold == prev_fold && prev_fold != 0) {
@ -999,6 +994,26 @@ next_rec:
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
if (UNIV_UNLIKELY(!block->is_hashed)) {
/* Someone else has meanwhile dropped the hash index */
goto cleanup;
}
ut_a(block->index == index);
if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)
|| UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {
/* Someone else has meanwhile built a new hash index on the
page, with different parameters */
rw_lock_x_unlock(&btr_search_latch);
mem_free(folds);
goto retry;
}
for (i = 0; i < n_cached; i++) { for (i = 0; i < n_cached; i++) {
ha_remove_all_nodes_to_page(table, folds[i], page); ha_remove_all_nodes_to_page(table, folds[i], page);
@ -1006,8 +1021,20 @@ next_rec:
block->is_hashed = FALSE; block->is_hashed = FALSE;
block->index = NULL; block->index = NULL;
cleanup:
if (UNIV_UNLIKELY(block->n_pointers)) {
/* Corruption */
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Corruption of adaptive hash index. After dropping\n"
"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
index->name, (ulong) block->n_pointers);
rw_lock_x_unlock(&btr_search_latch);
rw_lock_x_unlock(&btr_search_latch); btr_search_validate();
} else {
rw_lock_x_unlock(&btr_search_latch);
}
mem_free(folds); mem_free(folds);
} }
@ -1032,14 +1059,14 @@ btr_search_drop_page_hash_when_freed(
return; return;
} }
mtr_start(&mtr); mtr_start(&mtr);
/* We assume that if the caller has a latch on the page, then the /* We assume that if the caller has a latch on the page, then the
caller has already dropped the hash index for the page, and we never caller has already dropped the hash index for the page, and we never
get here. Therefore we can acquire the s-latch to the page without get here. Therefore we can acquire the s-latch to the page without
having to fear a deadlock. */ having to fear a deadlock. */
page = buf_page_get_gen(space, page_no, RW_S_LATCH, NULL, page = buf_page_get_gen(space, page_no, RW_S_LATCH, NULL,
BUF_GET_IF_IN_POOL, __FILE__, __LINE__, BUF_GET_IF_IN_POOL, __FILE__, __LINE__,
&mtr); &mtr);
@ -1098,10 +1125,10 @@ btr_search_build_page_hash_index(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
rw_lock_s_lock(&btr_search_latch); rw_lock_s_lock(&btr_search_latch);
if (block->is_hashed && ((block->curr_n_fields != n_fields) if (block->is_hashed && ((block->curr_n_fields != n_fields)
|| (block->curr_n_bytes != n_bytes) || (block->curr_n_bytes != n_bytes)
|| (block->curr_side != side))) { || (block->curr_side != side))) {
rw_lock_s_unlock(&btr_search_latch); rw_lock_s_unlock(&btr_search_latch);
@ -1118,15 +1145,15 @@ btr_search_build_page_hash_index(
} }
/* Check that the values for hash index build are sensible */ /* Check that the values for hash index build are sensible */
if (n_fields + n_bytes == 0) { if (n_fields + n_bytes == 0) {
return; return;
} }
if (dict_index_get_n_unique_in_tree(index) < n_fields if (dict_index_get_n_unique_in_tree(index) < n_fields
|| (dict_index_get_n_unique_in_tree(index) == n_fields || (dict_index_get_n_unique_in_tree(index) == n_fields
&& n_bytes > 0)) { && n_bytes > 0)) {
return; return;
} }
@ -1164,20 +1191,20 @@ btr_search_build_page_hash_index(
recs[n_cached] = rec; recs[n_cached] = rec;
n_cached++; n_cached++;
} }
for (;;) { for (;;) {
next_rec = page_rec_get_next(rec); next_rec = page_rec_get_next(rec);
if (page_rec_is_supremum(next_rec)) { if (page_rec_is_supremum(next_rec)) {
if (side == BTR_SEARCH_RIGHT_SIDE) { if (side == BTR_SEARCH_RIGHT_SIDE) {
folds[n_cached] = fold; folds[n_cached] = fold;
recs[n_cached] = rec; recs[n_cached] = rec;
n_cached++; n_cached++;
} }
break; break;
} }
offsets = rec_get_offsets(next_rec, index, offsets, offsets = rec_get_offsets(next_rec, index, offsets,
@ -1209,21 +1236,21 @@ btr_search_build_page_hash_index(
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
if (block->is_hashed && ((block->curr_n_fields != n_fields) if (block->is_hashed && ((block->curr_n_fields != n_fields)
|| (block->curr_n_bytes != n_bytes) || (block->curr_n_bytes != n_bytes)
|| (block->curr_side != side))) { || (block->curr_side != side))) {
goto exit_func; goto exit_func;
} }
block->is_hashed = TRUE; block->is_hashed = TRUE;
block->n_hash_helps = 0; block->n_hash_helps = 0;
block->curr_n_fields = n_fields; block->curr_n_fields = n_fields;
block->curr_n_bytes = n_bytes; block->curr_n_bytes = n_bytes;
block->curr_side = side; block->curr_side = side;
block->index = index; block->index = index;
for (i = 0; i < n_cached; i++) { for (i = 0; i < n_cached; i++) {
ha_insert_for_fold(table, folds[i], recs[i]); ha_insert_for_fold(table, folds[i], recs[i]);
} }
@ -1272,7 +1299,7 @@ btr_search_move_or_delete_hash_entries(
ut_a(!block->is_hashed || block->index == index); ut_a(!block->is_hashed || block->index == index);
rw_lock_s_lock(&btr_search_latch); rw_lock_s_lock(&btr_search_latch);
if (new_block->is_hashed) { if (new_block->is_hashed) {
rw_lock_s_unlock(&btr_search_latch); rw_lock_s_unlock(&btr_search_latch);
@ -1393,13 +1420,13 @@ btr_search_update_hash_node_on_insert(
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
if ((cursor->flag == BTR_CUR_HASH) if ((cursor->flag == BTR_CUR_HASH)
&& (cursor->n_fields == block->curr_n_fields) && (cursor->n_fields == block->curr_n_fields)
&& (cursor->n_bytes == block->curr_n_bytes) && (cursor->n_bytes == block->curr_n_bytes)
&& (block->curr_side == BTR_SEARCH_RIGHT_SIDE)) { && (block->curr_side == BTR_SEARCH_RIGHT_SIDE)) {
table = btr_search_sys->hash_index; table = btr_search_sys->hash_index;
ha_search_and_update_if_found(table, cursor->fold, rec, ha_search_and_update_if_found(table, cursor->fold, rec,
page_rec_get_next(rec)); page_rec_get_next(rec));
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
@ -1421,7 +1448,7 @@ btr_search_update_hash_on_insert(
and the new record has been inserted next and the new record has been inserted next
to the cursor */ to the cursor */
{ {
hash_table_t* table; hash_table_t* table;
buf_block_t* block; buf_block_t* block;
rec_t* rec; rec_t* rec;
rec_t* ins_rec; rec_t* ins_rec;
@ -1450,7 +1477,7 @@ btr_search_update_hash_on_insert(
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
if (!block->is_hashed) { if (!block->is_hashed) {
return; return;
@ -1494,10 +1521,10 @@ btr_search_update_hash_on_insert(
goto check_next_rec; goto check_next_rec;
} }
if (fold != ins_fold) {
if (!locked) { if (fold != ins_fold) {
if (!locked) {
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
@ -1516,22 +1543,22 @@ check_next_rec:
if (side == BTR_SEARCH_RIGHT_SIDE) { if (side == BTR_SEARCH_RIGHT_SIDE) {
if (!locked) { if (!locked) {
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
locked = TRUE; locked = TRUE;
} }
ha_insert_for_fold(table, ins_fold, ins_rec); ha_insert_for_fold(table, ins_fold, ins_rec);
} }
goto function_exit; goto function_exit;
} }
if (ins_fold != next_fold) { if (ins_fold != next_fold) {
if (!locked) { if (!locked) {
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
locked = TRUE; locked = TRUE;
@ -1548,8 +1575,8 @@ check_next_rec:
} else { } else {
ha_insert_for_fold(table, next_fold, next_rec); ha_insert_for_fold(table, next_fold, next_rec);
} }
} }
function_exit: function_exit:
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
@ -1573,14 +1600,29 @@ btr_search_validate(void)
ulint n_page_dumps = 0; ulint n_page_dumps = 0;
ibool ok = TRUE; ibool ok = TRUE;
ulint i; ulint i;
ulint cell_count;
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_; ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_;
/* How many cells to check before temporarily releasing
btr_search_latch. */
ulint chunk_size = 10000;
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
for (i = 0; i < hash_get_n_cells(btr_search_sys->hash_index); i++) { cell_count = hash_get_n_cells(btr_search_sys->hash_index);
for (i = 0; i < cell_count; i++) {
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if ((i != 0) && ((i % chunk_size) == 0)) {
rw_lock_x_unlock(&btr_search_latch);
os_thread_yield();
rw_lock_x_lock(&btr_search_latch);
}
node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node; node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
while (node != NULL) { while (node != NULL) {
@ -1592,11 +1634,11 @@ btr_search_validate(void)
+ (block->curr_n_bytes > 0), &heap); + (block->curr_n_bytes > 0), &heap);
if (!block->is_hashed if (!block->is_hashed
|| node->fold != rec_fold((rec_t*)(node->data), || node->fold != rec_fold((rec_t*)(node->data),
offsets, offsets,
block->curr_n_fields, block->curr_n_fields,
block->curr_n_bytes, block->curr_n_bytes,
btr_page_get_index_id(page))) { btr_page_get_index_id(page))) {
ok = FALSE; ok = FALSE;
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
@ -1610,9 +1652,9 @@ btr_search_validate(void)
(ulong) node->fold, (ulong) node->fold,
(ulong) rec_fold((rec_t*)(node->data), (ulong) rec_fold((rec_t*)(node->data),
offsets, offsets,
block->curr_n_fields, block->curr_n_fields,
block->curr_n_bytes, block->curr_n_bytes,
btr_page_get_index_id(page))); btr_page_get_index_id(page)));
fputs("InnoDB: Record ", stderr); fputs("InnoDB: Record ", stderr);
rec_print_new(stderr, (rec_t*)node->data, rec_print_new(stderr, (rec_t*)node->data,
@ -1620,11 +1662,11 @@ btr_search_validate(void)
fprintf(stderr, "\nInnoDB: on that page." fprintf(stderr, "\nInnoDB: on that page."
"Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n" "Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n"
"side %lu\n", "side %lu\n",
page, (ulong) block->is_hashed, page, (ulong) block->is_hashed,
(ulong) block->curr_n_fields, (ulong) block->curr_n_fields,
(ulong) block->curr_n_bytes, (ulong) block->curr_side); (ulong) block->curr_n_bytes, (ulong) block->curr_side);
if (n_page_dumps < 20) { if (n_page_dumps < 20) {
buf_page_print(page); buf_page_print(page);
n_page_dumps++; n_page_dumps++;
} }
@ -1633,10 +1675,21 @@ btr_search_validate(void)
node = node->next; node = node->next;
} }
} }
if (!ha_validate(btr_search_sys->hash_index)) {
ok = FALSE; for (i = 0; i < cell_count; i += chunk_size) {
ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1);
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if (i != 0) {
rw_lock_x_unlock(&btr_search_latch);
os_thread_yield();
rw_lock_x_lock(&btr_search_latch);
}
if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
ok = FALSE;
}
} }
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ Created 11/11/1995 Heikki Tuuri
flushed along with the original page. */ flushed along with the original page. */
#define BUF_FLUSH_AREA ut_min(BUF_READ_AHEAD_AREA,\ #define BUF_FLUSH_AREA ut_min(BUF_READ_AHEAD_AREA,\
buf_pool->curr_size / 16) buf_pool->curr_size / 16)
/********************************************************************** /**********************************************************************
Validates the flush list. */ Validates the flush list. */
@ -55,10 +55,10 @@ buf_flush_insert_into_flush_list(
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_ad((UT_LIST_GET_FIRST(buf_pool->flush_list) == NULL) ut_ad((UT_LIST_GET_FIRST(buf_pool->flush_list) == NULL)
|| (ut_dulint_cmp( || (ut_dulint_cmp(
(UT_LIST_GET_FIRST(buf_pool->flush_list)) (UT_LIST_GET_FIRST(buf_pool->flush_list))
->oldest_modification, ->oldest_modification,
block->oldest_modification) <= 0)); block->oldest_modification) <= 0));
UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, block); UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, block);
@ -77,7 +77,7 @@ buf_flush_insert_sorted_into_flush_list(
{ {
buf_block_t* prev_b; buf_block_t* prev_b;
buf_block_t* b; buf_block_t* b;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(buf_pool->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
@ -120,18 +120,18 @@ buf_flush_ready_for_replace(
fprintf(stderr, fprintf(stderr,
" InnoDB: Error: buffer block state %lu in the LRU list!\n", " InnoDB: Error: buffer block state %lu in the LRU list!\n",
(ulong)block->state); (ulong)block->state);
ut_print_buf(stderr, (byte*)block, sizeof(buf_block_t)); ut_print_buf(stderr, block, sizeof(buf_block_t));
return(FALSE); return(FALSE);
} }
if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0) if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0)
|| (block->buf_fix_count != 0) || (block->buf_fix_count != 0)
|| (block->io_fix != 0)) { || (block->io_fix != 0)) {
return(FALSE); return(FALSE);
} }
return(TRUE); return(TRUE);
} }
@ -152,13 +152,13 @@ buf_flush_ready_for_flush(
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0) if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0)
&& (block->io_fix == 0)) { && (block->io_fix == 0)) {
if (flush_type != BUF_FLUSH_LRU) { if (flush_type != BUF_FLUSH_LRU) {
return(TRUE); return(TRUE);
} else if (block->buf_fix_count == 0) { } else if (block->buf_fix_count == 0) {
/* If we are flushing the LRU list, to avoid deadlocks /* If we are flushing the LRU list, to avoid deadlocks
we require the block not to be bufferfixed, and hence we require the block not to be bufferfixed, and hence
not latched. */ not latched. */
@ -166,7 +166,7 @@ buf_flush_ready_for_flush(
return(TRUE); return(TRUE);
} }
} }
return(FALSE); return(FALSE);
} }
@ -205,7 +205,7 @@ buf_flush_write_complete(
buf_pool->n_flush[block->flush_type]); */ buf_pool->n_flush[block->flush_type]); */
if ((buf_pool->n_flush[block->flush_type] == 0) if ((buf_pool->n_flush[block->flush_type] == 0)
&& (buf_pool->init_flush[block->flush_type] == FALSE)) { && (buf_pool->init_flush[block->flush_type] == FALSE)) {
/* The running flush batch has ended */ /* The running flush batch has ended */
@ -235,7 +235,7 @@ buf_flush_buffered_writes(void)
return; return;
} }
mutex_enter(&(trx_doublewrite->mutex)); mutex_enter(&(trx_doublewrite->mutex));
/* Write first to doublewrite buffer blocks. We use synchronous /* Write first to doublewrite buffer blocks. We use synchronous
@ -252,17 +252,17 @@ buf_flush_buffered_writes(void)
for (i = 0; i < trx_doublewrite->first_free; i++) { for (i = 0; i < trx_doublewrite->first_free; i++) {
block = trx_doublewrite->buf_block_arr[i]; block = trx_doublewrite->buf_block_arr[i];
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
if (mach_read_from_4(block->frame + FIL_PAGE_LSN + 4) if (mach_read_from_4(block->frame + FIL_PAGE_LSN + 4)
!= mach_read_from_4(block->frame + UNIV_PAGE_SIZE != mach_read_from_4(block->frame + UNIV_PAGE_SIZE
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: ERROR: The page to be written seems corrupt!\n" " InnoDB: ERROR: The page to be written seems corrupt!\n"
"InnoDB: The lsn fields do not match! Noticed in the buffer pool\n" "InnoDB: The lsn fields do not match! Noticed in the buffer pool\n"
"InnoDB: before posting to the doublewrite buffer.\n"); "InnoDB: before posting to the doublewrite buffer.\n");
} }
if (block->check_index_page_at_flush if (block->check_index_page_at_flush
&& !page_simple_validate(block->frame)) { && !page_simple_validate(block->frame)) {
@ -281,27 +281,27 @@ buf_flush_buffered_writes(void)
} }
} }
/* increment the doublewrite flushed pages counter */ /* increment the doublewrite flushed pages counter */
srv_dblwr_pages_written+= trx_doublewrite->first_free; srv_dblwr_pages_written+= trx_doublewrite->first_free;
srv_dblwr_writes++; srv_dblwr_writes++;
if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
len = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; len = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
} else { } else {
len = trx_doublewrite->first_free * UNIV_PAGE_SIZE; len = trx_doublewrite->first_free * UNIV_PAGE_SIZE;
} }
fil_io(OS_FILE_WRITE, fil_io(OS_FILE_WRITE,
TRUE, TRX_SYS_SPACE, TRUE, TRX_SYS_SPACE,
trx_doublewrite->block1, 0, len, trx_doublewrite->block1, 0, len,
(void*)trx_doublewrite->write_buf, NULL); (void*)trx_doublewrite->write_buf, NULL);
write_buf = trx_doublewrite->write_buf; write_buf = trx_doublewrite->write_buf;
for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; len2 += UNIV_PAGE_SIZE) { for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; len2 += UNIV_PAGE_SIZE) {
if (mach_read_from_4(write_buf + len2 + FIL_PAGE_LSN + 4) if (mach_read_from_4(write_buf + len2 + FIL_PAGE_LSN + 4)
!= mach_read_from_4(write_buf + len2 + UNIV_PAGE_SIZE != mach_read_from_4(write_buf + len2 + UNIV_PAGE_SIZE
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: ERROR: The page to be written seems corrupt!\n" " InnoDB: ERROR: The page to be written seems corrupt!\n"
@ -312,23 +312,23 @@ buf_flush_buffered_writes(void)
if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
len = (trx_doublewrite->first_free len = (trx_doublewrite->first_free
- TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE; - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE;
fil_io(OS_FILE_WRITE, fil_io(OS_FILE_WRITE,
TRUE, TRX_SYS_SPACE, TRUE, TRX_SYS_SPACE,
trx_doublewrite->block2, 0, len, trx_doublewrite->block2, 0, len,
(void*)(trx_doublewrite->write_buf (void*)(trx_doublewrite->write_buf
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE), + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE),
NULL); NULL);
write_buf = trx_doublewrite->write_buf write_buf = trx_doublewrite->write_buf
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len;
len2 += UNIV_PAGE_SIZE) { len2 += UNIV_PAGE_SIZE) {
if (mach_read_from_4(write_buf + len2 if (mach_read_from_4(write_buf + len2
+ FIL_PAGE_LSN + 4) + FIL_PAGE_LSN + 4)
!= mach_read_from_4(write_buf + len2 != mach_read_from_4(write_buf + len2
+ UNIV_PAGE_SIZE + UNIV_PAGE_SIZE
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: ERROR: The page to be written seems corrupt!\n" " InnoDB: ERROR: The page to be written seems corrupt!\n"
@ -349,32 +349,33 @@ buf_flush_buffered_writes(void)
block = trx_doublewrite->buf_block_arr[i]; block = trx_doublewrite->buf_block_arr[i];
if (mach_read_from_4(block->frame + FIL_PAGE_LSN + 4) if (mach_read_from_4(block->frame + FIL_PAGE_LSN + 4)
!= mach_read_from_4(block->frame + UNIV_PAGE_SIZE != mach_read_from_4(block->frame + UNIV_PAGE_SIZE
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: ERROR: The page to be written seems corrupt!\n" " InnoDB: ERROR: The page to be written seems corrupt!\n"
"InnoDB: The lsn fields do not match! Noticed in the buffer pool\n" "InnoDB: The lsn fields do not match! Noticed in the buffer pool\n"
"InnoDB: after posting and flushing the doublewrite buffer.\n" "InnoDB: after posting and flushing the doublewrite buffer.\n"
"InnoDB: Page buf fix count %lu, io fix %lu, state %lu\n", "InnoDB: Page buf fix count %lu, io fix %lu, state %lu\n",
(ulong)block->buf_fix_count, (ulong)block->io_fix, (ulong)block->buf_fix_count,
(ulong)block->state); (ulong)block->io_fix,
} (ulong)block->state);
}
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE, FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
(void*)block->frame, (void*)block); (void*)block->frame, (void*)block);
} }
/* Wake possible simulated aio thread to actually post the /* Wake possible simulated aio thread to actually post the
writes to the operating system */ writes to the operating system */
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
/* Wait that all async writes to tablespaces have been posted to /* Wait that all async writes to tablespaces have been posted to
the OS */ the OS */
os_aio_wait_until_no_pending_writes(); os_aio_wait_until_no_pending_writes();
/* Now we flush the data to disk (for example, with fsync) */ /* Now we flush the data to disk (for example, with fsync) */
@ -385,7 +386,7 @@ buf_flush_buffered_writes(void)
trx_doublewrite->first_free = 0; trx_doublewrite->first_free = 0;
mutex_exit(&(trx_doublewrite->mutex)); mutex_exit(&(trx_doublewrite->mutex));
} }
/************************************************************************ /************************************************************************
@ -442,7 +443,7 @@ buf_flush_init_for_writing(
dulint newest_lsn, /* in: newest modification lsn to the page */ dulint newest_lsn, /* in: newest modification lsn to the page */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint page_no) /* in: page number */ ulint page_no) /* in: page number */
{ {
/* Write the newest modification lsn to the page header and trailer */ /* Write the newest modification lsn to the page header and trailer */
mach_write_to_8(page + FIL_PAGE_LSN, newest_lsn); mach_write_to_8(page + FIL_PAGE_LSN, newest_lsn);
@ -451,13 +452,13 @@ buf_flush_init_for_writing(
/* Write the page number and the space id */ /* Write the page number and the space id */
mach_write_to_4(page + FIL_PAGE_OFFSET, page_no); mach_write_to_4(page + FIL_PAGE_OFFSET, page_no);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space); mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space);
/* Store the new formula checksum */ /* Store the new formula checksum */
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
srv_use_checksums ? srv_use_checksums ?
buf_calc_page_new_checksum(page) : BUF_NO_CHECKSUM_MAGIC); buf_calc_page_new_checksum(page) : BUF_NO_CHECKSUM_MAGIC);
/* We overwrite the first 4 bytes of the end lsn field to store /* We overwrite the first 4 bytes of the end lsn field to store
the old formula checksum. Since it depends also on the field the old formula checksum. Since it depends also on the field
@ -466,7 +467,7 @@ buf_flush_init_for_writing(
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
srv_use_checksums ? srv_use_checksums ?
buf_calc_page_old_checksum(page) : BUF_NO_CHECKSUM_MAGIC); buf_calc_page_old_checksum(page) : BUF_NO_CHECKSUM_MAGIC);
} }
/************************************************************************ /************************************************************************
@ -500,13 +501,13 @@ buf_flush_write_block_low(
#else #else
/* Force the log to the disk before writing the modified block */ /* Force the log to the disk before writing the modified block */
log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE); log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE);
#endif #endif
buf_flush_init_for_writing(block->frame, block->newest_modification, buf_flush_init_for_writing(block->frame, block->newest_modification,
block->space, block->offset); block->space, block->offset);
if (!srv_use_doublewrite_buf || !trx_doublewrite) { if (!srv_use_doublewrite_buf || !trx_doublewrite) {
fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE, FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
(void*)block->frame, (void*)block); (void*)block->frame, (void*)block);
} else { } else {
buf_flush_post_to_doublewrite_buf(block); buf_flush_post_to_doublewrite_buf(block);
} }
@ -529,7 +530,7 @@ buf_flush_try_page(
{ {
buf_block_t* block; buf_block_t* block;
ibool locked; ibool locked;
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST
|| flush_type == BUF_FLUSH_SINGLE_PAGE); || flush_type == BUF_FLUSH_SINGLE_PAGE);
@ -540,8 +541,8 @@ buf_flush_try_page(
ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE); ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE);
if (flush_type == BUF_FLUSH_LIST if (flush_type == BUF_FLUSH_LIST
&& block && buf_flush_ready_for_flush(block, flush_type)) { && block && buf_flush_ready_for_flush(block, flush_type)) {
block->io_fix = BUF_IO_WRITE; block->io_fix = BUF_IO_WRITE;
/* If AWE is enabled and the page is not mapped to a frame, /* If AWE is enabled and the page is not mapped to a frame,
@ -553,7 +554,7 @@ buf_flush_try_page(
/* We set second parameter TRUE because the block is /* We set second parameter TRUE because the block is
in the LRU list and we must put it to in the LRU list and we must put it to
awe_LRU_free_mapped list once mapped to a frame */ awe_LRU_free_mapped list once mapped to a frame */
buf_awe_map_page_to_frame(block, TRUE); buf_awe_map_page_to_frame(block, TRUE);
} }
@ -567,7 +568,7 @@ buf_flush_try_page(
(buf_pool->n_flush[flush_type])++; (buf_pool->n_flush[flush_type])++;
locked = FALSE; locked = FALSE;
/* If the simulated aio thread is not running, we must /* If the simulated aio thread is not running, we must
not wait for any latch, as we may end up in a deadlock: not wait for any latch, as we may end up in a deadlock:
if buf_fix_count == 0, then we know we need not wait */ if buf_fix_count == 0, then we know we need not wait */
@ -595,7 +596,7 @@ buf_flush_try_page(
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
buf_flush_write_block_low(block); buf_flush_write_block_low(block);
return(1); return(1);
} else if (flush_type == BUF_FLUSH_LRU && block } else if (flush_type == BUF_FLUSH_LRU && block
@ -620,7 +621,7 @@ buf_flush_try_page(
/* We set second parameter TRUE because the block is /* We set second parameter TRUE because the block is
in the LRU list and we must put it to in the LRU list and we must put it to
awe_LRU_free_mapped list once mapped to a frame */ awe_LRU_free_mapped list once mapped to a frame */
buf_awe_map_page_to_frame(block, TRUE); buf_awe_map_page_to_frame(block, TRUE);
} }
@ -638,7 +639,7 @@ buf_flush_try_page(
/* Note that the s-latch is acquired before releasing the /* Note that the s-latch is acquired before releasing the
buf_pool mutex: this ensures that the latch is acquired buf_pool mutex: this ensures that the latch is acquired
immediately. */ immediately. */
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
buf_flush_write_block_low(block); buf_flush_write_block_low(block);
@ -647,7 +648,7 @@ buf_flush_try_page(
} else if (flush_type == BUF_FLUSH_SINGLE_PAGE && block } else if (flush_type == BUF_FLUSH_SINGLE_PAGE && block
&& buf_flush_ready_for_flush(block, flush_type)) { && buf_flush_ready_for_flush(block, flush_type)) {
block->io_fix = BUF_IO_WRITE; block->io_fix = BUF_IO_WRITE;
/* If AWE is enabled and the page is not mapped to a frame, /* If AWE is enabled and the page is not mapped to a frame,
@ -659,7 +660,7 @@ buf_flush_try_page(
/* We set second parameter TRUE because the block is /* We set second parameter TRUE because the block is
in the LRU list and we must put it to in the LRU list and we must put it to
awe_LRU_free_mapped list once mapped to a frame */ awe_LRU_free_mapped list once mapped to a frame */
buf_awe_map_page_to_frame(block, TRUE); buf_awe_map_page_to_frame(block, TRUE);
} }
@ -681,18 +682,18 @@ buf_flush_try_page(
fprintf(stderr, fprintf(stderr,
"Flushing single page space %lu, page no %lu \n", "Flushing single page space %lu, page no %lu \n",
(ulong) block->space, (ulong) block->space,
(ulong) block->offset); (ulong) block->offset);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
buf_flush_write_block_low(block); buf_flush_write_block_low(block);
return(1); return(1);
} else { } else {
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(0); return(0);
} }
} }
/*************************************************************** /***************************************************************
@ -719,13 +720,13 @@ buf_flush_try_neighbors(
if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) { if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
/* If there is little space, it is better not to flush any /* If there is little space, it is better not to flush any
block except from the end of the LRU list */ block except from the end of the LRU list */
low = offset; low = offset;
high = offset + 1; high = offset + 1;
} }
/* fprintf(stderr, "Flush area: low %lu high %lu\n", low, high); */ /* fprintf(stderr, "Flush area: low %lu high %lu\n", low, high); */
if (high > fil_space_get_size(space)) { if (high > fil_space_get_size(space)) {
high = fil_space_get_size(space); high = fil_space_get_size(space);
} }
@ -738,12 +739,12 @@ buf_flush_try_neighbors(
ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE); ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE);
if (block && flush_type == BUF_FLUSH_LRU && i != offset if (block && flush_type == BUF_FLUSH_LRU && i != offset
&& !block->old) { && !block->old) {
/* We avoid flushing 'non-old' blocks in an LRU flush, /* We avoid flushing 'non-old' blocks in an LRU flush,
because the flushed blocks are soon freed */ because the flushed blocks are soon freed */
continue; continue;
} }
if (block && buf_flush_ready_for_flush(block, flush_type) if (block && buf_flush_ready_for_flush(block, flush_type)
@ -767,7 +768,7 @@ buf_flush_try_neighbors(
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
} }
} }
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(count); return(count);
@ -798,64 +799,64 @@ buf_flush_batch(
exceed min_n), otherwise ignored */ exceed min_n), otherwise ignored */
{ {
buf_block_t* block; buf_block_t* block;
ulint page_count = 0; ulint page_count = 0;
ulint old_page_count; ulint old_page_count;
ulint space; ulint space;
ulint offset; ulint offset;
ibool found; ibool found;
ut_ad((flush_type == BUF_FLUSH_LRU) ut_ad((flush_type == BUF_FLUSH_LRU)
|| (flush_type == BUF_FLUSH_LIST)); || (flush_type == BUF_FLUSH_LIST));
ut_ad((flush_type != BUF_FLUSH_LIST) ut_ad((flush_type != BUF_FLUSH_LIST)
|| sync_thread_levels_empty_gen(TRUE)); || sync_thread_levels_empty_gen(TRUE));
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
if ((buf_pool->n_flush[flush_type] > 0) if ((buf_pool->n_flush[flush_type] > 0)
|| (buf_pool->init_flush[flush_type] == TRUE)) { || (buf_pool->init_flush[flush_type] == TRUE)) {
/* There is already a flush batch of the same type running */ /* There is already a flush batch of the same type running */
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(ULINT_UNDEFINED); return(ULINT_UNDEFINED);
} }
(buf_pool->init_flush)[flush_type] = TRUE; (buf_pool->init_flush)[flush_type] = TRUE;
for (;;) { for (;;) {
/* If we have flushed enough, leave the loop */ /* If we have flushed enough, leave the loop */
if (page_count >= min_n) { if (page_count >= min_n) {
break; break;
} }
/* Start from the end of the list looking for a suitable /* Start from the end of the list looking for a suitable
block to be flushed. */ block to be flushed. */
if (flush_type == BUF_FLUSH_LRU) { if (flush_type == BUF_FLUSH_LRU) {
block = UT_LIST_GET_LAST(buf_pool->LRU); block = UT_LIST_GET_LAST(buf_pool->LRU);
} else { } else {
ut_ad(flush_type == BUF_FLUSH_LIST); ut_ad(flush_type == BUF_FLUSH_LIST);
block = UT_LIST_GET_LAST(buf_pool->flush_list); block = UT_LIST_GET_LAST(buf_pool->flush_list);
if (!block if (!block
|| (ut_dulint_cmp(block->oldest_modification, || (ut_dulint_cmp(block->oldest_modification,
lsn_limit) >= 0)) { lsn_limit) >= 0)) {
/* We have flushed enough */ /* We have flushed enough */
break; break;
} }
} }
found = FALSE; found = FALSE;
/* Note that after finding a single flushable page, we try to /* Note that after finding a single flushable page, we try to
flush also all its neighbors, and after that start from the flush also all its neighbors, and after that start from the
END of the LRU list or flush list again: the list may change END of the LRU list or flush list again: the list may change
during the flushing and we cannot safely preserve within this during the flushing and we cannot safely preserve within this
function a pointer to a block in the list! */ function a pointer to a block in the list! */
while ((block != NULL) && !found) { while ((block != NULL) && !found) {
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
if (buf_flush_ready_for_flush(block, flush_type)) { if (buf_flush_ready_for_flush(block, flush_type)) {
@ -863,11 +864,11 @@ buf_flush_batch(
found = TRUE; found = TRUE;
space = block->space; space = block->space;
offset = block->offset; offset = block->offset;
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
old_page_count = page_count; old_page_count = page_count;
/* Try to flush also all the neighbors */ /* Try to flush also all the neighbors */
page_count += page_count +=
buf_flush_try_neighbors(space, offset, buf_flush_try_neighbors(space, offset,
@ -887,19 +888,19 @@ buf_flush_batch(
block = UT_LIST_GET_PREV(flush_list, block); block = UT_LIST_GET_PREV(flush_list, block);
} }
} }
/* If we could not find anything to flush, leave the loop */ /* If we could not find anything to flush, leave the loop */
if (!found) { if (!found) {
break; break;
} }
} }
(buf_pool->init_flush)[flush_type] = FALSE; (buf_pool->init_flush)[flush_type] = FALSE;
if ((buf_pool->n_flush[flush_type] == 0) if ((buf_pool->n_flush[flush_type] == 0)
&& (buf_pool->init_flush[flush_type] == FALSE)) { && (buf_pool->init_flush[flush_type] == FALSE)) {
/* The running flush batch has ended */ /* The running flush batch has ended */
@ -920,9 +921,9 @@ buf_flush_batch(
(ulong) page_count); (ulong) page_count);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
if (page_count != ULINT_UNDEFINED) if (page_count != ULINT_UNDEFINED)
srv_buf_pool_flushed+= page_count; srv_buf_pool_flushed+= page_count;
return(page_count); return(page_count);
} }
@ -936,9 +937,9 @@ buf_flush_wait_batch_end(
ulint type) /* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */ ulint type) /* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
{ {
ut_ad((type == BUF_FLUSH_LRU) || (type == BUF_FLUSH_LIST)); ut_ad((type == BUF_FLUSH_LRU) || (type == BUF_FLUSH_LIST));
os_event_wait(buf_pool->no_flush[type]); os_event_wait(buf_pool->no_flush[type]);
} }
/********************************************************************** /**********************************************************************
Gives a recommendation of how many blocks should be flushed to establish Gives a recommendation of how many blocks should be flushed to establish
@ -954,7 +955,7 @@ buf_flush_LRU_recommendation(void)
buf_block_t* block; buf_block_t* block;
ulint n_replaceable; ulint n_replaceable;
ulint distance = 0; ulint distance = 0;
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
n_replaceable = UT_LIST_GET_LEN(buf_pool->free); n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
@ -962,26 +963,26 @@ buf_flush_LRU_recommendation(void)
block = UT_LIST_GET_LAST(buf_pool->LRU); block = UT_LIST_GET_LAST(buf_pool->LRU);
while ((block != NULL) while ((block != NULL)
&& (n_replaceable < BUF_FLUSH_FREE_BLOCK_MARGIN && (n_replaceable < BUF_FLUSH_FREE_BLOCK_MARGIN
+ BUF_FLUSH_EXTRA_MARGIN) + BUF_FLUSH_EXTRA_MARGIN)
&& (distance < BUF_LRU_FREE_SEARCH_LEN)) { && (distance < BUF_LRU_FREE_SEARCH_LEN)) {
if (buf_flush_ready_for_replace(block)) { if (buf_flush_ready_for_replace(block)) {
n_replaceable++; n_replaceable++;
} }
distance++; distance++;
block = UT_LIST_GET_PREV(LRU, block); block = UT_LIST_GET_PREV(LRU, block);
} }
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) { if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) {
return(0); return(0);
} }
return(BUF_FLUSH_FREE_BLOCK_MARGIN + BUF_FLUSH_EXTRA_MARGIN return(BUF_FLUSH_FREE_BLOCK_MARGIN + BUF_FLUSH_EXTRA_MARGIN
- n_replaceable); - n_replaceable);
} }
@ -991,7 +992,7 @@ Flushes pages from the end of the LRU list if there is too small a margin
of replaceable pages there or in the free list. VERY IMPORTANT: this function of replaceable pages there or in the free list. VERY IMPORTANT: this function
is called also by threads which have locks on pages. To avoid deadlocks, we is called also by threads which have locks on pages. To avoid deadlocks, we
flush only pages such that the s-lock required for flushing can be acquired flush only pages such that the s-lock required for flushing can be acquired
immediately, without waiting. */ immediately, without waiting. */
void void
buf_flush_free_margin(void) buf_flush_free_margin(void)
@ -1001,15 +1002,15 @@ buf_flush_free_margin(void)
ulint n_flushed; ulint n_flushed;
n_to_flush = buf_flush_LRU_recommendation(); n_to_flush = buf_flush_LRU_recommendation();
if (n_to_flush > 0) { if (n_to_flush > 0) {
n_flushed = buf_flush_batch(BUF_FLUSH_LRU, n_to_flush, n_flushed = buf_flush_batch(BUF_FLUSH_LRU, n_to_flush,
ut_dulint_zero); ut_dulint_zero);
if (n_flushed == ULINT_UNDEFINED) { if (n_flushed == ULINT_UNDEFINED) {
/* There was an LRU type flush batch already running; /* There was an LRU type flush batch already running;
let us wait for it to end */ let us wait for it to end */
buf_flush_wait_batch_end(BUF_FLUSH_LRU); buf_flush_wait_batch_end(BUF_FLUSH_LRU);
} }
} }
} }
@ -1024,7 +1025,7 @@ buf_flush_validate_low(void)
{ {
buf_block_t* block; buf_block_t* block;
dulint om; dulint om;
UT_LIST_VALIDATE(flush_list, buf_block_t, buf_pool->flush_list); UT_LIST_VALIDATE(flush_list, buf_block_t, buf_pool->flush_list);
block = UT_LIST_GET_FIRST(buf_pool->flush_list); block = UT_LIST_GET_FIRST(buf_pool->flush_list);
@ -1033,7 +1034,7 @@ buf_flush_validate_low(void)
om = block->oldest_modification; om = block->oldest_modification;
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_a(ut_dulint_cmp(om, ut_dulint_zero) > 0); ut_a(ut_dulint_cmp(om, ut_dulint_zero) > 0);
block = UT_LIST_GET_NEXT(flush_list, block); block = UT_LIST_GET_NEXT(flush_list, block);
if (block) { if (block) {
@ -1054,11 +1055,11 @@ buf_flush_validate(void)
/* out: TRUE if ok */ /* out: TRUE if ok */
{ {
ibool ret; ibool ret;
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
ret = buf_flush_validate_low(); ret = buf_flush_validate_low();
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(ret); return(ret);

View File

@ -80,21 +80,21 @@ buf_LRU_invalidate_tablespace(
scan_again: scan_again:
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
all_freed = TRUE; all_freed = TRUE;
block = UT_LIST_GET_LAST(buf_pool->LRU); block = UT_LIST_GET_LAST(buf_pool->LRU);
while (block != NULL) { while (block != NULL) {
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
if (block->space == id if (block->space == id
&& (block->buf_fix_count > 0 || block->io_fix != 0)) { && (block->buf_fix_count > 0 || block->io_fix != 0)) {
/* We cannot remove this page during this scan yet; /* We cannot remove this page during this scan yet;
maybe the system is currently reading it in, or maybe the system is currently reading it in, or
flushing the modifications to the file */ flushing the modifications to the file */
all_freed = FALSE; all_freed = FALSE;
goto next_page; goto next_page;
@ -106,12 +106,12 @@ scan_again:
printf( printf(
"Dropping space %lu page %lu\n", "Dropping space %lu page %lu\n",
(ulong) block->space, (ulong) block->space,
(ulong) block->offset); (ulong) block->offset);
} }
#endif #endif
if (block->is_hashed) { if (block->is_hashed) {
page_no = block->offset; page_no = block->offset;
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
/* Note that the following call will acquire /* Note that the following call will acquire
@ -129,7 +129,7 @@ scan_again:
blocks */ blocks */
block->oldest_modification = ut_dulint_zero; block->oldest_modification = ut_dulint_zero;
UT_LIST_REMOVE(flush_list, UT_LIST_REMOVE(flush_list,
buf_pool->flush_list, block); buf_pool->flush_list, block);
} }
@ -142,11 +142,11 @@ next_page:
} }
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
if (!all_freed) { if (!all_freed) {
os_thread_sleep(20000); os_thread_sleep(20000);
goto scan_again; goto scan_again;
} }
} }
@ -193,7 +193,7 @@ ibool
buf_LRU_search_and_free_block( buf_LRU_search_and_free_block(
/*==========================*/ /*==========================*/
/* out: TRUE if freed */ /* out: TRUE if freed */
ulint n_iterations) /* in: how many times this has been called ulint n_iterations) /* in: how many times this has been called
repeatedly without result: a high value means repeatedly without result: a high value means
that we should search farther; if value is that we should search farther; if value is
k < 10, then we only search k/10 * [number k < 10, then we only search k/10 * [number
@ -205,12 +205,12 @@ buf_LRU_search_and_free_block(
ibool freed; ibool freed;
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
freed = FALSE; freed = FALSE;
block = UT_LIST_GET_LAST(buf_pool->LRU); block = UT_LIST_GET_LAST(buf_pool->LRU);
while (block != NULL) { while (block != NULL) {
ut_a(block->in_LRU_list); ut_a(block->in_LRU_list);
if (buf_flush_ready_for_replace(block)) { if (buf_flush_ready_for_replace(block)) {
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
@ -218,7 +218,7 @@ buf_LRU_search_and_free_block(
fprintf(stderr, fprintf(stderr,
"Putting space %lu page %lu to free list\n", "Putting space %lu page %lu to free list\n",
(ulong) block->space, (ulong) block->space,
(ulong) block->offset); (ulong) block->offset);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
@ -229,7 +229,7 @@ buf_LRU_search_and_free_block(
/* Remove possible adaptive hash index built on the /* Remove possible adaptive hash index built on the
page; in the case of AWE the block may not have a page; in the case of AWE the block may not have a
frame at all */ frame at all */
if (block->frame) { if (block->frame) {
btr_search_drop_page_hash_index(block->frame); btr_search_drop_page_hash_index(block->frame);
} }
@ -246,26 +246,26 @@ buf_LRU_search_and_free_block(
distance++; distance++;
if (!freed && n_iterations <= 10 if (!freed && n_iterations <= 10
&& distance > 100 + (n_iterations * buf_pool->curr_size) && distance > 100 + (n_iterations * buf_pool->curr_size)
/ 10) { / 10) {
buf_pool->LRU_flush_ended = 0; buf_pool->LRU_flush_ended = 0;
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(FALSE); return(FALSE);
} }
} }
if (buf_pool->LRU_flush_ended > 0) { if (buf_pool->LRU_flush_ended > 0) {
buf_pool->LRU_flush_ended--; buf_pool->LRU_flush_ended--;
} }
if (!freed) { if (!freed) {
buf_pool->LRU_flush_ended = 0; buf_pool->LRU_flush_ended = 0;
} }
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(freed); return(freed);
} }
/********************************************************************** /**********************************************************************
Tries to remove LRU flushed blocks from the end of the LRU list and put them Tries to remove LRU flushed blocks from the end of the LRU list and put them
to the free list. This is beneficial for the efficiency of the insert buffer to the free list. This is beneficial for the efficiency of the insert buffer
@ -286,12 +286,12 @@ buf_LRU_try_free_flushed_blocks(void)
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
buf_LRU_search_and_free_block(1); buf_LRU_search_and_free_block(1);
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
} }
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
} }
/********************************************************************** /**********************************************************************
Returns TRUE if less than 15 % of the buffer pool is available. This can be Returns TRUE if less than 15 % of the buffer pool is available. This can be
@ -310,7 +310,7 @@ buf_LRU_buf_pool_running_out(void)
if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 7) { + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 7) {
ret = TRUE; ret = TRUE;
} }
@ -334,16 +334,16 @@ buf_LRU_get_free_block(void)
buf_block_t* block = NULL; buf_block_t* block = NULL;
ibool freed; ibool freed;
ulint n_iterations = 1; ulint n_iterations = 1;
ibool mon_value_was = FALSE; ibool mon_value_was = FALSE;
ibool started_monitor = FALSE; ibool started_monitor = FALSE;
loop: loop:
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 10) { + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 10) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: ERROR: over 9 / 10 of the buffer pool is occupied by\n" " InnoDB: ERROR: over 9 / 10 of the buffer pool is occupied by\n"
"InnoDB: lock heaps or the adaptive hash index! Check that your\n" "InnoDB: lock heaps or the adaptive hash index! Check that your\n"
"InnoDB: transactions do not set too many row locks.\n" "InnoDB: transactions do not set too many row locks.\n"
@ -354,18 +354,18 @@ loop:
(ulong)(buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE))); (ulong)(buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE)));
ut_error; ut_error;
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) } else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) { + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) {
if (!buf_lru_switched_on_innodb_mon) { if (!buf_lru_switched_on_innodb_mon) {
/* Over 80 % of the buffer pool is occupied by lock /* Over 80 % of the buffer pool is occupied by lock
heaps or the adaptive hash index. This may be a memory heaps or the adaptive hash index. This may be a memory
leak! */ leak! */
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: WARNING: over 4 / 5 of the buffer pool is occupied by\n" " InnoDB: WARNING: over 4 / 5 of the buffer pool is occupied by\n"
"InnoDB: lock heaps or the adaptive hash index! Check that your\n" "InnoDB: lock heaps or the adaptive hash index! Check that your\n"
"InnoDB: transactions do not set too many row locks.\n" "InnoDB: transactions do not set too many row locks.\n"
@ -389,21 +389,21 @@ loop:
buf_lru_switched_on_innodb_mon = FALSE; buf_lru_switched_on_innodb_mon = FALSE;
srv_print_innodb_monitor = FALSE; srv_print_innodb_monitor = FALSE;
} }
/* If there is a block in the free list, take it */ /* If there is a block in the free list, take it */
if (UT_LIST_GET_LEN(buf_pool->free) > 0) { if (UT_LIST_GET_LEN(buf_pool->free) > 0) {
block = UT_LIST_GET_FIRST(buf_pool->free); block = UT_LIST_GET_FIRST(buf_pool->free);
ut_a(block->in_free_list); ut_a(block->in_free_list);
UT_LIST_REMOVE(free, buf_pool->free, block); UT_LIST_REMOVE(free, buf_pool->free, block);
block->in_free_list = FALSE; block->in_free_list = FALSE;
ut_a(block->state != BUF_BLOCK_FILE_PAGE); ut_a(block->state != BUF_BLOCK_FILE_PAGE);
ut_a(!block->in_LRU_list); ut_a(!block->in_LRU_list);
if (srv_use_awe) { if (srv_use_awe) {
if (block->frame) { if (block->frame) {
/* Remove from the list of mapped pages */ /* Remove from the list of mapped pages */
UT_LIST_REMOVE(awe_LRU_free_mapped, UT_LIST_REMOVE(awe_LRU_free_mapped,
buf_pool->awe_LRU_free_mapped, block); buf_pool->awe_LRU_free_mapped, block);
} else { } else {
@ -414,18 +414,18 @@ loop:
buf_awe_map_page_to_frame(block, FALSE); buf_awe_map_page_to_frame(block, FALSE);
} }
} }
block->state = BUF_BLOCK_READY_FOR_USE; block->state = BUF_BLOCK_READY_FOR_USE;
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
if (started_monitor) { if (started_monitor) {
srv_print_innodb_monitor = mon_value_was; srv_print_innodb_monitor = mon_value_was;
} }
return(block); return(block);
} }
/* If no block was in the free list, search from the end of the LRU /* If no block was in the free list, search from the end of the LRU
list and try to free a block there */ list and try to free a block there */
@ -456,7 +456,7 @@ loop:
(ulong) fil_n_pending_log_flushes, (ulong) fil_n_pending_log_flushes,
(ulong) fil_n_pending_tablespace_flushes, (ulong) fil_n_pending_tablespace_flushes,
(ulong) os_n_file_reads, (ulong) os_n_file_writes, (ulong) os_n_file_reads, (ulong) os_n_file_writes,
(ulong) os_n_fsyncs); (ulong) os_n_fsyncs);
mon_value_was = srv_print_innodb_monitor; mon_value_was = srv_print_innodb_monitor;
started_monitor = TRUE; started_monitor = TRUE;
@ -467,7 +467,7 @@ loop:
/* No free block was found: try to flush the LRU list */ /* No free block was found: try to flush the LRU list */
buf_flush_free_margin(); buf_flush_free_margin();
++srv_buf_pool_wait_free; ++srv_buf_pool_wait_free;
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
@ -492,8 +492,8 @@ loop:
n_iterations++; n_iterations++;
goto loop; goto loop;
} }
/*********************************************************************** /***********************************************************************
Moves the LRU_old pointer so that the length of the old blocks list Moves the LRU_old pointer so that the length of the old blocks list
@ -519,9 +519,9 @@ buf_LRU_old_adjust_len(void)
ut_a(buf_pool->LRU_old->in_LRU_list); ut_a(buf_pool->LRU_old->in_LRU_list);
/* Update the LRU_old pointer if necessary */ /* Update the LRU_old pointer if necessary */
if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) { if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, buf_pool->LRU_old = UT_LIST_GET_PREV(LRU,
buf_pool->LRU_old); buf_pool->LRU_old);
(buf_pool->LRU_old)->old = TRUE; (buf_pool->LRU_old)->old = TRUE;
@ -561,16 +561,16 @@ buf_LRU_old_init(void)
while (block != NULL) { while (block != NULL) {
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_a(block->in_LRU_list); ut_a(block->in_LRU_list);
block->old = TRUE; block->old = TRUE;
block = UT_LIST_GET_NEXT(LRU, block); block = UT_LIST_GET_NEXT(LRU, block);
} }
buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU); buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU);
buf_pool->LRU_old_len = UT_LIST_GET_LEN(buf_pool->LRU); buf_pool->LRU_old_len = UT_LIST_GET_LEN(buf_pool->LRU);
buf_LRU_old_adjust_len(); buf_LRU_old_adjust_len();
} }
/********************************************************************** /**********************************************************************
Removes a block from the LRU list. */ Removes a block from the LRU list. */
@ -585,7 +585,7 @@ buf_LRU_remove_block(
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(buf_pool->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_a(block->in_LRU_list); ut_a(block->in_LRU_list);
@ -611,10 +611,10 @@ buf_LRU_remove_block(
if (srv_use_awe && block->frame) { if (srv_use_awe && block->frame) {
/* Remove from the list of mapped pages */ /* Remove from the list of mapped pages */
UT_LIST_REMOVE(awe_LRU_free_mapped, UT_LIST_REMOVE(awe_LRU_free_mapped,
buf_pool->awe_LRU_free_mapped, block); buf_pool->awe_LRU_free_mapped, block);
} }
/* If the LRU list is so short that LRU_old not defined, return */ /* If the LRU list is so short that LRU_old not defined, return */
if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) { if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
@ -624,7 +624,7 @@ buf_LRU_remove_block(
return; return;
} }
ut_ad(buf_pool->LRU_old); ut_ad(buf_pool->LRU_old);
/* Update the LRU_old_len field if necessary */ /* Update the LRU_old_len field if necessary */
if (block->old) { if (block->old) {
@ -634,7 +634,7 @@ buf_LRU_remove_block(
/* Adjust the length of the old block list if necessary */ /* Adjust the length of the old block list if necessary */
buf_LRU_old_adjust_len(); buf_LRU_old_adjust_len();
} }
/********************************************************************** /**********************************************************************
Adds a block to the LRU list end. */ Adds a block to the LRU list end. */
@ -645,7 +645,7 @@ buf_LRU_add_block_to_end_low(
buf_block_t* block) /* in: control block */ buf_block_t* block) /* in: control block */
{ {
buf_block_t* last_block; buf_block_t* last_block;
ut_ad(buf_pool); ut_ad(buf_pool);
ut_ad(block); ut_ad(block);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
@ -662,7 +662,7 @@ buf_LRU_add_block_to_end_low(
block->LRU_position = last_block->LRU_position; block->LRU_position = last_block->LRU_position;
} else { } else {
block->LRU_position = buf_pool_clock_tic(); block->LRU_position = buf_pool_clock_tic();
} }
ut_a(!block->in_LRU_list); ut_a(!block->in_LRU_list);
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, block); UT_LIST_ADD_LAST(LRU, buf_pool->LRU, block);
@ -670,11 +670,11 @@ buf_LRU_add_block_to_end_low(
if (srv_use_awe && block->frame) { if (srv_use_awe && block->frame) {
/* Add to the list of mapped pages */ /* Add to the list of mapped pages */
UT_LIST_ADD_LAST(awe_LRU_free_mapped, UT_LIST_ADD_LAST(awe_LRU_free_mapped,
buf_pool->awe_LRU_free_mapped, block); buf_pool->awe_LRU_free_mapped, block);
} }
if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) { if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
buf_pool->LRU_old_len++; buf_pool->LRU_old_len++;
@ -695,7 +695,7 @@ buf_LRU_add_block_to_end_low(
buf_LRU_old_init(); buf_LRU_old_init();
} }
} }
/********************************************************************** /**********************************************************************
Adds a block to the LRU list. */ Adds a block to the LRU list. */
@ -710,7 +710,7 @@ buf_LRU_add_block_low(
the start, regardless of this parameter */ the start, regardless of this parameter */
{ {
ulint cl; ulint cl;
ut_ad(buf_pool); ut_ad(buf_pool);
ut_ad(block); ut_ad(block);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
@ -727,7 +727,7 @@ buf_LRU_add_block_low(
/* Add to the list of mapped pages; for simplicity we always /* Add to the list of mapped pages; for simplicity we always
add to the start, even if the user would have set 'old' add to the start, even if the user would have set 'old'
TRUE */ TRUE */
UT_LIST_ADD_FIRST(awe_LRU_free_mapped, UT_LIST_ADD_FIRST(awe_LRU_free_mapped,
buf_pool->awe_LRU_free_mapped, block); buf_pool->awe_LRU_free_mapped, block);
} }
@ -736,7 +736,7 @@ buf_LRU_add_block_low(
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, block); UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, block);
block->LRU_position = cl; block->LRU_position = cl;
block->freed_page_clock = buf_pool->freed_page_clock; block->freed_page_clock = buf_pool->freed_page_clock;
} else { } else {
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old, UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
@ -765,8 +765,8 @@ buf_LRU_add_block_low(
defined: init it */ defined: init it */
buf_LRU_old_init(); buf_LRU_old_init();
} }
} }
/********************************************************************** /**********************************************************************
Adds a block to the LRU list. */ Adds a block to the LRU list. */
@ -820,25 +820,25 @@ buf_LRU_block_free_non_file_page(
ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(buf_pool->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_ad(block); ut_ad(block);
ut_a((block->state == BUF_BLOCK_MEMORY) ut_a((block->state == BUF_BLOCK_MEMORY)
|| (block->state == BUF_BLOCK_READY_FOR_USE)); || (block->state == BUF_BLOCK_READY_FOR_USE));
ut_a(block->n_pointers == 0); ut_a(block->n_pointers == 0);
ut_a(!block->in_free_list); ut_a(!block->in_free_list);
block->state = BUF_BLOCK_NOT_USED; block->state = BUF_BLOCK_NOT_USED;
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
/* Wipe contents of page to reveal possible stale pointers to it */ /* Wipe contents of page to reveal possible stale pointers to it */
memset(block->frame, '\0', UNIV_PAGE_SIZE); memset(block->frame, '\0', UNIV_PAGE_SIZE);
#endif #endif
UT_LIST_ADD_FIRST(free, buf_pool->free, block); UT_LIST_ADD_FIRST(free, buf_pool->free, block);
block->in_free_list = TRUE; block->in_free_list = TRUE;
if (srv_use_awe && block->frame) { if (srv_use_awe && block->frame) {
/* Add to the list of mapped pages */ /* Add to the list of mapped pages */
UT_LIST_ADD_FIRST(awe_LRU_free_mapped, UT_LIST_ADD_FIRST(awe_LRU_free_mapped,
buf_pool->awe_LRU_free_mapped, block); buf_pool->awe_LRU_free_mapped, block);
} }
@ -859,7 +859,7 @@ buf_LRU_block_remove_hashed_page(
ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(buf_pool->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_ad(block); ut_ad(block);
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_a(block->io_fix == 0); ut_a(block->io_fix == 0);
ut_a(block->buf_fix_count == 0); ut_a(block->buf_fix_count == 0);
@ -870,31 +870,31 @@ buf_LRU_block_remove_hashed_page(
buf_pool->freed_page_clock += 1; buf_pool->freed_page_clock += 1;
/* Note that if AWE is enabled the block may not have a frame at all */ /* Note that if AWE is enabled the block may not have a frame at all */
buf_block_modify_clock_inc(block); buf_block_modify_clock_inc(block);
if (block != buf_page_hash_get(block->space, block->offset)) { if (block != buf_page_hash_get(block->space, block->offset)) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: page %lu %lu not found from the hash table\n", "InnoDB: Error: page %lu %lu not found from the hash table\n",
(ulong) block->space, (ulong) block->space,
(ulong) block->offset); (ulong) block->offset);
if (buf_page_hash_get(block->space, block->offset)) { if (buf_page_hash_get(block->space, block->offset)) {
fprintf(stderr, fprintf(stderr,
"InnoDB: From hash table we find block %p of %lu %lu which is not %p\n", "InnoDB: From hash table we find block %p of %lu %lu which is not %p\n",
buf_page_hash_get(block->space, block->offset), buf_page_hash_get(block->space, block->offset),
(ulong) buf_page_hash_get(block->space, block->offset)->space, (ulong) buf_page_hash_get(block->space, block->offset)->space,
(ulong) buf_page_hash_get(block->space, block->offset)->offset, (ulong) buf_page_hash_get(block->space, block->offset)->offset,
block); block);
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
buf_print(); buf_print();
buf_LRU_print(); buf_LRU_print();
buf_validate(); buf_validate();
buf_LRU_validate(); buf_LRU_validate();
#endif #endif
ut_a(0); ut_a(0);
} }
HASH_DELETE(buf_block_t, hash, buf_pool->page_hash, HASH_DELETE(buf_block_t, hash, buf_pool->page_hash,
buf_page_address_fold(block->space, block->offset), buf_page_address_fold(block->space, block->offset),
@ -934,7 +934,7 @@ buf_LRU_validate(void)
ulint old_len; ulint old_len;
ulint new_len; ulint new_len;
ulint LRU_pos; ulint LRU_pos;
ut_ad(buf_pool); ut_ad(buf_pool);
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
@ -946,7 +946,7 @@ buf_LRU_validate(void)
ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE); ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE); ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
} }
UT_LIST_VALIDATE(LRU, buf_block_t, buf_pool->LRU); UT_LIST_VALIDATE(LRU, buf_block_t, buf_pool->LRU);
block = UT_LIST_GET_FIRST(buf_pool->LRU); block = UT_LIST_GET_FIRST(buf_pool->LRU);
@ -979,7 +979,7 @@ buf_LRU_validate(void)
if (buf_pool->LRU_old) { if (buf_pool->LRU_old) {
ut_a(buf_pool->LRU_old_len == old_len); ut_a(buf_pool->LRU_old_len == old_len);
} }
UT_LIST_VALIDATE(free, buf_block_t, buf_pool->free); UT_LIST_VALIDATE(free, buf_block_t, buf_pool->free);
@ -1005,7 +1005,7 @@ buf_LRU_print(void)
buf_block_t* block; buf_block_t* block;
buf_frame_t* frame; buf_frame_t* frame;
ulint len; ulint len;
ut_ad(buf_pool); ut_ad(buf_pool);
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));

View File

@ -79,14 +79,14 @@ buf_read_page_low(
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER; mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER;
if (trx_doublewrite && space == TRX_SYS_SPACE if (trx_doublewrite && space == TRX_SYS_SPACE
&& ( (offset >= trx_doublewrite->block1 && ( (offset >= trx_doublewrite->block1
&& offset < trx_doublewrite->block1 && offset < trx_doublewrite->block1
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
|| (offset >= trx_doublewrite->block2 || (offset >= trx_doublewrite->block2
&& offset < trx_doublewrite->block2 && offset < trx_doublewrite->block2
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE))) { + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE))) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: Warning: trying to read doublewrite buffer page %lu\n", " InnoDB: Warning: trying to read doublewrite buffer page %lu\n",
@ -112,9 +112,9 @@ buf_read_page_low(
/* Trx sys header is so low in the latching order that we play /* Trx sys header is so low in the latching order that we play
safe and do not leave the i/o-completion to an asynchronous safe and do not leave the i/o-completion to an asynchronous
i/o-thread. Ibuf bitmap pages must always be read with i/o-thread. Ibuf bitmap pages must always be read with
syncronous i/o, to make sure they do not get involved in syncronous i/o, to make sure they do not get involved in
thread deadlocks. */ thread deadlocks. */
sync = TRUE; sync = TRUE;
} }
@ -125,16 +125,16 @@ buf_read_page_low(
block = buf_page_init_for_read(err, mode, space, tablespace_version, block = buf_page_init_for_read(err, mode, space, tablespace_version,
offset); offset);
if (block == NULL) { if (block == NULL) {
return(0); return(0);
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
if (buf_debug_prints) { if (buf_debug_prints) {
fprintf(stderr, fprintf(stderr,
"Posting read request for page %lu, sync %lu\n", "Posting read request for page %lu, sync %lu\n",
(ulong) offset, (ulong) offset,
(ulong) sync); (ulong) sync);
} }
#endif #endif
@ -151,9 +151,9 @@ buf_read_page_low(
fil_read */ fil_read */
buf_page_io_complete(block); buf_page_io_complete(block);
} }
return(1); return(1);
} }
/************************************************************************ /************************************************************************
Applies a random read-ahead in buf_pool if there are at least a threshold Applies a random read-ahead in buf_pool if there are at least a threshold
@ -188,15 +188,15 @@ buf_read_ahead_random(
ulint i; ulint i;
if (srv_startup_is_before_trx_rollback_phase) { if (srv_startup_is_before_trx_rollback_phase) {
/* No read-ahead to avoid thread deadlocks */ /* No read-ahead to avoid thread deadlocks */
return(0); return(0);
} }
if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) { if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) {
/* If it is an ibuf bitmap page or trx sys hdr, we do /* If it is an ibuf bitmap page or trx sys hdr, we do
no read-ahead, as that could break the ibuf page access no read-ahead, as that could break the ibuf page access
order */ order */
return(0); return(0);
} }
@ -219,7 +219,7 @@ buf_read_ahead_random(
/* Get the minimum LRU_position field value for an initial segment /* Get the minimum LRU_position field value for an initial segment
of the LRU list, to determine which blocks have recently been added of the LRU list, to determine which blocks have recently been added
to the start of the list. */ to the start of the list. */
LRU_recent_limit = buf_LRU_get_recent_limit(); LRU_recent_limit = buf_LRU_get_recent_limit();
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
@ -229,7 +229,7 @@ buf_read_ahead_random(
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(0); return(0);
} }
/* Count how many blocks in the area have been recently accessed, /* Count how many blocks in the area have been recently accessed,
that is, reside near the start of the LRU list. */ that is, reside near the start of the LRU list. */
@ -238,15 +238,15 @@ buf_read_ahead_random(
block = buf_page_hash_get(space, i); block = buf_page_hash_get(space, i);
if ((block) if ((block)
&& (block->LRU_position > LRU_recent_limit) && (block->LRU_position > LRU_recent_limit)
&& block->accessed) { && block->accessed) {
recent_blocks++; recent_blocks++;
} }
} }
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
if (recent_blocks < BUF_READ_AHEAD_RANDOM_THRESHOLD) { if (recent_blocks < BUF_READ_AHEAD_RANDOM_THRESHOLD) {
/* Do nothing */ /* Do nothing */
@ -270,7 +270,7 @@ buf_read_ahead_random(
if (!ibuf_bitmap_page(i)) { if (!ibuf_bitmap_page(i)) {
count += buf_read_page_low(&err, FALSE, ibuf_mode count += buf_read_page_low(&err, FALSE, ibuf_mode
| OS_AIO_SIMULATED_WAKE_LATER, | OS_AIO_SIMULATED_WAKE_LATER,
space, tablespace_version, i); space, tablespace_version, i);
if (err == DB_TABLESPACE_DELETED) { if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
@ -285,7 +285,7 @@ buf_read_ahead_random(
/* In simulated aio we wake the aio handler threads only after /* In simulated aio we wake the aio handler threads only after
queuing all aio requests, in native aio the following call does queuing all aio requests, in native aio the following call does
nothing: */ nothing: */
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
@ -293,11 +293,11 @@ buf_read_ahead_random(
fprintf(stderr, fprintf(stderr,
"Random read-ahead space %lu offset %lu pages %lu\n", "Random read-ahead space %lu offset %lu pages %lu\n",
(ulong) space, (ulong) offset, (ulong) space, (ulong) offset,
(ulong) count); (ulong) count);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
++srv_read_ahead_rnd; ++srv_read_ahead_rnd;
return(count); return(count);
} }
@ -330,9 +330,9 @@ buf_read_page(
count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space, count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
tablespace_version, offset); tablespace_version, offset);
srv_buf_pool_reads+= count2; srv_buf_pool_reads+= count2;
if (err == DB_TABLESPACE_DELETED) { if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: Error: trying to access tablespace %lu page no. %lu,\n" " InnoDB: Error: trying to access tablespace %lu page no. %lu,\n"
"InnoDB: but the tablespace does not exist or is just being dropped.\n", "InnoDB: but the tablespace does not exist or is just being dropped.\n",
@ -391,17 +391,17 @@ buf_read_ahead_linear(
ulint low, high; ulint low, high;
ulint err; ulint err;
ulint i; ulint i;
if (srv_startup_is_before_trx_rollback_phase) { if (srv_startup_is_before_trx_rollback_phase) {
/* No read-ahead to avoid thread deadlocks */ /* No read-ahead to avoid thread deadlocks */
return(0); return(0);
} }
if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) { if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) {
/* If it is an ibuf bitmap page or trx sys hdr, we do /* If it is an ibuf bitmap page or trx sys hdr, we do
no read-ahead, as that could break the ibuf page access no read-ahead, as that could break the ibuf page access
order */ order */
return(0); return(0);
} }
@ -437,7 +437,7 @@ buf_read_ahead_linear(
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
return(0); return(0);
} }
/* Check that almost all pages in the area have been accessed; if /* Check that almost all pages in the area have been accessed; if
offset == low, the accesses must be in a descending order, otherwise, offset == low, the accesses must be in a descending order, otherwise,
@ -453,14 +453,15 @@ buf_read_ahead_linear(
for (i = low; i < high; i++) { for (i = low; i < high; i++) {
block = buf_page_hash_get(space, i); block = buf_page_hash_get(space, i);
if ((block == NULL) || !block->accessed) { if ((block == NULL) || !block->accessed) {
/* Not accessed */ /* Not accessed */
fail_count++; fail_count++;
} else if (pred_block && (ut_ulint_cmp(block->LRU_position, } else if (pred_block
pred_block->LRU_position) && (ut_ulint_cmp(block->LRU_position,
!= asc_or_desc)) { pred_block->LRU_position)
!= asc_or_desc)) {
/* Accesses not in the right order */ /* Accesses not in the right order */
fail_count++; fail_count++;
@ -489,27 +490,27 @@ buf_read_ahead_linear(
} }
frame = block->frame; frame = block->frame;
/* Read the natural predecessor and successor page addresses from /* Read the natural predecessor and successor page addresses from
the page; NOTE that because the calling thread may have an x-latch the page; NOTE that because the calling thread may have an x-latch
on the page, we do not acquire an s-latch on the page, this is to on the page, we do not acquire an s-latch on the page, this is to
prevent deadlocks. Even if we read values which are nonsense, the prevent deadlocks. Even if we read values which are nonsense, the
algorithm will work. */ algorithm will work. */
pred_offset = fil_page_get_prev(frame); pred_offset = fil_page_get_prev(frame);
succ_offset = fil_page_get_next(frame); succ_offset = fil_page_get_next(frame);
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
if ((offset == low) && (succ_offset == offset + 1)) { if ((offset == low) && (succ_offset == offset + 1)) {
/* This is ok, we can continue */ /* This is ok, we can continue */
new_offset = pred_offset; new_offset = pred_offset;
} else if ((offset == high - 1) && (pred_offset == offset - 1)) { } else if ((offset == high - 1) && (pred_offset == offset - 1)) {
/* This is ok, we can continue */ /* This is ok, we can continue */
new_offset = succ_offset; new_offset = succ_offset;
} else { } else {
/* Successor or predecessor not in the right order */ /* Successor or predecessor not in the right order */
@ -548,7 +549,7 @@ buf_read_ahead_linear(
full read batch to be posted, we use special heuristics here */ full read batch to be posted, we use special heuristics here */
os_aio_simulated_put_read_threads_to_sleep(); os_aio_simulated_put_read_threads_to_sleep();
for (i = low; i < high; i++) { for (i = low; i < high; i++) {
/* It is only sensible to do read-ahead in the non-sync /* It is only sensible to do read-ahead in the non-sync
aio mode: hence FALSE as the first parameter */ aio mode: hence FALSE as the first parameter */
@ -556,7 +557,7 @@ buf_read_ahead_linear(
if (!ibuf_bitmap_page(i)) { if (!ibuf_bitmap_page(i)) {
count += buf_read_page_low(&err, FALSE, ibuf_mode count += buf_read_page_low(&err, FALSE, ibuf_mode
| OS_AIO_SIMULATED_WAKE_LATER, | OS_AIO_SIMULATED_WAKE_LATER,
space, tablespace_version, i); space, tablespace_version, i);
if (err == DB_TABLESPACE_DELETED) { if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
@ -571,7 +572,7 @@ buf_read_ahead_linear(
/* In simulated aio we wake the aio handler threads only after /* In simulated aio we wake the aio handler threads only after
queuing all aio requests, in native aio the following call does queuing all aio requests, in native aio the following call does
nothing: */ nothing: */
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
/* Flush pages from the end of the LRU list if necessary */ /* Flush pages from the end of the LRU list if necessary */
@ -585,7 +586,7 @@ buf_read_ahead_linear(
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
++srv_read_ahead_seq; ++srv_read_ahead_seq;
return(count); return(count);
} }
@ -616,11 +617,11 @@ buf_read_ibuf_merge_pages(
ut_ad(!ibuf_inside()); ut_ad(!ibuf_inside());
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
ut_a(n_stored < UNIV_PAGE_SIZE); ut_a(n_stored < UNIV_PAGE_SIZE);
#endif #endif
while (buf_pool->n_pend_reads > while (buf_pool->n_pend_reads >
buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) { buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
os_thread_sleep(500000); os_thread_sleep(500000);
} }
for (i = 0; i < n_stored; i++) { for (i = 0; i < n_stored; i++) {
if ((i + 1 == n_stored) && sync) { if ((i + 1 == n_stored) && sync) {
@ -639,7 +640,7 @@ buf_read_ibuf_merge_pages(
page_nos[i], FALSE); page_nos[i], FALSE);
} }
} }
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
/* Flush pages from the end of the LRU list if necessary */ /* Flush pages from the end of the LRU list if necessary */
@ -704,14 +705,14 @@ buf_read_recv_pages(
if ((i + 1 == n_stored) && sync) { if ((i + 1 == n_stored) && sync) {
buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space, buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
tablespace_version, page_nos[i]); tablespace_version, page_nos[i]);
} else { } else {
buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
| OS_AIO_SIMULATED_WAKE_LATER, | OS_AIO_SIMULATED_WAKE_LATER,
space, tablespace_version, page_nos[i]); space, tablespace_version, page_nos[i]);
} }
} }
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
/* Flush pages from the end of the LRU list if necessary */ /* Flush pages from the end of the LRU list if necessary */

View File

@ -18,24 +18,24 @@ Created 5/30/1994 Heikki Tuuri
#include "dict0dict.h" #include "dict0dict.h"
#include "btr0cur.h" #include "btr0cur.h"
#ifdef UNIV_DEBUG
byte data_error; /* data pointers of tuple fields are initialized byte data_error; /* data pointers of tuple fields are initialized
to point here for error checking */ to point here for error checking */
#ifdef UNIV_DEBUG
ulint data_dummy; /* this is used to fool the compiler in ulint data_dummy; /* this is used to fool the compiler in
dtuple_validate */ dtuple_validate */
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/* Some non-inlined functions used in the MySQL interface: */ /* Some non-inlined functions used in the MySQL interface: */
void void
dfield_set_data_noninline( dfield_set_data_noninline(
dfield_t* field, /* in: field */ dfield_t* field, /* in: field */
void* data, /* in: data */ void* data, /* in: data */
ulint len) /* in: length or UNIV_SQL_NULL */ ulint len) /* in: length or UNIV_SQL_NULL */
{ {
dfield_set_data(field, data, len); dfield_set_data(field, data, len);
} }
void* void*
dfield_get_data_noninline( dfield_get_data_noninline(
dfield_t* field) /* in: field */ dfield_t* field) /* in: field */
{ {
@ -47,15 +47,15 @@ dfield_get_len_noninline(
{ {
return(dfield_get_len(field)); return(dfield_get_len(field));
} }
ulint ulint
dtuple_get_n_fields_noninline( dtuple_get_n_fields_noninline(
dtuple_t* tuple) /* in: tuple */ dtuple_t* tuple) /* in: tuple */
{ {
return(dtuple_get_n_fields(tuple)); return(dtuple_get_n_fields(tuple));
} }
dfield_t* dfield_t*
dtuple_get_nth_field_noninline( dtuple_get_nth_field_noninline(
dtuple_t* tuple, /* in: tuple */ dtuple_t* tuple, /* in: tuple */
ulint n) /* in: index of field */ ulint n) /* in: index of field */
{ {
return(dtuple_get_nth_field(tuple, n)); return(dtuple_get_nth_field(tuple, n));
@ -83,7 +83,7 @@ dfield_data_is_binary_equal(
} }
if (0 != ut_memcmp(field->data, data, len)) { if (0 != ut_memcmp(field->data, data, len)) {
return(FALSE); return(FALSE);
} }
@ -122,18 +122,18 @@ dtuple_datas_are_ordering_equal(
return(FALSE); return(FALSE);
} }
for (i = 0; i < n_fields; i++) { for (i = 0; i < n_fields; i++) {
field1 = dtuple_get_nth_field(tuple1, i); field1 = dtuple_get_nth_field(tuple1, i);
field2 = dtuple_get_nth_field(tuple2, i); field2 = dtuple_get_nth_field(tuple2, i);
if (0 != cmp_dfield_dfield(field1, field2)) { if (0 != cmp_dfield_dfield(field1, field2)) {
return(FALSE); return(FALSE);
} }
} }
return(TRUE); return(TRUE);
} }
@ -144,12 +144,12 @@ dtuple_t*
dtuple_create_for_mysql( dtuple_create_for_mysql(
/*====================*/ /*====================*/
/* out, own created dtuple */ /* out, own created dtuple */
void** heap, /* out: created memory heap */ void** heap, /* out: created memory heap */
ulint n_fields) /* in: number of fields */ ulint n_fields) /* in: number of fields */
{ {
*heap = (void*)mem_heap_create(500); *heap = (void*)mem_heap_create(500);
return(dtuple_create(*((mem_heap_t**)heap), n_fields)); return(dtuple_create(*((mem_heap_t**)heap), n_fields));
} }
/************************************************************************* /*************************************************************************
@ -160,12 +160,12 @@ dtuple_free_for_mysql(
/*==================*/ /*==================*/
void* heap) /* in: memory heap where tuple was created */ void* heap) /* in: memory heap where tuple was created */
{ {
mem_heap_free((mem_heap_t*)heap); mem_heap_free((mem_heap_t*)heap);
} }
/************************************************************************* /*************************************************************************
Sets number of fields used in a tuple. Normally this is set in Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */ dtuple_create, but if you want later to set it smaller, you can use this. */
void void
dtuple_set_n_fields( dtuple_set_n_fields(
@ -189,7 +189,7 @@ dfield_check_typed_no_assert(
dfield_t* field) /* in: data field */ dfield_t* field) /* in: data field */
{ {
if (dfield_get_type(field)->mtype > DATA_MYSQL if (dfield_get_type(field)->mtype > DATA_MYSQL
|| dfield_get_type(field)->mtype < DATA_VARCHAR) { || dfield_get_type(field)->mtype < DATA_VARCHAR) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: data field type %lu, len %lu\n", "InnoDB: Error: data field type %lu, len %lu\n",
@ -211,8 +211,8 @@ dtuple_check_typed_no_assert(
dtuple_t* tuple) /* in: tuple */ dtuple_t* tuple) /* in: tuple */
{ {
dfield_t* field; dfield_t* field;
ulint i; ulint i;
if (dtuple_get_n_fields(tuple) > REC_MAX_N_FIELDS) { if (dtuple_get_n_fields(tuple) > REC_MAX_N_FIELDS) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: index entry has %lu fields\n", "InnoDB: Error: index entry has %lu fields\n",
@ -247,7 +247,7 @@ dfield_check_typed(
dfield_t* field) /* in: data field */ dfield_t* field) /* in: data field */
{ {
if (dfield_get_type(field)->mtype > DATA_MYSQL if (dfield_get_type(field)->mtype > DATA_MYSQL
|| dfield_get_type(field)->mtype < DATA_VARCHAR) { || dfield_get_type(field)->mtype < DATA_VARCHAR) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: data field type %lu, len %lu\n", "InnoDB: Error: data field type %lu, len %lu\n",
@ -270,7 +270,7 @@ dtuple_check_typed(
dtuple_t* tuple) /* in: tuple */ dtuple_t* tuple) /* in: tuple */
{ {
dfield_t* field; dfield_t* field;
ulint i; ulint i;
for (i = 0; i < dtuple_get_n_fields(tuple); i++) { for (i = 0; i < dtuple_get_n_fields(tuple); i++) {
@ -294,11 +294,11 @@ dtuple_validate(
dtuple_t* tuple) /* in: tuple */ dtuple_t* tuple) /* in: tuple */
{ {
dfield_t* field; dfield_t* field;
byte* data; byte* data;
ulint n_fields; ulint n_fields;
ulint len; ulint len;
ulint i; ulint i;
ulint j; ulint j;
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N); ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
@ -311,7 +311,7 @@ dtuple_validate(
field = dtuple_get_nth_field(tuple, i); field = dtuple_get_nth_field(tuple, i);
len = dfield_get_len(field); len = dfield_get_len(field);
if (len != UNIV_SQL_NULL) { if (len != UNIV_SQL_NULL) {
data = field->data; data = field->data;
@ -357,7 +357,7 @@ dfield_print(
mtype = dtype_get_mtype(dfield_get_type(dfield)); mtype = dtype_get_mtype(dfield_get_type(dfield));
if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) { if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) {
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
int c = *data++; int c = *data++;
putc(isprint(c) ? c : ' ', stderr); putc(isprint(c) ? c : ' ', stderr);
@ -372,7 +372,7 @@ dfield_print(
/***************************************************************** /*****************************************************************
Pretty prints a dfield value according to its data type. Also the hex string Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */ is printed if a string contains non-printable characters. */
void void
dfield_print_also_hex( dfield_print_also_hex(
@ -399,7 +399,7 @@ dfield_print_also_hex(
if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) { if ((mtype == DATA_CHAR) || (mtype == DATA_VARCHAR)) {
print_also_hex = FALSE; print_also_hex = FALSE;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
int c = *data++; int c = *data++;
if (!isprint(c)) { if (!isprint(c)) {
@ -415,9 +415,9 @@ dfield_print_also_hex(
} }
fputs(" Hex: ", stderr); fputs(" Hex: ", stderr);
data = dfield_get_data(dfield); data = dfield_get_data(dfield);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
fprintf(stderr, "%02lx", (ulint)*data); fprintf(stderr, "%02lx", (ulint)*data);
@ -431,6 +431,22 @@ dfield_print_also_hex(
} }
} }
/*****************************************************************
Print a dfield value using ut_print_buf. */
void
dfield_print_raw(
/*=============*/
FILE* f, /* in: output stream */
dfield_t* dfield) /* in: dfield */
{
if (dfield->len != UNIV_SQL_NULL) {
ut_print_buf(f, dfield->data, dfield->len);
} else {
fputs(" SQL NULL", f);
}
}
/************************************************************** /**************************************************************
The following function prints the contents of a tuple. */ The following function prints the contents of a tuple. */
@ -440,7 +456,6 @@ dtuple_print(
FILE* f, /* in: output stream */ FILE* f, /* in: output stream */
dtuple_t* tuple) /* in: tuple */ dtuple_t* tuple) /* in: tuple */
{ {
dfield_t* field;
ulint n_fields; ulint n_fields;
ulint i; ulint i;
@ -451,13 +466,7 @@ dtuple_print(
for (i = 0; i < n_fields; i++) { for (i = 0; i < n_fields; i++) {
fprintf(f, " %lu:", (ulong) i); fprintf(f, " %lu:", (ulong) i);
field = dtuple_get_nth_field(tuple, i); dfield_print_raw(f, dtuple_get_nth_field(tuple, i));
if (field->len != UNIV_SQL_NULL) {
ut_print_buf(f, field->data, field->len);
} else {
fputs(" SQL NULL", f);
}
putc(';', f); putc(';', f);
} }
@ -497,7 +506,7 @@ dtuple_convert_big_rec(
ibool is_externally_stored; ibool is_externally_stored;
ulint i; ulint i;
ulint j; ulint j;
ut_a(dtuple_check_typed_no_assert(entry)); ut_a(dtuple_check_typed_no_assert(entry));
size = rec_get_converted_size(index, entry); size = rec_get_converted_size(index, entry);
@ -525,9 +534,9 @@ dtuple_convert_big_rec(
n_fields = 0; n_fields = 0;
while (rec_get_converted_size(index, entry) while (rec_get_converted_size(index, entry)
>= ut_min(page_get_free_space_of_empty( >= ut_min(page_get_free_space_of_empty(
index->table->comp) / 2, dict_table_is_comp(index->table)) / 2,
REC_MAX_DATA_SIZE)) { REC_MAX_DATA_SIZE)) {
longest = 0; longest = 0;
for (i = dict_index_get_n_unique_in_tree(index); for (i = dict_index_get_n_unique_in_tree(index);
@ -545,25 +554,27 @@ dtuple_convert_big_rec(
} }
} }
} }
if (!is_externally_stored) { if (!is_externally_stored) {
dfield = dtuple_get_nth_field(entry, i); dfield = dtuple_get_nth_field(entry, i);
if (dfield->len != UNIV_SQL_NULL && if (dfield->len != UNIV_SQL_NULL &&
dfield->len > longest) { dfield->len > longest) {
longest = dfield->len; longest = dfield->len;
longest_i = i; longest_i = i;
} }
} }
} }
/* We do not store externally fields which are smaller than /* We do not store externally fields which are smaller than
DICT_MAX_INDEX_COL_LEN */ DICT_MAX_INDEX_COL_LEN */
ut_a(DICT_MAX_INDEX_COL_LEN > REC_1BYTE_OFFS_LIMIT); #if DICT_MAX_INDEX_COL_LEN <= REC_1BYTE_OFFS_LIMIT
# error "DICT_MAX_INDEX_COL_LEN <= REC_1BYTE_OFFS_LIMIT"
#endif
if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10 if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10
+ DICT_MAX_INDEX_COL_LEN) { + DICT_MAX_INDEX_COL_LEN) {
@ -589,7 +600,7 @@ dtuple_convert_big_rec(
vector->fields[n_fields].field_no = longest_i; vector->fields[n_fields].field_no = longest_i;
ut_a(dfield->len > DICT_MAX_INDEX_COL_LEN); ut_a(dfield->len > DICT_MAX_INDEX_COL_LEN);
vector->fields[n_fields].len = dfield->len vector->fields[n_fields].len = dfield->len
- DICT_MAX_INDEX_COL_LEN; - DICT_MAX_INDEX_COL_LEN;
@ -610,7 +621,7 @@ dtuple_convert_big_rec(
+ dfield->len - BTR_EXTERN_FIELD_REF_SIZE, + dfield->len - BTR_EXTERN_FIELD_REF_SIZE,
0, BTR_EXTERN_FIELD_REF_SIZE); 0, BTR_EXTERN_FIELD_REF_SIZE);
n_fields++; n_fields++;
} }
vector->n_fields = n_fields; vector->n_fields = n_fields;
return(vector); return(vector);
@ -630,10 +641,10 @@ dtuple_convert_back_big_rec(
freed in this function */ freed in this function */
{ {
dfield_t* dfield; dfield_t* dfield;
ulint i; ulint i;
for (i = 0; i < vector->n_fields; i++) { for (i = 0; i < vector->n_fields; i++) {
dfield = dtuple_get_nth_field(entry, dfield = dtuple_get_nth_field(entry,
vector->fields[i].field_no); vector->fields[i].field_no);
/* Copy data from big rec vector */ /* Copy data from big rec vector */
@ -641,10 +652,10 @@ dtuple_convert_back_big_rec(
ut_memcpy(((byte*)dfield->data) ut_memcpy(((byte*)dfield->data)
+ dfield->len - BTR_EXTERN_FIELD_REF_SIZE, + dfield->len - BTR_EXTERN_FIELD_REF_SIZE,
vector->fields[i].data, vector->fields[i].data,
vector->fields[i].len); vector->fields[i].len);
dfield->len = dfield->len + vector->fields[i].len dfield->len = dfield->len + vector->fields[i].len
- BTR_EXTERN_FIELD_REF_SIZE; - BTR_EXTERN_FIELD_REF_SIZE;
} }
mem_heap_free(vector->heap); mem_heap_free(vector->heap);
} }

View File

@ -30,7 +30,7 @@ innobase_get_at_most_n_mbchars(
ulint prefix_len, /* in: prefix length in bytes of the index ulint prefix_len, /* in: prefix length in bytes of the index
(this has to be divided by mbmaxlen to get the (this has to be divided by mbmaxlen to get the
number of CHARACTERS n in the prefix) */ number of CHARACTERS n in the prefix) */
ulint data_len, /* in: length of the string in bytes */ ulint data_len, /* in: length of the string in bytes */
const char* str); /* in: character string */ const char* str); /* in: character string */
/* At the database startup we store the default-charset collation number of /* At the database startup we store the default-charset collation number of
@ -41,7 +41,7 @@ charset-collation code for them. */
ulint data_mysql_default_charset_coll = 99999999; ulint data_mysql_default_charset_coll = 99999999;
dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0, 0}; dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0, 0};
dtype_t* dtype_binary = &dtype_binary_val; dtype_t* dtype_binary = &dtype_binary_val;
/************************************************************************* /*************************************************************************
Determine how many bytes the first n characters of the given string occupy. Determine how many bytes the first n characters of the given string occupy.
@ -97,9 +97,9 @@ dtype_is_string_type(
/* out: TRUE if string type */ /* out: TRUE if string type */
ulint mtype) /* in: InnoDB main data type code: DATA_CHAR, ... */ ulint mtype) /* in: InnoDB main data type code: DATA_CHAR, ... */
{ {
if (mtype <= DATA_BLOB if (mtype <= DATA_BLOB
|| mtype == DATA_MYSQL || mtype == DATA_MYSQL
|| mtype == DATA_VARMYSQL) { || mtype == DATA_VARMYSQL) {
return(TRUE); return(TRUE);
} }
@ -119,9 +119,9 @@ dtype_is_binary_string_type(
ulint mtype, /* in: main data type */ ulint mtype, /* in: main data type */
ulint prtype) /* in: precise type */ ulint prtype) /* in: precise type */
{ {
if ((mtype == DATA_FIXBINARY) if ((mtype == DATA_FIXBINARY)
|| (mtype == DATA_BINARY) || (mtype == DATA_BINARY)
|| (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE))) { || (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE))) {
return(TRUE); return(TRUE);
} }
@ -143,8 +143,8 @@ dtype_is_non_binary_string_type(
ulint prtype) /* in: precise type */ ulint prtype) /* in: precise type */
{ {
if (dtype_is_string_type(mtype) == TRUE if (dtype_is_string_type(mtype) == TRUE
&& dtype_is_binary_string_type(mtype, prtype) == FALSE) { && dtype_is_binary_string_type(mtype, prtype) == FALSE) {
return(TRUE); return(TRUE);
} }
@ -190,7 +190,7 @@ dtype_validate(
{ {
ut_a(type); ut_a(type);
ut_a((type->mtype >= DATA_VARCHAR) && (type->mtype <= DATA_MYSQL)); ut_a((type->mtype >= DATA_VARCHAR) && (type->mtype <= DATA_MYSQL));
if (type->mtype == DATA_SYS) { if (type->mtype == DATA_SYS) {
ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS); ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS);
} }
@ -211,7 +211,7 @@ dtype_print(
ulint mtype; ulint mtype;
ulint prtype; ulint prtype;
ulint len; ulint len;
ut_a(type); ut_a(type);
mtype = type->mtype; mtype = type->mtype;
@ -233,7 +233,7 @@ dtype_print(
} }
len = type->len; len = type->len;
if ((type->mtype == DATA_SYS) if ((type->mtype == DATA_SYS)
|| (type->mtype == DATA_VARCHAR) || (type->mtype == DATA_VARCHAR)
|| (type->mtype == DATA_CHAR)) { || (type->mtype == DATA_CHAR)) {
@ -252,7 +252,7 @@ dtype_print(
} else if (prtype == DATA_ENGLISH) { } else if (prtype == DATA_ENGLISH) {
fputs("DATA_ENGLISH", stderr); fputs("DATA_ENGLISH", stderr);
} else { } else {
fprintf(stderr, "prtype %lu", (ulong) mtype); fprintf(stderr, "prtype %lu", (ulong) prtype);
} }
} }

View File

@ -29,14 +29,14 @@ Gets a pointer to the dictionary header and x-latches its page. */
dict_hdr_t* dict_hdr_t*
dict_hdr_get( dict_hdr_get(
/*=========*/ /*=========*/
/* out: pointer to the dictionary header, /* out: pointer to the dictionary header,
page x-latched */ page x-latched */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
dict_hdr_t* header; dict_hdr_t* header;
ut_ad(mtr); ut_ad(mtr);
header = DICT_HDR + buf_page_get(DICT_HDR_SPACE, DICT_HDR_PAGE_NO, header = DICT_HDR + buf_page_get(DICT_HDR_SPACE, DICT_HDR_PAGE_NO,
RW_X_LATCH, mtr); RW_X_LATCH, mtr);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
@ -59,21 +59,21 @@ dict_hdr_get_new_id(
mtr_t mtr; mtr_t mtr;
ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID) ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID)
|| (type == DICT_HDR_MIX_ID)); || (type == DICT_HDR_MIX_ID));
mtr_start(&mtr); mtr_start(&mtr);
dict_hdr = dict_hdr_get(&mtr); dict_hdr = dict_hdr_get(&mtr);
id = mtr_read_dulint(dict_hdr + type, &mtr); id = mtr_read_dulint(dict_hdr + type, &mtr);
id = ut_dulint_add(id, 1); id = ut_dulint_add(id, 1);
mlog_write_dulint(dict_hdr + type, id, &mtr); mlog_write_dulint(dict_hdr + type, id, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
return(id); return(id);
} }
/************************************************************************** /**************************************************************************
Writes the current value of the row id counter to the dictionary header file Writes the current value of the row id counter to the dictionary header file
@ -96,11 +96,11 @@ dict_hdr_flush_row_id(void)
mtr_start(&mtr); mtr_start(&mtr);
dict_hdr = dict_hdr_get(&mtr); dict_hdr = dict_hdr_get(&mtr);
mlog_write_dulint(dict_hdr + DICT_HDR_ROW_ID, id, &mtr); mlog_write_dulint(dict_hdr + DICT_HDR_ROW_ID, id, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
} }
/********************************************************************* /*********************************************************************
Creates the file page for the dictionary header. This function is Creates the file page for the dictionary header. This function is
@ -116,7 +116,7 @@ dict_hdr_create(
ulint hdr_page_no; ulint hdr_page_no;
ulint root_page_no; ulint root_page_no;
page_t* page; page_t* page;
ut_ad(mtr); ut_ad(mtr);
/* Create the dictionary header file block in a new, allocated file /* Create the dictionary header file block in a new, allocated file
@ -125,7 +125,7 @@ dict_hdr_create(
DICT_HDR + DICT_HDR_FSEG_HEADER, mtr); DICT_HDR + DICT_HDR_FSEG_HEADER, mtr);
hdr_page_no = buf_frame_get_page_no(page); hdr_page_no = buf_frame_get_page_no(page);
ut_a(DICT_HDR_PAGE_NO == hdr_page_no); ut_a(DICT_HDR_PAGE_NO == hdr_page_no);
dict_header = dict_hdr_get(mtr); dict_header = dict_hdr_get(mtr);
@ -147,7 +147,7 @@ dict_hdr_create(
/* Create the B-tree roots for the clustered indexes of the basic /* Create the B-tree roots for the clustered indexes of the basic
system tables */ system tables */
/*--------------------------*/ /*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, DICT_TABLES_ID, FALSE, mtr); DICT_HDR_SPACE, DICT_TABLES_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) { if (root_page_no == FIL_NULL) {
@ -157,7 +157,7 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no, mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no,
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
/*--------------------------*/ /*--------------------------*/
root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE, root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE,
DICT_TABLE_IDS_ID, FALSE, mtr); DICT_TABLE_IDS_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) { if (root_page_no == FIL_NULL) {
@ -167,7 +167,7 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no, mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no,
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
/*--------------------------*/ /*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, DICT_COLUMNS_ID, FALSE, mtr); DICT_HDR_SPACE, DICT_COLUMNS_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) { if (root_page_no == FIL_NULL) {
@ -177,7 +177,7 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_COLUMNS, root_page_no, mlog_write_ulint(dict_header + DICT_HDR_COLUMNS, root_page_no,
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
/*--------------------------*/ /*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, DICT_INDEXES_ID, FALSE, mtr); DICT_HDR_SPACE, DICT_INDEXES_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) { if (root_page_no == FIL_NULL) {
@ -187,7 +187,7 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no, mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no,
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
/*--------------------------*/ /*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, DICT_FIELDS_ID, FALSE, mtr); DICT_HDR_SPACE, DICT_FIELDS_ID, FALSE, mtr);
if (root_page_no == FIL_NULL) { if (root_page_no == FIL_NULL) {
@ -197,7 +197,7 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no, mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no,
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
/*--------------------------*/ /*--------------------------*/
return(TRUE); return(TRUE);
} }
@ -217,12 +217,12 @@ dict_boot(void)
ibool success; ibool success;
mtr_start(&mtr); mtr_start(&mtr);
/* Create the hash tables etc. */ /* Create the hash tables etc. */
dict_init(); dict_init();
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
/* Get the dictionary header */ /* Get the dictionary header */
dict_hdr = dict_hdr_get(&mtr); dict_hdr = dict_hdr_get(&mtr);
@ -237,16 +237,15 @@ dict_boot(void)
header. */ header. */
dict_sys->row_id = ut_dulint_add( dict_sys->row_id = ut_dulint_add(
ut_dulint_align_up( ut_dulint_align_up(
mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID, mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID, &mtr),
&mtr), DICT_HDR_ROW_ID_WRITE_MARGIN),
DICT_HDR_ROW_ID_WRITE_MARGIN), DICT_HDR_ROW_ID_WRITE_MARGIN);
DICT_HDR_ROW_ID_WRITE_MARGIN);
/* Insert into the dictionary cache the descriptions of the basic /* Insert into the dictionary cache the descriptions of the basic
system tables */ system tables */
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, FALSE); table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
@ -258,14 +257,14 @@ dict_boot(void)
dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0); dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
table->id = DICT_TABLES_ID; table->id = DICT_TABLES_ID;
dict_table_add_to_cache(table); dict_table_add_to_cache(table);
dict_sys->sys_tables = table; dict_sys->sys_tables = table;
index = dict_mem_index_create("SYS_TABLES", "CLUST_IND", index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 1); DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 1);
dict_mem_index_add_field(index, "NAME", 0, 0); dict_mem_index_add_field(index, "NAME", 0);
index->id = DICT_TABLES_ID; index->id = DICT_TABLES_ID;
@ -275,14 +274,14 @@ dict_boot(void)
/*-------------------------*/ /*-------------------------*/
index = dict_mem_index_create("SYS_TABLES", "ID_IND", index = dict_mem_index_create("SYS_TABLES", "ID_IND",
DICT_HDR_SPACE, DICT_UNIQUE, 1); DICT_HDR_SPACE, DICT_UNIQUE, 1);
dict_mem_index_add_field(index, "ID", 0, 0); dict_mem_index_add_field(index, "ID", 0);
index->id = DICT_TABLE_IDS_ID; index->id = DICT_TABLE_IDS_ID;
success = dict_index_add_to_cache(table, index, mtr_read_ulint( success = dict_index_add_to_cache(table, index, mtr_read_ulint(
dict_hdr + DICT_HDR_TABLE_IDS, MLOG_4BYTES, &mtr)); dict_hdr + DICT_HDR_TABLE_IDS, MLOG_4BYTES, &mtr));
ut_a(success); ut_a(success);
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, FALSE); table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0); dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0); dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
@ -291,7 +290,7 @@ dict_boot(void)
dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4, 0); dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4, 0);
dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4, 0); dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4, 0);
dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4, 0); dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4, 0);
table->id = DICT_COLUMNS_ID; table->id = DICT_COLUMNS_ID;
dict_table_add_to_cache(table); dict_table_add_to_cache(table);
@ -300,15 +299,15 @@ dict_boot(void)
index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND", index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
dict_mem_index_add_field(index, "TABLE_ID", 0, 0); dict_mem_index_add_field(index, "TABLE_ID", 0);
dict_mem_index_add_field(index, "POS", 0, 0); dict_mem_index_add_field(index, "POS", 0);
index->id = DICT_COLUMNS_ID; index->id = DICT_COLUMNS_ID;
success = dict_index_add_to_cache(table, index, mtr_read_ulint( success = dict_index_add_to_cache(table, index, mtr_read_ulint(
dict_hdr + DICT_HDR_COLUMNS, MLOG_4BYTES, &mtr)); dict_hdr + DICT_HDR_COLUMNS, MLOG_4BYTES, &mtr));
ut_a(success); ut_a(success);
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, FALSE); table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0); dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
@ -336,15 +335,15 @@ dict_boot(void)
index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND", index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
dict_mem_index_add_field(index, "TABLE_ID", 0, 0); dict_mem_index_add_field(index, "TABLE_ID", 0);
dict_mem_index_add_field(index, "ID", 0, 0); dict_mem_index_add_field(index, "ID", 0);
index->id = DICT_INDEXES_ID; index->id = DICT_INDEXES_ID;
success = dict_index_add_to_cache(table, index, mtr_read_ulint( success = dict_index_add_to_cache(table, index, mtr_read_ulint(
dict_hdr + DICT_HDR_INDEXES, MLOG_4BYTES, &mtr)); dict_hdr + DICT_HDR_INDEXES, MLOG_4BYTES, &mtr));
ut_a(success); ut_a(success);
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, FALSE); table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0); dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0); dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
@ -357,8 +356,8 @@ dict_boot(void)
index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND", index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
dict_mem_index_add_field(index, "INDEX_ID", 0, 0); dict_mem_index_add_field(index, "INDEX_ID", 0);
dict_mem_index_add_field(index, "POS", 0, 0); dict_mem_index_add_field(index, "POS", 0);
index->id = DICT_FIELDS_ID; index->id = DICT_FIELDS_ID;
success = dict_index_add_to_cache(table, index, mtr_read_ulint( success = dict_index_add_to_cache(table, index, mtr_read_ulint(
@ -378,7 +377,7 @@ dict_boot(void)
dict_load_sys_table(dict_sys->sys_columns); dict_load_sys_table(dict_sys->sys_columns);
dict_load_sys_table(dict_sys->sys_indexes); dict_load_sys_table(dict_sys->sys_indexes);
dict_load_sys_table(dict_sys->sys_fields); dict_load_sys_table(dict_sys->sys_fields);
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
} }
@ -407,7 +406,7 @@ dict_create(void)
dict_hdr_create(&mtr); dict_hdr_create(&mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
dict_boot(); dict_boot();
dict_insert_initial_data(); dict_insert_initial_data();

View File

@ -33,7 +33,7 @@ dtuple_t*
dict_create_sys_tables_tuple( dict_create_sys_tables_tuple(
/*=========================*/ /*=========================*/
/* out: the tuple which should be inserted */ /* out: the tuple which should be inserted */
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
mem_heap_t* heap) /* in: memory heap from which the memory for mem_heap_t* heap) /* in: memory heap from which the memory for
the built tuple is allocated */ the built tuple is allocated */
{ {
@ -45,7 +45,7 @@ dict_create_sys_tables_tuple(
ut_ad(table && heap); ut_ad(table && heap);
sys_tables = dict_sys->sys_tables; sys_tables = dict_sys->sys_tables;
entry = dtuple_create(heap, 8 + DATA_N_SYS_COLS); entry = dtuple_create(heap, 8 + DATA_N_SYS_COLS);
/* 0: NAME -----------------------------*/ /* 0: NAME -----------------------------*/
@ -62,9 +62,13 @@ dict_create_sys_tables_tuple(
/* 4: N_COLS ---------------------------*/ /* 4: N_COLS ---------------------------*/
dfield = dtuple_get_nth_field(entry, 2); dfield = dtuple_get_nth_field(entry, 2);
#if DICT_TF_COMPACT != 1
#error
#endif
ptr = mem_heap_alloc(heap, 4); ptr = mem_heap_alloc(heap, 4);
mach_write_to_4(ptr, table->n_def mach_write_to_4(ptr, table->n_def
| ((ulint) table->comp << 31)); | ((table->flags & DICT_TF_COMPACT) << 31));
dfield_set_data(dfield, ptr, 4); dfield_set_data(dfield, ptr, 4);
/* 5: TYPE -----------------------------*/ /* 5: TYPE -----------------------------*/
dfield = dtuple_get_nth_field(entry, 3); dfield = dtuple_get_nth_field(entry, 3);
@ -91,7 +95,7 @@ dict_create_sys_tables_tuple(
/* 8: CLUSTER_NAME ---------------------*/ /* 8: CLUSTER_NAME ---------------------*/
dfield = dtuple_get_nth_field(entry, 6); dfield = dtuple_get_nth_field(entry, 6);
if (table->type == DICT_TABLE_CLUSTER_MEMBER) { if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
dfield_set_data(dfield, table->cluster_name, dfield_set_data(dfield, table->cluster_name,
ut_strlen(table->cluster_name)); ut_strlen(table->cluster_name));
ut_error; /* Oracle-style clusters are not supported yet */ ut_error; /* Oracle-style clusters are not supported yet */
@ -108,9 +112,9 @@ dict_create_sys_tables_tuple(
/*----------------------------------*/ /*----------------------------------*/
dict_table_copy_types(entry, sys_tables); dict_table_copy_types(entry, sys_tables);
return(entry); return(entry);
} }
/********************************************************************* /*********************************************************************
Based on a table object, this function builds the entry to be inserted Based on a table object, this function builds the entry to be inserted
@ -120,7 +124,7 @@ dtuple_t*
dict_create_sys_columns_tuple( dict_create_sys_columns_tuple(
/*==========================*/ /*==========================*/
/* out: the tuple which should be inserted */ /* out: the tuple which should be inserted */
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
ulint i, /* in: column number */ ulint i, /* in: column number */
mem_heap_t* heap) /* in: memory heap from which the memory for mem_heap_t* heap) /* in: memory heap from which the memory for
the built tuple is allocated */ the built tuple is allocated */
@ -136,7 +140,7 @@ dict_create_sys_columns_tuple(
column = dict_table_get_nth_col(table, i); column = dict_table_get_nth_col(table, i);
sys_columns = dict_sys->sys_columns; sys_columns = dict_sys->sys_columns;
entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS); entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS);
/* 0: TABLE_ID -----------------------*/ /* 0: TABLE_ID -----------------------*/
@ -190,7 +194,7 @@ dict_create_sys_columns_tuple(
dict_table_copy_types(entry, sys_columns); dict_table_copy_types(entry, sys_columns);
return(entry); return(entry);
} }
/******************************************************************* /*******************************************************************
Builds a table definition to insert. */ Builds a table definition to insert. */
@ -236,7 +240,7 @@ dict_build_table_def_step(
cluster_table = dict_table_get_low(table->cluster_name); cluster_table = dict_table_get_low(table->cluster_name);
if (cluster_table == NULL) { if (cluster_table == NULL) {
return(DB_CLUSTER_NOT_FOUND); return(DB_CLUSTER_NOT_FOUND);
} }
@ -244,7 +248,7 @@ dict_build_table_def_step(
table->space = cluster_table->space; table->space = cluster_table->space;
table->mix_len = cluster_table->mix_len; table->mix_len = cluster_table->mix_len;
table->mix_id = dict_hdr_get_new_id(DICT_HDR_MIX_ID); table->mix_id = dict_hdr_get_new_id(DICT_HDR_MIX_ID);
} }
@ -256,7 +260,7 @@ dict_build_table_def_step(
- page 2 is the first inode page, - page 2 is the first inode page,
- page 3 will contain the root of the clustered index of the - page 3 will contain the root of the clustered index of the
table we create here. */ table we create here. */
table->space = 0; /* reset to zero for the call below */ table->space = 0; /* reset to zero for the call below */
if (table->dir_path_of_temp_table) { if (table->dir_path_of_temp_table) {
@ -281,7 +285,7 @@ dict_build_table_def_step(
mtr_start(&mtr); mtr_start(&mtr);
fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
} }
@ -306,7 +310,7 @@ dict_build_col_def_step(
row = dict_create_sys_columns_tuple(node->table, node->col_no, row = dict_create_sys_columns_tuple(node->table, node->col_no,
node->heap); node->heap);
ins_node_set_new_row(node->col_def, row); ins_node_set_new_row(node->col_def, row);
return(DB_SUCCESS); return(DB_SUCCESS);
} }
@ -318,7 +322,7 @@ dtuple_t*
dict_create_sys_indexes_tuple( dict_create_sys_indexes_tuple(
/*==========================*/ /*==========================*/
/* out: the tuple which should be inserted */ /* out: the tuple which should be inserted */
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
mem_heap_t* heap) /* in: memory heap from which the memory for mem_heap_t* heap) /* in: memory heap from which the memory for
the built tuple is allocated */ the built tuple is allocated */
{ {
@ -336,7 +340,7 @@ dict_create_sys_indexes_tuple(
sys_indexes = dict_sys->sys_indexes; sys_indexes = dict_sys->sys_indexes;
table = dict_table_get_low(index->table_name); table = dict_table_get_low(index->table_name);
entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS); entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS);
/* 0: TABLE_ID -----------------------*/ /* 0: TABLE_ID -----------------------*/
@ -400,7 +404,7 @@ dict_create_sys_indexes_tuple(
dict_table_copy_types(entry, sys_indexes); dict_table_copy_types(entry, sys_indexes);
return(entry); return(entry);
} }
/********************************************************************* /*********************************************************************
Based on an index object, this function builds the entry to be inserted Based on an index object, this function builds the entry to be inserted
@ -410,7 +414,7 @@ dtuple_t*
dict_create_sys_fields_tuple( dict_create_sys_fields_tuple(
/*=========================*/ /*=========================*/
/* out: the tuple which should be inserted */ /* out: the tuple which should be inserted */
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
ulint i, /* in: field number */ ulint i, /* in: field number */
mem_heap_t* heap) /* in: memory heap from which the memory for mem_heap_t* heap) /* in: memory heap from which the memory for
the built tuple is allocated */ the built tuple is allocated */
@ -426,15 +430,15 @@ dict_create_sys_fields_tuple(
ut_ad(index && heap); ut_ad(index && heap);
for (j = 0; j < index->n_fields; j++) { for (j = 0; j < index->n_fields; j++) {
if (dict_index_get_nth_field(index, j)->prefix_len > 0) { if (dict_index_get_nth_field(index, j)->prefix_len > 0) {
index_contains_column_prefix_field = TRUE; index_contains_column_prefix_field = TRUE;
} }
} }
field = dict_index_get_nth_field(index, i); field = dict_index_get_nth_field(index, i);
sys_fields = dict_sys->sys_fields; sys_fields = dict_sys->sys_fields;
entry = dtuple_create(heap, 3 + DATA_N_SYS_COLS); entry = dtuple_create(heap, 3 + DATA_N_SYS_COLS);
/* 0: INDEX_ID -----------------------*/ /* 0: INDEX_ID -----------------------*/
@ -449,19 +453,19 @@ dict_create_sys_fields_tuple(
dfield = dtuple_get_nth_field(entry, 1); dfield = dtuple_get_nth_field(entry, 1);
ptr = mem_heap_alloc(heap, 4); ptr = mem_heap_alloc(heap, 4);
if (index_contains_column_prefix_field) { if (index_contains_column_prefix_field) {
/* If there are column prefix fields in the index, then /* If there are column prefix fields in the index, then
we store the number of the field to the 2 HIGH bytes we store the number of the field to the 2 HIGH bytes
and the prefix length to the 2 low bytes, */ and the prefix length to the 2 low bytes, */
mach_write_to_4(ptr, (i << 16) + field->prefix_len); mach_write_to_4(ptr, (i << 16) + field->prefix_len);
} else { } else {
/* Else we store the number of the field to the 2 LOW bytes. /* Else we store the number of the field to the 2 LOW bytes.
This is to keep the storage format compatible with This is to keep the storage format compatible with
InnoDB versions < 4.0.14. */ InnoDB versions < 4.0.14. */
mach_write_to_4(ptr, i); mach_write_to_4(ptr, i);
} }
dfield_set_data(dfield, ptr, 4); dfield_set_data(dfield, ptr, 4);
@ -473,9 +477,9 @@ dict_create_sys_fields_tuple(
/*---------------------------------*/ /*---------------------------------*/
dict_table_copy_types(entry, sys_fields); dict_table_copy_types(entry, sys_fields);
return(entry); return(entry);
} }
/********************************************************************* /*********************************************************************
Creates the tuple with which the index entry is searched for writing the index Creates the tuple with which the index entry is searched for writing the index
@ -498,13 +502,13 @@ dict_create_search_tuple(
search_tuple = dtuple_create(heap, 2); search_tuple = dtuple_create(heap, 2);
field1 = dtuple_get_nth_field(tuple, 0); field1 = dtuple_get_nth_field(tuple, 0);
field2 = dtuple_get_nth_field(search_tuple, 0); field2 = dtuple_get_nth_field(search_tuple, 0);
dfield_copy(field2, field1); dfield_copy(field2, field1);
field1 = dtuple_get_nth_field(tuple, 1); field1 = dtuple_get_nth_field(tuple, 1);
field2 = dtuple_get_nth_field(search_tuple, 1); field2 = dtuple_get_nth_field(search_tuple, 1);
dfield_copy(field2, field1); dfield_copy(field2, field1);
@ -547,8 +551,8 @@ dict_build_index_def_step(
node->table = table; node->table = table;
ut_ad((UT_LIST_GET_LEN(table->indexes) > 0) ut_ad((UT_LIST_GET_LEN(table->indexes) > 0)
|| (index->type & DICT_CLUSTERED)); || (index->type & DICT_CLUSTERED));
index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID); index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
/* Inherit the space id from the table; we store all indexes of a /* Inherit the space id from the table; we store all indexes of a
@ -577,7 +581,7 @@ dict_build_field_def_step(
dtuple_t* row; dtuple_t* row;
index = node->index; index = node->index;
row = dict_create_sys_fields_tuple(index, node->field_no, node->heap); row = dict_create_sys_fields_tuple(index, node->field_no, node->heap);
ins_node_set_new_row(node->field_def, row); ins_node_set_new_row(node->field_def, row);
@ -605,7 +609,7 @@ dict_create_index_tree_step(
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
index = node->index; index = node->index;
table = node->table; table = node->table;
sys_indexes = dict_sys->sys_indexes; sys_indexes = dict_sys->sys_indexes;
@ -626,7 +630,7 @@ dict_create_index_tree_step(
mtr_start(&mtr); mtr_start(&mtr);
search_tuple = dict_create_search_tuple(node->ind_row, node->heap); search_tuple = dict_create_search_tuple(node->ind_row, node->heap);
btr_pcur_open(UT_LIST_GET_FIRST(sys_indexes->indexes), btr_pcur_open(UT_LIST_GET_FIRST(sys_indexes->indexes),
search_tuple, PAGE_CUR_L, BTR_MODIFY_LEAF, search_tuple, PAGE_CUR_L, BTR_MODIFY_LEAF,
&pcur, &mtr); &pcur, &mtr);
@ -634,7 +638,7 @@ dict_create_index_tree_step(
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
node->page_no = btr_create(index->type, index->space, index->id, node->page_no = btr_create(index->type, index->space, index->id,
table->comp, &mtr); dict_table_is_comp(table), &mtr);
/* printf("Created a new index tree in space %lu root page %lu\n", /* printf("Created a new index tree in space %lu root page %lu\n",
index->space, index->page_no); */ index->space, index->page_no); */
@ -666,16 +670,16 @@ dict_drop_index_tree(
ulint space; ulint space;
byte* ptr; byte* ptr;
ulint len; ulint len;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_a(!dict_sys->sys_indexes->comp); ut_a(!dict_table_is_comp(dict_sys->sys_indexes));
ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
ut_ad(len == 4); ut_ad(len == 4);
root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
if (root_page_no == FIL_NULL) { if (root_page_no == FIL_NULL) {
@ -706,7 +710,7 @@ dict_drop_index_tree(
/* Then we free the root page in the same mini-transaction where /* Then we free the root page in the same mini-transaction where
we write FIL_NULL to the appropriate field in the SYS_INDEXES we write FIL_NULL to the appropriate field in the SYS_INDEXES
record: this mini-transaction marks the B-tree totally freed */ record: this mini-transaction marks the B-tree totally freed */
/* printf("Dropping index tree in space %lu root page %lu\n", space, /* printf("Dropping index tree in space %lu root page %lu\n", space,
root_page_no); */ root_page_no); */
btr_free_root(space, root_page_no, mtr); btr_free_root(space, root_page_no, mtr);
@ -743,7 +747,7 @@ dict_truncate_index_tree(
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_a(!dict_sys->sys_indexes->comp); ut_a(!dict_table_is_comp(dict_sys->sys_indexes));
ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
ut_ad(len == 4); ut_ad(len == 4);
@ -853,7 +857,7 @@ tab_create_graph_create(
tab_node_t* node; tab_node_t* node;
node = mem_heap_alloc(heap, sizeof(tab_node_t)); node = mem_heap_alloc(heap, sizeof(tab_node_t));
node->common.type = QUE_NODE_CREATE_TABLE; node->common.type = QUE_NODE_CREATE_TABLE;
node->table = table; node->table = table;
@ -862,9 +866,9 @@ tab_create_graph_create(
node->heap = mem_heap_create(256); node->heap = mem_heap_create(256);
node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables, node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables,
heap); heap);
node->tab_def->common.parent = node; node->tab_def->common.parent = node;
node->col_def = ins_node_create(INS_DIRECT, dict_sys->sys_columns, node->col_def = ins_node_create(INS_DIRECT, dict_sys->sys_columns,
heap); heap);
node->col_def->common.parent = node; node->col_def->common.parent = node;
@ -899,7 +903,7 @@ ind_create_graph_create(
node->heap = mem_heap_create(256); node->heap = mem_heap_create(256);
node->ind_def = ins_node_create(INS_DIRECT, node->ind_def = ins_node_create(INS_DIRECT,
dict_sys->sys_indexes, heap); dict_sys->sys_indexes, heap);
node->ind_def->common.parent = node; node->ind_def->common.parent = node;
node->field_def = ins_node_create(INS_DIRECT, node->field_def = ins_node_create(INS_DIRECT,
@ -931,7 +935,7 @@ dict_create_table_step(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_TABLE); ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_TABLE);
@ -950,7 +954,7 @@ dict_create_table_step(
goto function_exit; goto function_exit;
} }
node->state = TABLE_BUILD_COL_DEF; node->state = TABLE_BUILD_COL_DEF;
node->col_no = 0; node->col_no = 0;
@ -971,7 +975,7 @@ dict_create_table_step(
} }
node->col_no++; node->col_no++;
thr->run_node = node->col_def; thr->run_node = node->col_def;
return(thr); return(thr);
@ -985,7 +989,7 @@ dict_create_table_step(
/* Table was correctly defined: do NOT commit the transaction /* Table was correctly defined: do NOT commit the transaction
(CREATE TABLE does NOT do an implicit commit of the current (CREATE TABLE does NOT do an implicit commit of the current
transaction) */ transaction) */
node->state = TABLE_ADD_TO_CACHE; node->state = TABLE_ADD_TO_CACHE;
/* thr->run_node = node->commit_node; /* thr->run_node = node->commit_node;
@ -1018,7 +1022,7 @@ function_exit:
thr->run_node = que_node_get_parent(node); thr->run_node = que_node_get_parent(node);
return(thr); return(thr);
} }
/*************************************************************** /***************************************************************
Creates an index. This is a high-level function used in SQL execution Creates an index. This is a high-level function used in SQL execution
@ -1041,7 +1045,7 @@ dict_create_index_step(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_INDEX); ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_INDEX);
@ -1058,7 +1062,7 @@ dict_create_index_step(
goto function_exit; goto function_exit;
} }
node->state = INDEX_BUILD_FIELD_DEF; node->state = INDEX_BUILD_FIELD_DEF;
node->field_no = 0; node->field_no = 0;
@ -1079,7 +1083,7 @@ dict_create_index_step(
} }
node->field_no++; node->field_no++;
thr->run_node = node->field_def; thr->run_node = node->field_def;
return(thr); return(thr);
@ -1105,7 +1109,7 @@ dict_create_index_step(
/* Index was correctly defined: do NOT commit the transaction /* Index was correctly defined: do NOT commit the transaction
(CREATE INDEX does NOT currently do an implicit commit of (CREATE INDEX does NOT currently do an implicit commit of
the current transaction) */ the current transaction) */
node->state = INDEX_ADD_TO_CACHE; node->state = INDEX_ADD_TO_CACHE;
/* thr->run_node = node->commit_node; /* thr->run_node = node->commit_node;
@ -1141,7 +1145,7 @@ function_exit:
thr->run_node = que_node_get_parent(node); thr->run_node = que_node_get_parent(node);
return(thr); return(thr);
} }
/******************************************************************** /********************************************************************
Creates the foreign key constraints system tables inside InnoDB Creates the foreign key constraints system tables inside InnoDB
@ -1159,29 +1163,29 @@ dict_create_or_check_foreign_constraint_tables(void)
que_t* graph; que_t* graph;
ulint error; ulint error;
trx_t* trx; trx_t* trx;
const char* str; const char* str;
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
table1 = dict_table_get_low("SYS_FOREIGN"); table1 = dict_table_get_low("SYS_FOREIGN");
table2 = dict_table_get_low("SYS_FOREIGN_COLS"); table2 = dict_table_get_low("SYS_FOREIGN_COLS");
if (table1 && table2
&& UT_LIST_GET_LEN(table1->indexes) == 3
&& UT_LIST_GET_LEN(table2->indexes) == 1) {
/* Foreign constraint system tables have already been if (table1 && table2
created, and they are ok */ && UT_LIST_GET_LEN(table1->indexes) == 3
&& UT_LIST_GET_LEN(table2->indexes) == 1) {
/* Foreign constraint system tables have already been
created, and they are ok */
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
return(DB_SUCCESS); return(DB_SUCCESS);
} }
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
trx = trx_allocate_for_mysql(); trx = trx_allocate_for_mysql();
trx->op_info = "creating foreign key sys tables"; trx->op_info = "creating foreign key sys tables";
row_mysql_lock_data_dictionary(trx); row_mysql_lock_data_dictionary(trx);
@ -1204,7 +1208,7 @@ dict_create_or_check_foreign_constraint_tables(void)
/* NOTE: in dict_load_foreigns we use the fact that /* NOTE: in dict_load_foreigns we use the fact that
there are 2 secondary indexes on SYS_FOREIGN, and they there are 2 secondary indexes on SYS_FOREIGN, and they
are defined just like below */ are defined just like below */
/* NOTE: when designing InnoDB's foreign key support in 2001, we made /* NOTE: when designing InnoDB's foreign key support in 2001, we made
an error and made the table names and the foreign key id of type an error and made the table names and the foreign key id of type
'CHAR' (internally, really a VARCHAR). We should have made the type 'CHAR' (internally, really a VARCHAR). We should have made the type
@ -1243,7 +1247,7 @@ dict_create_or_check_foreign_constraint_tables(void)
if (error != DB_SUCCESS) { if (error != DB_SUCCESS) {
fprintf(stderr, "InnoDB: error %lu in creation\n", fprintf(stderr, "InnoDB: error %lu in creation\n",
(ulong) error); (ulong) error);
ut_a(error == DB_OUT_OF_FILE_SPACE); ut_a(error == DB_OUT_OF_FILE_SPACE);
fprintf(stderr, "InnoDB: creation failed\n"); fprintf(stderr, "InnoDB: creation failed\n");
@ -1258,14 +1262,14 @@ dict_create_or_check_foreign_constraint_tables(void)
} }
que_graph_free(graph); que_graph_free(graph);
trx->op_info = ""; trx->op_info = "";
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
trx_free_for_mysql(trx); trx_free_for_mysql(trx);
if (error == DB_SUCCESS) { if (error == DB_SUCCESS) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Foreign key constraint system tables created\n"); "InnoDB: Foreign key constraint system tables created\n");
} }
@ -1324,7 +1328,7 @@ dict_create_add_foreigns_to_dictionary(
if (NULL == dict_table_get_low("SYS_FOREIGN")) { if (NULL == dict_table_get_low("SYS_FOREIGN")) {
fprintf(stderr, fprintf(stderr,
"InnoDB: table SYS_FOREIGN not found from internal data dictionary\n"); "InnoDB: table SYS_FOREIGN not found from internal data dictionary\n");
return(DB_ERROR); return(DB_ERROR);
} }
@ -1432,12 +1436,12 @@ loop:
"in front of the user-defined constraint name).\n", "in front of the user-defined constraint name).\n",
ef); ef);
fputs("Note that InnoDB's FOREIGN KEY system tables store\n" fputs("Note that InnoDB's FOREIGN KEY system tables store\n"
"constraint names as case-insensitive, with the\n" "constraint names as case-insensitive, with the\n"
"MySQL standard latin1_swedish_ci collation. If you\n" "MySQL standard latin1_swedish_ci collation. If you\n"
"create tables or databases whose names differ only in\n" "create tables or databases whose names differ only in\n"
"the character case, then collisions in constraint\n" "the character case, then collisions in constraint\n"
"names can occur. Workaround: name your constraints\n" "names can occur. Workaround: name your constraints\n"
"explicitly with unique names.\n", "explicitly with unique names.\n",
ef); ef);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
@ -1446,7 +1450,7 @@ loop:
} }
if (error != DB_SUCCESS) { if (error != DB_SUCCESS) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Foreign key constraint creation failed:\n" "InnoDB: Foreign key constraint creation failed:\n"
"InnoDB: internal error number %lu\n", (ulong) error); "InnoDB: internal error number %lu\n", (ulong) error);
@ -1461,7 +1465,7 @@ loop:
return(error); return(error);
} }
foreign = UT_LIST_GET_NEXT(foreign_list, foreign); foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
goto loop; goto loop;

File diff suppressed because it is too large Load Diff

View File

@ -47,18 +47,18 @@ dict_get_first_table_name_in_db(
byte* field; byte* field;
ulint len; ulint len;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
heap = mem_heap_create(1000); heap = mem_heap_create(1000);
mtr_start(&mtr); mtr_start(&mtr);
sys_tables = dict_table_get_low("SYS_TABLES"); sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
ut_a(!sys_tables->comp); ut_a(!dict_table_is_comp(sys_tables));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
@ -77,36 +77,36 @@ loop:
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
return(NULL); return(NULL);
} }
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
if (len < strlen(name) if (len < strlen(name)
|| ut_memcmp(name, field, strlen(name)) != 0) { || ut_memcmp(name, field, strlen(name)) != 0) {
/* Not found */ /* Not found */
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
return(NULL); return(NULL);
} }
if (!rec_get_deleted_flag(rec, sys_tables->comp)) { if (!rec_get_deleted_flag(rec, 0)) {
/* We found one */ /* We found one */
char* table_name = mem_strdupl((char*) field, len); char* table_name = mem_strdupl((char*) field, len);
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
return(table_name); return(table_name);
} }
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
goto loop; goto loop;
@ -128,7 +128,7 @@ dict_print(void)
byte* field; byte* field;
ulint len; ulint len;
mtr_t mtr; mtr_t mtr;
/* Enlarge the fatal semaphore wait timeout during the InnoDB table /* Enlarge the fatal semaphore wait timeout during the InnoDB table
monitor printout */ monitor printout */
@ -155,7 +155,7 @@ loop:
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
/* Restore the fatal semaphore wait timeout */ /* Restore the fatal semaphore wait timeout */
@ -165,15 +165,15 @@ loop:
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
return; return;
} }
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
if (!rec_get_deleted_flag(rec, sys_tables->comp)) { if (!rec_get_deleted_flag(rec, 0)) {
/* We found one */ /* We found one */
char* table_name = mem_strdupl((char*) field, len); char* table_name = mem_strdupl((char*) field, len);
btr_pcur_store_position(&pcur, &mtr); btr_pcur_store_position(&pcur, &mtr);
@ -228,14 +228,14 @@ dict_check_tablespaces_and_store_max_id(
ulint space_id; ulint space_id;
ulint max_space_id = 0; ulint max_space_id = 0;
mtr_t mtr; mtr_t mtr;
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
mtr_start(&mtr); mtr_start(&mtr);
sys_tables = dict_table_get_low("SYS_TABLES"); sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
ut_a(!sys_tables->comp); ut_a(!dict_table_is_comp(sys_tables));
btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur, btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
TRUE, &mtr); TRUE, &mtr);
@ -249,40 +249,40 @@ loop:
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
/* We must make the tablespace cache aware of the biggest /* We must make the tablespace cache aware of the biggest
known space id */ known space id */
/* printf("Biggest space id in data dictionary %lu\n", /* printf("Biggest space id in data dictionary %lu\n",
max_space_id); */ max_space_id); */
fil_set_max_space_id_if_bigger(max_space_id); fil_set_max_space_id_if_bigger(max_space_id);
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
return; return;
} }
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
if (!rec_get_deleted_flag(rec, sys_tables->comp)) { if (!rec_get_deleted_flag(rec, 0)) {
/* We found one */ /* We found one */
char* name = mem_strdupl((char*) field, len); char* name = mem_strdupl((char*) field, len);
field = rec_get_nth_field_old(rec, 9, &len); field = rec_get_nth_field_old(rec, 9, &len);
ut_a(len == 4); ut_a(len == 4);
space_id = mach_read_from_4(field); space_id = mach_read_from_4(field);
btr_pcur_store_position(&pcur, &mtr); btr_pcur_store_position(&pcur, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
if (space_id != 0 && in_crash_recovery) { if (space_id != 0 && in_crash_recovery) {
/* Check that the tablespace (the .ibd file) really /* Check that the tablespace (the .ibd file) really
exists; print a warning to the .err log if not */ exists; print a warning to the .err log if not */
fil_space_for_table_exists_in_mem(space_id, name, fil_space_for_table_exists_in_mem(space_id, name,
FALSE, TRUE, TRUE); FALSE, TRUE, TRUE);
} }
@ -334,7 +334,7 @@ dict_load_columns(
ulint prec; ulint prec;
ulint i; ulint i;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
@ -343,7 +343,7 @@ dict_load_columns(
sys_columns = dict_table_get_low("SYS_COLUMNS"); sys_columns = dict_table_get_low("SYS_COLUMNS");
sys_index = UT_LIST_GET_FIRST(sys_columns->indexes); sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
ut_a(!sys_columns->comp); ut_a(!dict_table_is_comp(sys_columns));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
@ -356,13 +356,13 @@ dict_load_columns(
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr); BTR_SEARCH_LEAF, &pcur, &mtr);
for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) { for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) {
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
ut_a(!rec_get_deleted_flag(rec, sys_columns->comp)); ut_a(!rec_get_deleted_flag(rec, 0));
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
ut_ad(len == 8); ut_ad(len == 8);
@ -385,13 +385,23 @@ dict_load_columns(
field = rec_get_nth_field_old(rec, 6, &len); field = rec_get_nth_field_old(rec, 6, &len);
prtype = mach_read_from_4(field); prtype = mach_read_from_4(field);
if (dtype_is_non_binary_string_type(mtype, prtype) if (dtype_get_charset_coll(prtype) == 0
&& dtype_get_charset_coll(prtype) == 0) { && dtype_is_string_type(mtype)) {
/* This is a non-binary string type, and the table /* The table was created with < 4.1.2. */
was created with < 4.1.2. Use the default charset. */
prtype = dtype_form_prtype(prtype, if (dtype_is_binary_string_type(mtype, prtype)) {
/* Use the binary collation for
string columns of binary type. */
prtype = dtype_form_prtype(prtype,
DATA_MYSQL_BINARY_CHARSET_COLL);
} else {
/* Use the default charset for
other than binary columns. */
prtype = dtype_form_prtype(prtype,
data_mysql_default_charset_coll); data_mysql_default_charset_coll);
}
} }
field = rec_get_nth_field_old(rec, 7, &len); field = rec_get_nth_field_old(rec, 7, &len);
@ -407,7 +417,7 @@ dict_load_columns(
dict_mem_table_add_col(table, name, mtype, prtype, col_len, dict_mem_table_add_col(table, name, mtype, prtype, col_len,
prec); prec);
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
} }
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
@ -455,7 +465,7 @@ dict_load_fields(
byte* buf; byte* buf;
ulint i; ulint i;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
@ -466,7 +476,7 @@ dict_load_fields(
sys_fields = dict_table_get_low("SYS_FIELDS"); sys_fields = dict_table_get_low("SYS_FIELDS");
sys_index = UT_LIST_GET_FIRST(sys_fields->indexes); sys_index = UT_LIST_GET_FIRST(sys_fields->indexes);
ut_a(!sys_fields->comp); ut_a(!dict_table_is_comp(sys_fields));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
@ -479,15 +489,15 @@ dict_load_fields(
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr); BTR_SEARCH_LEAF, &pcur, &mtr);
for (i = 0; i < index->n_fields; i++) { for (i = 0; i < index->n_fields; i++) {
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
if (rec_get_deleted_flag(rec, sys_fields->comp)) { if (rec_get_deleted_flag(rec, 0)) {
dict_load_report_deleted_index(table->name, i); dict_load_report_deleted_index(table->name, i);
} }
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
ut_ad(len == 8); ut_ad(len == 8);
ut_a(ut_memcmp(buf, field, len) == 0); ut_a(ut_memcmp(buf, field, len) == 0);
@ -506,14 +516,14 @@ dict_load_fields(
pos_and_prefix_len = mach_read_from_4(field); pos_and_prefix_len = mach_read_from_4(field);
ut_a((pos_and_prefix_len & 0xFFFFUL) == i ut_a((pos_and_prefix_len & 0xFFFFUL) == i
|| (pos_and_prefix_len & 0xFFFF0000UL) == (i << 16)); || (pos_and_prefix_len & 0xFFFF0000UL) == (i << 16));
if ((i == 0 && pos_and_prefix_len > 0) if ((i == 0 && pos_and_prefix_len > 0)
|| (pos_and_prefix_len & 0xFFFF0000UL) > 0) { || (pos_and_prefix_len & 0xFFFF0000UL) > 0) {
prefix_len = pos_and_prefix_len & 0xFFFFUL; prefix_len = pos_and_prefix_len & 0xFFFFUL;
} else { } else {
prefix_len = 0; prefix_len = 0;
} }
ut_a(0 == ut_strcmp("COL_NAME", ut_a(0 == ut_strcmp("COL_NAME",
@ -523,10 +533,10 @@ dict_load_fields(
field = rec_get_nth_field_old(rec, 4, &len); field = rec_get_nth_field_old(rec, 4, &len);
dict_mem_index_add_field(index, dict_mem_index_add_field(index,
mem_heap_strdupl(heap, (char*) field, len), 0, prefix_len); mem_heap_strdupl(heap, (char*) field, len), prefix_len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
} }
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
@ -563,23 +573,23 @@ dict_load_indexes(
ibool is_sys_table; ibool is_sys_table;
dulint id; dulint id;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
if ((ut_dulint_get_high(table->id) == 0) if ((ut_dulint_get_high(table->id) == 0)
&& (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) { && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) {
is_sys_table = TRUE; is_sys_table = TRUE;
} else { } else {
is_sys_table = FALSE; is_sys_table = FALSE;
} }
mtr_start(&mtr); mtr_start(&mtr);
sys_indexes = dict_table_get_low("SYS_INDEXES"); sys_indexes = dict_table_get_low("SYS_INDEXES");
sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes); sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes);
ut_a(!sys_indexes->comp); ut_a(!dict_table_is_comp(sys_indexes));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
@ -592,14 +602,14 @@ dict_load_indexes(
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr); BTR_SEARCH_LEAF, &pcur, &mtr);
for (;;) { for (;;) {
if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
break; break;
} }
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
ut_ad(len == 8); ut_ad(len == 8);
@ -607,7 +617,7 @@ dict_load_indexes(
break; break;
} }
if (rec_get_deleted_flag(rec, table->comp)) { if (rec_get_deleted_flag(rec, dict_table_is_comp(table))) {
dict_load_report_deleted_index(table->name, dict_load_report_deleted_index(table->name,
ULINT_UNDEFINED); ULINT_UNDEFINED);
@ -658,7 +668,7 @@ dict_load_indexes(
} }
if ((type & DICT_CLUSTERED) == 0 if ((type & DICT_CLUSTERED) == 0
&& NULL == dict_table_get_first_index(table)) { && NULL == dict_table_get_first_index(table)) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: trying to load index %s for table %s\n" "InnoDB: Error: trying to load index %s for table %s\n"
@ -670,27 +680,27 @@ dict_load_indexes(
return(FALSE); return(FALSE);
} }
if (is_sys_table if (is_sys_table
&& ((type & DICT_CLUSTERED) && ((type & DICT_CLUSTERED)
|| ((table == dict_sys->sys_tables) || ((table == dict_sys->sys_tables)
&& (name_len == (sizeof "ID_IND") - 1) && (name_len == (sizeof "ID_IND") - 1)
&& (0 == ut_memcmp(name_buf, "ID_IND", && (0 == ut_memcmp(name_buf, "ID_IND",
name_len))))) { name_len))))) {
/* The index was created in memory already at booting /* The index was created in memory already at booting
of the database server */ of the database server */
} else { } else {
index = dict_mem_index_create(table->name, name_buf, index = dict_mem_index_create(table->name, name_buf,
space, type, n_fields); space, type, n_fields);
index->id = id; index->id = id;
dict_load_fields(table, index, heap); dict_load_fields(table, index, heap);
dict_index_add_to_cache(table, index, page_no); dict_index_add_to_cache(table, index, page_no);
} }
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
} }
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
@ -729,20 +739,21 @@ dict_load_table(
ulint len; ulint len;
ulint space; ulint space;
ulint n_cols; ulint n_cols;
ulint flags;
ulint err; ulint err;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
heap = mem_heap_create(1000); heap = mem_heap_create(1000);
mtr_start(&mtr); mtr_start(&mtr);
sys_tables = dict_table_get_low("SYS_TABLES"); sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
ut_a(!sys_tables->comp); ut_a(!dict_table_is_comp(sys_tables));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
@ -755,15 +766,15 @@ dict_load_table(
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr) if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
|| rec_get_deleted_flag(rec, sys_tables->comp)) { || rec_get_deleted_flag(rec, 0)) {
/* Not found */ /* Not found */
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
return(NULL); return(NULL);
} }
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
@ -772,14 +783,14 @@ dict_load_table(
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
return(NULL); return(NULL);
} }
ut_a(0 == ut_strcmp("SPACE", ut_a(0 == ut_strcmp("SPACE",
dict_field_get_col( dict_field_get_col(
dict_index_get_nth_field(sys_index, 9))->name)); dict_index_get_nth_field(sys_index, 9))->name));
field = rec_get_nth_field_old(rec, 9, &len); field = rec_get_nth_field_old(rec, 9, &len);
space = mach_read_from_4(field); space = mach_read_from_4(field);
@ -817,10 +828,15 @@ dict_load_table(
field = rec_get_nth_field_old(rec, 4, &len); field = rec_get_nth_field_old(rec, 4, &len);
n_cols = mach_read_from_4(field); n_cols = mach_read_from_4(field);
flags = 0;
/* The high-order bit of N_COLS is the "compact format" flag. */ /* The high-order bit of N_COLS is the "compact format" flag. */
table = dict_mem_table_create(name, space, if (n_cols & 0x80000000UL) {
n_cols & ~0x80000000UL, flags |= DICT_TF_COMPACT;
!!(n_cols & 0x80000000UL)); }
table = dict_mem_table_create(name, space, n_cols & ~0x80000000UL,
flags);
table->ibd_file_missing = ibd_file_missing; table->ibd_file_missing = ibd_file_missing;
@ -846,7 +862,7 @@ dict_load_table(
} }
if ((table->type == DICT_TABLE_CLUSTER) if ((table->type == DICT_TABLE_CLUSTER)
|| (table->type == DICT_TABLE_CLUSTER_MEMBER)) { || (table->type == DICT_TABLE_CLUSTER_MEMBER)) {
field = rec_get_nth_field_old(rec, 7, &len); field = rec_get_nth_field_old(rec, 7, &len);
ut_a(len == 4); ut_a(len == 4);
@ -865,17 +881,17 @@ dict_load_table(
dict_load_columns(table, heap); dict_load_columns(table, heap);
dict_table_add_to_cache(table); dict_table_add_to_cache(table);
dict_load_indexes(table, heap); dict_load_indexes(table, heap);
err = dict_load_foreigns(table->name, TRUE); err = dict_load_foreigns(table->name, TRUE);
/* /*
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mutex_enter(&dict_foreign_err_mutex);
ut_print_timestamp(stderr); mutex_enter(&dict_foreign_err_mutex);
ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: Error: could not make a foreign key definition to match\n" " InnoDB: Error: could not make a foreign key definition to match\n"
"InnoDB: the foreign key table or the referenced table!\n" "InnoDB: the foreign key table or the referenced table!\n"
@ -883,7 +899,7 @@ dict_load_table(
"InnoDB: and recreate the foreign key table or the referenced table.\n" "InnoDB: and recreate the foreign key table or the referenced table.\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n"
"InnoDB: Latest foreign key error printout:\n%s\n", dict_foreign_err_buf); "InnoDB: Latest foreign key error printout:\n%s\n", dict_foreign_err_buf);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
} }
*/ */
@ -899,21 +915,21 @@ dict_table_t*
dict_load_table_on_id( dict_load_table_on_id(
/*==================*/ /*==================*/
/* out: table; NULL if table does not exist */ /* out: table; NULL if table does not exist */
dulint table_id) /* in: table id */ dulint table_id) /* in: table id */
{ {
byte id_buf[8]; byte id_buf[8];
btr_pcur_t pcur; btr_pcur_t pcur;
mem_heap_t* heap; mem_heap_t* heap;
dtuple_t* tuple; dtuple_t* tuple;
dfield_t* dfield; dfield_t* dfield;
dict_index_t* sys_table_ids; dict_index_t* sys_table_ids;
dict_table_t* sys_tables; dict_table_t* sys_tables;
rec_t* rec; rec_t* rec;
byte* field; byte* field;
ulint len; ulint len;
dict_table_t* table; dict_table_t* table;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
@ -922,13 +938,13 @@ dict_load_table_on_id(
the dictionary mutex, and therefore no deadlocks can occur the dictionary mutex, and therefore no deadlocks can occur
with other dictionary operations. */ with other dictionary operations. */
mtr_start(&mtr); mtr_start(&mtr);
/*---------------------------------------------------*/ /*---------------------------------------------------*/
/* Get the secondary index based on ID for table SYS_TABLES */ /* Get the secondary index based on ID for table SYS_TABLES */
sys_tables = dict_sys->sys_tables; sys_tables = dict_sys->sys_tables;
sys_table_ids = dict_table_get_next_index( sys_table_ids = dict_table_get_next_index(
dict_table_get_first_index(sys_tables)); dict_table_get_first_index(sys_tables));
ut_a(!sys_tables->comp); ut_a(!dict_table_is_comp(sys_tables));
heap = mem_heap_create(256); heap = mem_heap_create(256);
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
@ -936,22 +952,22 @@ dict_load_table_on_id(
/* Write the table id in byte format to id_buf */ /* Write the table id in byte format to id_buf */
mach_write_to_8(id_buf, table_id); mach_write_to_8(id_buf, table_id);
dfield_set_data(dfield, id_buf, 8); dfield_set_data(dfield, id_buf, 8);
dict_index_copy_types(tuple, sys_table_ids, 1); dict_index_copy_types(tuple, sys_table_ids, 1);
btr_pcur_open_on_user_rec(sys_table_ids, tuple, PAGE_CUR_GE, btr_pcur_open_on_user_rec(sys_table_ids, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr); BTR_SEARCH_LEAF, &pcur, &mtr);
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr) if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
|| rec_get_deleted_flag(rec, sys_tables->comp)) { || rec_get_deleted_flag(rec, 0)) {
/* Not found */ /* Not found */
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
return(NULL); return(NULL);
} }
@ -969,15 +985,15 @@ dict_load_table_on_id(
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
return(NULL); return(NULL);
} }
/* Now we get the table name from the record */ /* Now we get the table name from the record */
field = rec_get_nth_field_old(rec, 1, &len); field = rec_get_nth_field_old(rec, 1, &len);
/* Load the table definition to memory */ /* Load the table definition to memory */
table = dict_load_table(mem_heap_strdupl(heap, (char*) field, len)); table = dict_load_table(mem_heap_strdupl(heap, (char*) field, len));
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
@ -1004,7 +1020,7 @@ dict_load_sys_table(
heap = mem_heap_create(1000); heap = mem_heap_create(1000);
dict_load_indexes(table, heap); dict_load_indexes(table, heap);
mem_heap_free(heap); mem_heap_free(heap);
} }
@ -1028,7 +1044,7 @@ dict_load_foreign_cols(
ulint len; ulint len;
ulint i; ulint i;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
@ -1042,7 +1058,7 @@ dict_load_foreign_cols(
sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS"); sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS");
sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes); sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes);
ut_a(!sys_foreign_cols->comp); ut_a(!dict_table_is_comp(sys_foreign_cols));
tuple = dtuple_create(foreign->heap, 1); tuple = dtuple_create(foreign->heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
@ -1052,12 +1068,12 @@ dict_load_foreign_cols(
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr); BTR_SEARCH_LEAF, &pcur, &mtr);
for (i = 0; i < foreign->n_fields; i++) { for (i = 0; i < foreign->n_fields; i++) {
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
ut_a(!rec_get_deleted_flag(rec, sys_foreign_cols->comp)); ut_a(!rec_get_deleted_flag(rec, 0));
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
ut_a(len == ut_strlen(id)); ut_a(len == ut_strlen(id));
@ -1069,14 +1085,14 @@ dict_load_foreign_cols(
field = rec_get_nth_field_old(rec, 4, &len); field = rec_get_nth_field_old(rec, 4, &len);
foreign->foreign_col_names[i] = foreign->foreign_col_names[i] =
mem_heap_strdupl(foreign->heap, (char*) field, len); mem_heap_strdupl(foreign->heap, (char*) field, len);
field = rec_get_nth_field_old(rec, 5, &len); field = rec_get_nth_field_old(rec, 5, &len);
foreign->referenced_col_names[i] = foreign->referenced_col_names[i] =
mem_heap_strdupl(foreign->heap, (char*) field, len); mem_heap_strdupl(foreign->heap, (char*) field, len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
} }
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
@ -1091,8 +1107,8 @@ dict_load_foreign(
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
const char* id, /* in: foreign constraint id as a const char* id, /* in: foreign constraint id as a
null-terminated string */ null-terminated string */
ibool check_types)/* in: TRUE=check type compatibility */ ibool check_charsets)/* in: TRUE=check charset compatibility */
{ {
dict_foreign_t* foreign; dict_foreign_t* foreign;
dict_table_t* sys_foreign; dict_table_t* sys_foreign;
btr_pcur_t pcur; btr_pcur_t pcur;
@ -1104,18 +1120,18 @@ dict_load_foreign(
byte* field; byte* field;
ulint len; ulint len;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
heap2 = mem_heap_create(1000); heap2 = mem_heap_create(1000);
mtr_start(&mtr); mtr_start(&mtr);
sys_foreign = dict_table_get_low("SYS_FOREIGN"); sys_foreign = dict_table_get_low("SYS_FOREIGN");
sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes); sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes);
ut_a(!sys_foreign->comp); ut_a(!dict_table_is_comp(sys_foreign));
tuple = dtuple_create(heap2, 1); tuple = dtuple_create(heap2, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
@ -1128,7 +1144,7 @@ dict_load_foreign(
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr) if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
|| rec_get_deleted_flag(rec, sys_foreign->comp)) { || rec_get_deleted_flag(rec, 0)) {
/* Not found */ /* Not found */
fprintf(stderr, fprintf(stderr,
@ -1138,9 +1154,9 @@ dict_load_foreign(
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap2); mem_heap_free(heap2);
return(DB_ERROR); return(DB_ERROR);
} }
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
@ -1154,7 +1170,7 @@ dict_load_foreign(
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap2); mem_heap_free(heap2);
return(DB_ERROR); return(DB_ERROR);
} }
@ -1162,7 +1178,7 @@ dict_load_foreign(
with the constraint */ with the constraint */
mem_heap_free(heap2); mem_heap_free(heap2);
foreign = dict_mem_foreign_create(); foreign = dict_mem_foreign_create();
foreign->n_fields = foreign->n_fields =
@ -1171,19 +1187,19 @@ dict_load_foreign(
ut_a(len == 4); ut_a(len == 4);
/* We store the type to the bits 24-31 of n_fields */ /* We store the type to the bits 24-31 of n_fields */
foreign->type = foreign->n_fields >> 24; foreign->type = foreign->n_fields >> 24;
foreign->n_fields = foreign->n_fields & 0xFFFFFFUL; foreign->n_fields = foreign->n_fields & 0xFFFFFFUL;
foreign->id = mem_heap_strdup(foreign->heap, id); foreign->id = mem_heap_strdup(foreign->heap, id);
field = rec_get_nth_field_old(rec, 3, &len); field = rec_get_nth_field_old(rec, 3, &len);
foreign->foreign_table_name = foreign->foreign_table_name =
mem_heap_strdupl(foreign->heap, (char*) field, len); mem_heap_strdupl(foreign->heap, (char*) field, len);
field = rec_get_nth_field_old(rec, 4, &len); field = rec_get_nth_field_old(rec, 4, &len);
foreign->referenced_table_name = foreign->referenced_table_name =
mem_heap_strdupl(foreign->heap, (char*) field, len); mem_heap_strdupl(foreign->heap, (char*) field, len);
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
@ -1204,7 +1220,7 @@ dict_load_foreign(
a new foreign key constraint but loading one from the data a new foreign key constraint but loading one from the data
dictionary. */ dictionary. */
return(dict_foreign_add_to_cache(foreign, check_types)); return(dict_foreign_add_to_cache(foreign, check_charsets));
} }
/*************************************************************************** /***************************************************************************
@ -1219,21 +1235,22 @@ dict_load_foreigns(
/*===============*/ /*===============*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
const char* table_name, /* in: table name */ const char* table_name, /* in: table name */
ibool check_types) /* in: TRUE=check type compatibility */ ibool check_charsets) /* in: TRUE=check charset
compatibility */
{ {
btr_pcur_t pcur; btr_pcur_t pcur;
mem_heap_t* heap; mem_heap_t* heap;
dtuple_t* tuple; dtuple_t* tuple;
dfield_t* dfield; dfield_t* dfield;
dict_index_t* sec_index; dict_index_t* sec_index;
dict_table_t* sys_foreign; dict_table_t* sys_foreign;
rec_t* rec; rec_t* rec;
byte* field; byte* field;
ulint len; ulint len;
char* id ; char* id ;
ulint err; ulint err;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
@ -1245,15 +1262,15 @@ dict_load_foreigns(
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: no foreign key system tables in the database\n"); "InnoDB: Error: no foreign key system tables in the database\n");
return(DB_ERROR); return(DB_ERROR);
} }
ut_a(!sys_foreign->comp); ut_a(!dict_table_is_comp(sys_foreign));
mtr_start(&mtr); mtr_start(&mtr);
/* Get the secondary index based on FOR_NAME from table /* Get the secondary index based on FOR_NAME from table
SYS_FOREIGN */ SYS_FOREIGN */
sec_index = dict_table_get_next_index( sec_index = dict_table_get_next_index(
dict_table_get_first_index(sys_foreign)); dict_table_get_first_index(sys_foreign));
@ -1270,7 +1287,7 @@ start_load:
BTR_SEARCH_LEAF, &pcur, &mtr); BTR_SEARCH_LEAF, &pcur, &mtr);
loop: loop:
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
/* End of index */ /* End of index */
@ -1290,7 +1307,7 @@ loop:
if (0 != cmp_data_data(dfield_get_type(dfield), if (0 != cmp_data_data(dfield_get_type(dfield),
dfield_get_data(dfield), dfield_get_len(dfield), dfield_get_data(dfield), dfield_get_len(dfield),
field, len)) { field, len)) {
goto load_next_index; goto load_next_index;
} }
@ -1303,8 +1320,8 @@ loop:
goto next_rec; goto next_rec;
} }
if (rec_get_deleted_flag(rec, sys_foreign->comp)) { if (rec_get_deleted_flag(rec, 0)) {
goto next_rec; goto next_rec;
} }
@ -1312,14 +1329,14 @@ loop:
/* Now we get a foreign key constraint id */ /* Now we get a foreign key constraint id */
field = rec_get_nth_field_old(rec, 1, &len); field = rec_get_nth_field_old(rec, 1, &len);
id = mem_heap_strdupl(heap, (char*) field, len); id = mem_heap_strdupl(heap, (char*) field, len);
btr_pcur_store_position(&pcur, &mtr); btr_pcur_store_position(&pcur, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
/* Load the foreign constraint definition to the dictionary cache */ /* Load the foreign constraint definition to the dictionary cache */
err = dict_load_foreign(id, check_types); err = dict_load_foreign(id, check_charsets);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
@ -1340,12 +1357,12 @@ load_next_index:
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
sec_index = dict_table_get_next_index(sec_index); sec_index = dict_table_get_next_index(sec_index);
if (sec_index != NULL) { if (sec_index != NULL) {
mtr_start(&mtr); mtr_start(&mtr);
goto start_load; goto start_load;
} }

View File

@ -36,13 +36,13 @@ dict_mem_table_create(
ignored if the table is made a member of ignored if the table is made a member of
a cluster */ a cluster */
ulint n_cols, /* in: number of columns */ ulint n_cols, /* in: number of columns */
ibool comp) /* in: TRUE=compact page format */ ulint flags) /* in: table flags */
{ {
dict_table_t* table; dict_table_t* table;
mem_heap_t* heap; mem_heap_t* heap;
ut_ad(name); ut_ad(name);
ut_ad(comp == FALSE || comp == TRUE); ut_ad(!(flags & ~DICT_TF_COMPACT));
heap = mem_heap_create(DICT_HEAP_SIZE); heap = mem_heap_create(DICT_HEAP_SIZE);
@ -51,24 +51,24 @@ dict_mem_table_create(
table->heap = heap; table->heap = heap;
table->type = DICT_TABLE_ORDINARY; table->type = DICT_TABLE_ORDINARY;
table->flags = flags;
table->name = mem_heap_strdup(heap, name); table->name = mem_heap_strdup(heap, name);
table->dir_path_of_temp_table = NULL; table->dir_path_of_temp_table = NULL;
table->space = space; table->space = space;
table->ibd_file_missing = FALSE; table->ibd_file_missing = FALSE;
table->tablespace_discarded = FALSE; table->tablespace_discarded = FALSE;
table->comp = comp;
table->n_def = 0; table->n_def = 0;
table->n_cols = n_cols + DATA_N_SYS_COLS; table->n_cols = n_cols + DATA_N_SYS_COLS;
table->mem_fix = 0; table->mem_fix = 0;
table->n_mysql_handles_opened = 0; table->n_mysql_handles_opened = 0;
table->n_foreign_key_checks_running = 0; table->n_foreign_key_checks_running = 0;
table->cached = FALSE; table->cached = FALSE;
table->mix_id = ut_dulint_zero; table->mix_id = ut_dulint_zero;
table->mix_len = 0; table->mix_len = 0;
table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS) table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
* sizeof(dict_col_t)); * sizeof(dict_col_t));
UT_LIST_INIT(table->indexes); UT_LIST_INIT(table->indexes);
@ -86,14 +86,14 @@ dict_mem_table_create(
table->stat_initialized = FALSE; table->stat_initialized = FALSE;
table->stat_modified_counter = 0; table->stat_modified_counter = 0;
mutex_create(&(table->autoinc_mutex)); mutex_create(&(table->autoinc_mutex));
mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX); mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX);
table->autoinc_inited = FALSE; table->autoinc_inited = FALSE;
table->magic_n = DICT_TABLE_MAGIC_N; table->magic_n = DICT_TABLE_MAGIC_N;
return(table); return(table);
} }
@ -114,7 +114,7 @@ dict_mem_cluster_create(
dict_table_t* cluster; dict_table_t* cluster;
/* Clustered tables cannot work with the compact record format. */ /* Clustered tables cannot work with the compact record format. */
cluster = dict_mem_table_create(name, space, n_cols, FALSE); cluster = dict_mem_table_create(name, space, n_cols, 0);
cluster->type = DICT_TABLE_CLUSTER; cluster->type = DICT_TABLE_CLUSTER;
cluster->mix_len = mix_len; cluster->mix_len = mix_len;
@ -150,13 +150,13 @@ dict_mem_table_add_col(
{ {
dict_col_t* col; dict_col_t* col;
dtype_t* type; dtype_t* type;
ut_ad(table && name); ut_ad(table && name);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
table->n_def++; table->n_def++;
col = dict_table_get_nth_col(table, table->n_def - 1); col = dict_table_get_nth_col(table, table->n_def - 1);
col->ind = table->n_def - 1; col->ind = table->n_def - 1;
col->name = mem_heap_strdup(table->heap, name); col->name = mem_heap_strdup(table->heap, name);
@ -164,7 +164,7 @@ dict_mem_table_add_col(
col->ord_part = 0; col->ord_part = 0;
col->clust_pos = ULINT_UNDEFINED; col->clust_pos = ULINT_UNDEFINED;
type = dict_col_get_type(col); type = dict_col_get_type(col);
dtype_set(type, mtype, prtype, len, prec); dtype_set(type, mtype, prtype, len, prec);
@ -188,14 +188,14 @@ dict_mem_index_create(
{ {
dict_index_t* index; dict_index_t* index;
mem_heap_t* heap; mem_heap_t* heap;
ut_ad(table_name && index_name); ut_ad(table_name && index_name);
heap = mem_heap_create(DICT_HEAP_SIZE); heap = mem_heap_create(DICT_HEAP_SIZE);
index = mem_heap_alloc(heap, sizeof(dict_index_t)); index = mem_heap_alloc(heap, sizeof(dict_index_t));
index->heap = heap; index->heap = heap;
index->type = type; index->type = type;
index->space = space; index->space = space;
index->name = mem_heap_strdup(heap, index_name); index->name = mem_heap_strdup(heap, index_name);
@ -261,24 +261,20 @@ dict_mem_index_add_field(
/*=====================*/ /*=====================*/
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
const char* name, /* in: column name */ const char* name, /* in: column name */
ulint order, /* in: order criterion; 0 means an
ascending order */
ulint prefix_len) /* in: 0 or the column prefix length ulint prefix_len) /* in: 0 or the column prefix length
in a MySQL index like in a MySQL index like
INDEX (textcol(25)) */ INDEX (textcol(25)) */
{ {
dict_field_t* field; dict_field_t* field;
ut_ad(index && name); ut_ad(index && name);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
index->n_def++; index->n_def++;
field = dict_index_get_nth_field(index, index->n_def - 1); field = dict_index_get_nth_field(index, index->n_def - 1);
field->name = name; field->name = name;
field->order = order;
field->prefix_len = prefix_len; field->prefix_len = prefix_len;
} }

View File

@ -31,7 +31,7 @@ dyn_array_add_block(
UT_LIST_ADD_FIRST(list, arr->base, arr); UT_LIST_ADD_FIRST(list, arr->base, arr);
arr->heap = mem_heap_create(sizeof(dyn_block_t)); arr->heap = mem_heap_create(sizeof(dyn_block_t));
} }
block = dyn_array_get_last_block(arr); block = dyn_array_get_last_block(arr);
block->used = block->used | DYN_BLOCK_FULL_FLAG; block->used = block->used | DYN_BLOCK_FULL_FLAG;

View File

@ -17,7 +17,7 @@ Created 12/29/1997 Heikki Tuuri
#include "row0sel.h" #include "row0sel.h"
/* The RND function seed */ /* The RND function seed */
ulint eval_rnd = 128367121; ulint eval_rnd = 128367121;
/* Dummy adress used when we should allocate a buffer of size 0 in /* Dummy adress used when we should allocate a buffer of size 0 in
the function below */ the function below */
@ -44,12 +44,12 @@ eval_node_alloc_val_buf(
byte* data; byte* data;
ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
|| que_node_get_type(node) == QUE_NODE_FUNC); || que_node_get_type(node) == QUE_NODE_FUNC);
dfield = que_node_get_val(node); dfield = que_node_get_val(node);
data = dfield_get_data(dfield); data = dfield_get_data(dfield);
if (data && data != &eval_dummy) { if (data && data != &eval_dummy) {
mem_free(data); mem_free(data);
} }
@ -81,15 +81,15 @@ eval_node_free_val_buf(
byte* data; byte* data;
ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL ut_ad(que_node_get_type(node) == QUE_NODE_SYMBOL
|| que_node_get_type(node) == QUE_NODE_FUNC); || que_node_get_type(node) == QUE_NODE_FUNC);
dfield = que_node_get_val(node); dfield = que_node_get_val(node);
data = dfield_get_data(dfield); data = dfield_get_data(dfield);
if (que_node_get_val_buf_size(node) > 0) { if (que_node_get_val_buf_size(node) > 0) {
ut_a(data); ut_a(data);
mem_free(data); mem_free(data);
} }
} }
@ -108,7 +108,7 @@ eval_cmp(
int res; int res;
ibool val; ibool val;
int func; int func;
ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC); ut_ad(que_node_get_type(cmp_node) == QUE_NODE_FUNC);
arg1 = cmp_node->args; arg1 = cmp_node->args;
@ -119,7 +119,7 @@ eval_cmp(
val = TRUE; val = TRUE;
func = cmp_node->func; func = cmp_node->func;
if (func == '=') { if (func == '=') {
if (res != 0) { if (res != 0) {
val = FALSE; val = FALSE;
@ -142,7 +142,7 @@ eval_cmp(
} }
} else { } else {
ut_ad(func == '>'); ut_ad(func == '>');
if (res != 1) { if (res != 1) {
val = FALSE; val = FALSE;
} }
@ -268,7 +268,7 @@ eval_aggregate(
val = val + arg_val; val = val + arg_val;
} }
eval_node_set_int_val(node, val); eval_node_set_int_val(node, val);
} }
@ -304,7 +304,7 @@ eval_predefined_2(
if (func == PARS_PRINTF_TOKEN) { if (func == PARS_PRINTF_TOKEN) {
arg = arg1; arg = arg1;
while (arg) { while (arg) {
dfield_print(que_node_get_val(arg)); dfield_print(que_node_get_val(arg));
@ -312,16 +312,16 @@ eval_predefined_2(
} }
putc('\n', stderr); putc('\n', stderr);
} else if (func == PARS_ASSERT_TOKEN) { } else if (func == PARS_ASSERT_TOKEN) {
if (!eval_node_get_ibool_val(arg1)) { if (!eval_node_get_ibool_val(arg1)) {
fputs("SQL assertion fails in a stored procedure!\n", fputs("SQL assertion fails in a stored procedure!\n",
stderr); stderr);
} }
ut_a(eval_node_get_ibool_val(arg1)); ut_a(eval_node_get_ibool_val(arg1));
/* This function, or more precisely, a debug procedure, /* This function, or more precisely, a debug procedure,
returns no value */ returns no value */
@ -332,7 +332,7 @@ eval_predefined_2(
ut_ad(len2 >= len1); ut_ad(len2 >= len1);
if (len2 > len1) { if (len2 > len1) {
int_val = (lint)(len1 + int_val = (lint)(len1 +
(eval_rnd % (len2 - len1 + 1))); (eval_rnd % (len2 - len1 + 1)));
} else { } else {
@ -383,7 +383,7 @@ eval_notfound(
ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL); ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL);
if (cursor->token_type == SYM_LIT) { if (cursor->token_type == SYM_LIT) {
ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)), ut_ad(ut_memcmp(dfield_get_data(que_node_get_val(cursor)),
"SQL", 3) == 0); "SQL", 3) == 0);
@ -425,7 +425,7 @@ eval_substr(
arg3 = que_node_get_next(arg2); arg3 = que_node_get_next(arg2);
str1 = dfield_get_data(que_node_get_val(arg1)); str1 = dfield_get_data(que_node_get_val(arg1));
len1 = (ulint)eval_node_get_int_val(arg2); len1 = (ulint)eval_node_get_int_val(arg2);
len2 = (ulint)eval_node_get_int_val(arg3); len2 = (ulint)eval_node_get_int_val(arg3);
@ -473,7 +473,7 @@ eval_replstr(
ut_memcpy(str1 + len1, str2, len2); ut_memcpy(str1 + len1, str2, len2);
} }
/********************************************************************* /*********************************************************************
Evaluates an instr-function node. */ Evaluates an instr-function node. */
static static
@ -500,7 +500,7 @@ eval_instr(
dfield1 = que_node_get_val(arg1); dfield1 = que_node_get_val(arg1);
dfield2 = que_node_get_val(arg2); dfield2 = que_node_get_val(arg2);
str1 = dfield_get_data(dfield1); str1 = dfield_get_data(dfield1);
str2 = dfield_get_data(dfield2); str2 = dfield_get_data(dfield2);
@ -539,7 +539,7 @@ eval_instr(
} }
} }
} }
int_val = 0; int_val = 0;
match_found: match_found:
@ -568,7 +568,7 @@ eval_binary_to_number(
str1 = dfield_get_data(dfield); str1 = dfield_get_data(dfield);
len1 = dfield_get_len(dfield); len1 = dfield_get_len(dfield);
if (len1 > 4) { if (len1 > 4) {
ut_error; ut_error;
} }
@ -577,13 +577,13 @@ eval_binary_to_number(
} else { } else {
int_val = 0; int_val = 0;
str2 = (byte*)&int_val; str2 = (byte*)&int_val;
ut_memcpy(str2 + (4 - len1), str1, len1); ut_memcpy(str2 + (4 - len1), str1, len1);
} }
eval_node_copy_and_alloc_val(func_node, str2, 4); eval_node_copy_and_alloc_val(func_node, str2, 4);
} }
/********************************************************************* /*********************************************************************
Evaluates a predefined function node. */ Evaluates a predefined function node. */
static static
@ -661,14 +661,14 @@ eval_to_binary(
} }
arg2 = que_node_get_next(arg1); arg2 = que_node_get_next(arg1);
len1 = (ulint)eval_node_get_int_val(arg2); len1 = (ulint)eval_node_get_int_val(arg2);
if (len1 > 4) { if (len1 > 4) {
ut_error; ut_error;
} }
dfield = que_node_get_val(func_node); dfield = que_node_get_val(func_node);
dfield_set_data(dfield, str1 + (4 - len1), len1); dfield_set_data(dfield, str1 + (4 - len1), len1);
@ -688,7 +688,7 @@ eval_predefined(
int func; int func;
func = func_node->func; func = func_node->func;
arg1 = func_node->args; arg1 = func_node->args;
if (func == PARS_LENGTH_TOKEN) { if (func == PARS_LENGTH_TOKEN) {
@ -763,7 +763,7 @@ eval_predefined(
return; return;
} }
eval_node_set_int_val(func_node, int_val); eval_node_set_int_val(func_node, int_val);
} }
/********************************************************************* /*********************************************************************
@ -791,7 +791,7 @@ eval_func(
/* The functions are not defined for SQL null argument /* The functions are not defined for SQL null argument
values, except for eval_cmp and notfound */ values, except for eval_cmp and notfound */
if ((dfield_get_len(que_node_get_val(arg)) == UNIV_SQL_NULL) if ((dfield_get_len(que_node_get_val(arg)) == UNIV_SQL_NULL)
&& (class != PARS_FUNC_CMP) && (class != PARS_FUNC_CMP)
&& (func != PARS_NOTFOUND_TOKEN) && (func != PARS_NOTFOUND_TOKEN)

View File

@ -25,7 +25,7 @@ if_step(
elsif_node_t* elsif_node; elsif_node_t* elsif_node;
ut_ad(thr); ut_ad(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_IF); ut_ad(que_node_get_type(node) == QUE_NODE_IF);
@ -83,9 +83,9 @@ if_step(
if (thr->run_node == NULL) { if (thr->run_node == NULL) {
thr->run_node = que_node_get_parent(node); thr->run_node = que_node_get_parent(node);
} }
return(thr); return(thr);
} }
/************************************************************************** /**************************************************************************
Performs an execution step of a while-statement node. */ Performs an execution step of a while-statement node. */
@ -99,7 +99,7 @@ while_step(
while_node_t* node; while_node_t* node;
ut_ad(thr); ut_ad(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_WHILE); ut_ad(que_node_get_type(node) == QUE_NODE_WHILE);
@ -121,7 +121,7 @@ while_step(
} }
return(thr); return(thr);
} }
/************************************************************************** /**************************************************************************
Performs an execution step of an assignment statement node. */ Performs an execution step of an assignment statement node. */
@ -135,7 +135,7 @@ assign_step(
assign_node_t* node; assign_node_t* node;
ut_ad(thr); ut_ad(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_ASSIGNMENT); ut_ad(que_node_get_type(node) == QUE_NODE_ASSIGNMENT);
@ -144,11 +144,11 @@ assign_step(
eval_exp(node->val); eval_exp(node->val);
eval_node_copy_val(node->var->alias, node->val); eval_node_copy_val(node->var->alias, node->val);
thr->run_node = que_node_get_parent(node); thr->run_node = que_node_get_parent(node);
return(thr); return(thr);
} }
/************************************************************************** /**************************************************************************
Performs an execution step of a for-loop node. */ Performs an execution step of a for-loop node. */
@ -164,9 +164,9 @@ for_step(
lint loop_var_value; lint loop_var_value;
ut_ad(thr); ut_ad(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_FOR); ut_ad(que_node_get_type(node) == QUE_NODE_FOR);
parent = que_node_get_parent(node); parent = que_node_get_parent(node);
@ -182,7 +182,7 @@ for_step(
} }
/* Increment the value of loop_var */ /* Increment the value of loop_var */
loop_var_value = 1 + eval_node_get_int_val(node->loop_var); loop_var_value = 1 + eval_node_get_int_val(node->loop_var);
} else { } else {
/* Initialize the loop */ /* Initialize the loop */
@ -210,7 +210,7 @@ for_step(
} }
return(thr); return(thr);
} }
/************************************************************************** /**************************************************************************
Performs an execution step of a return-statement node. */ Performs an execution step of a return-statement node. */
@ -225,9 +225,9 @@ return_step(
que_node_t* parent; que_node_t* parent;
ut_ad(thr); ut_ad(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_RETURN); ut_ad(que_node_get_type(node) == QUE_NODE_RETURN);
parent = node; parent = node;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@ flst_add_to_empty(
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
len = flst_get_len(base, mtr); len = flst_get_len(base, mtr);
ut_a(len == 0); ut_a(len == 0);
buf_ptr_get_fsp_addr(node, &space, &node_addr); buf_ptr_get_fsp_addr(node, &space, &node_addr);
/* Update first and last fields of base node */ /* Update first and last fields of base node */
@ -50,7 +50,7 @@ flst_add_to_empty(
flst_write_addr(node + FLST_NEXT, fil_addr_null, mtr); flst_write_addr(node + FLST_NEXT, fil_addr_null, mtr);
/* Update len of base node */ /* Update len of base node */
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr); mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
} }
/************************************************************************ /************************************************************************
@ -68,7 +68,7 @@ flst_add_last(
ulint len; ulint len;
fil_addr_t last_addr; fil_addr_t last_addr;
flst_node_t* last_node; flst_node_t* last_node;
ut_ad(mtr && base && node); ut_ad(mtr && base && node);
ut_ad(base != node); ut_ad(base != node);
ut_ad(mtr_memo_contains(mtr, buf_block_align(base), ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
@ -89,10 +89,10 @@ flst_add_last(
mtr); mtr);
} }
flst_insert_after(base, last_node, node, mtr); flst_insert_after(base, last_node, node, mtr);
} else { } else {
/* else call flst_add_to_empty */ /* else call flst_add_to_empty */
flst_add_to_empty(base, node, mtr); flst_add_to_empty(base, node, mtr);
} }
} }
@ -111,7 +111,7 @@ flst_add_first(
ulint len; ulint len;
fil_addr_t first_addr; fil_addr_t first_addr;
flst_node_t* first_node; flst_node_t* first_node;
ut_ad(mtr && base && node); ut_ad(mtr && base && node);
ut_ad(base != node); ut_ad(base != node);
ut_ad(mtr_memo_contains(mtr, buf_block_align(base), ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
@ -133,10 +133,10 @@ flst_add_first(
RW_X_LATCH, mtr); RW_X_LATCH, mtr);
} }
flst_insert_before(base, node, first_node, mtr); flst_insert_before(base, node, first_node, mtr);
} else { } else {
/* else call flst_add_to_empty */ /* else call flst_add_to_empty */
flst_add_to_empty(base, node, mtr); flst_add_to_empty(base, node, mtr);
} }
} }
@ -157,7 +157,7 @@ flst_insert_after(
flst_node_t* node3; flst_node_t* node3;
fil_addr_t node3_addr; fil_addr_t node3_addr;
ulint len; ulint len;
ut_ad(mtr && node1 && node2 && base); ut_ad(mtr && node1 && node2 && base);
ut_ad(base != node1); ut_ad(base != node1);
ut_ad(base != node2); ut_ad(base != node2);
@ -173,7 +173,7 @@ flst_insert_after(
buf_ptr_get_fsp_addr(node2, &space, &node2_addr); buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
node3_addr = flst_get_next_addr(node1, mtr); node3_addr = flst_get_next_addr(node1, mtr);
/* Set prev and next fields of node2 */ /* Set prev and next fields of node2 */
flst_write_addr(node2 + FLST_PREV, node1_addr, mtr); flst_write_addr(node2 + FLST_PREV, node1_addr, mtr);
flst_write_addr(node2 + FLST_NEXT, node3_addr, mtr); flst_write_addr(node2 + FLST_NEXT, node3_addr, mtr);
@ -186,13 +186,13 @@ flst_insert_after(
/* node1 was last in list: update last field in base */ /* node1 was last in list: update last field in base */
flst_write_addr(base + FLST_LAST, node2_addr, mtr); flst_write_addr(base + FLST_LAST, node2_addr, mtr);
} }
/* Set next field of node1 */ /* Set next field of node1 */
flst_write_addr(node1 + FLST_NEXT, node2_addr, mtr); flst_write_addr(node1 + FLST_NEXT, node2_addr, mtr);
/* Update len of base node */ /* Update len of base node */
len = flst_get_len(base, mtr); len = flst_get_len(base, mtr);
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr); mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
} }
/************************************************************************ /************************************************************************
@ -212,7 +212,7 @@ flst_insert_before(
fil_addr_t node2_addr; fil_addr_t node2_addr;
fil_addr_t node3_addr; fil_addr_t node3_addr;
ulint len; ulint len;
ut_ad(mtr && node2 && node3 && base); ut_ad(mtr && node2 && node3 && base);
ut_ad(base != node2); ut_ad(base != node2);
ut_ad(base != node3); ut_ad(base != node3);
@ -228,7 +228,7 @@ flst_insert_before(
buf_ptr_get_fsp_addr(node3, &space, &node3_addr); buf_ptr_get_fsp_addr(node3, &space, &node3_addr);
node1_addr = flst_get_prev_addr(node3, mtr); node1_addr = flst_get_prev_addr(node3, mtr);
/* Set prev and next fields of node2 */ /* Set prev and next fields of node2 */
flst_write_addr(node2 + FLST_PREV, node1_addr, mtr); flst_write_addr(node2 + FLST_PREV, node1_addr, mtr);
flst_write_addr(node2 + FLST_NEXT, node3_addr, mtr); flst_write_addr(node2 + FLST_NEXT, node3_addr, mtr);
@ -241,13 +241,13 @@ flst_insert_before(
/* node3 was first in list: update first field in base */ /* node3 was first in list: update first field in base */
flst_write_addr(base + FLST_FIRST, node2_addr, mtr); flst_write_addr(base + FLST_FIRST, node2_addr, mtr);
} }
/* Set prev field of node3 */ /* Set prev field of node3 */
flst_write_addr(node3 + FLST_PREV, node2_addr, mtr); flst_write_addr(node3 + FLST_PREV, node2_addr, mtr);
/* Update len of base node */ /* Update len of base node */
len = flst_get_len(base, mtr); len = flst_get_len(base, mtr);
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr); mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
} }
/************************************************************************ /************************************************************************
@ -267,7 +267,7 @@ flst_remove(
flst_node_t* node3; flst_node_t* node3;
fil_addr_t node3_addr; fil_addr_t node3_addr;
ulint len; ulint len;
ut_ad(mtr && node2 && base); ut_ad(mtr && node2 && base);
ut_ad(mtr_memo_contains(mtr, buf_block_align(base), ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
@ -282,7 +282,7 @@ flst_remove(
if (!fil_addr_is_null(node1_addr)) { if (!fil_addr_is_null(node1_addr)) {
/* Update next field of node1 */ /* Update next field of node1 */
if (node1_addr.page == node2_addr.page) { if (node1_addr.page == node2_addr.page) {
node1 = buf_frame_align(node2) + node1_addr.boffset; node1 = buf_frame_align(node2) + node1_addr.boffset;
@ -290,7 +290,7 @@ flst_remove(
node1 = fut_get_ptr(space, node1_addr, RW_X_LATCH, node1 = fut_get_ptr(space, node1_addr, RW_X_LATCH,
mtr); mtr);
} }
ut_ad(node1 != node2); ut_ad(node1 != node2);
flst_write_addr(node1 + FLST_NEXT, node3_addr, mtr); flst_write_addr(node1 + FLST_NEXT, node3_addr, mtr);
@ -309,7 +309,7 @@ flst_remove(
node3 = fut_get_ptr(space, node3_addr, RW_X_LATCH, node3 = fut_get_ptr(space, node3_addr, RW_X_LATCH,
mtr); mtr);
} }
ut_ad(node2 != node3); ut_ad(node2 != node3);
flst_write_addr(node3 + FLST_PREV, node1_addr, mtr); flst_write_addr(node3 + FLST_PREV, node1_addr, mtr);
@ -317,12 +317,12 @@ flst_remove(
/* node2 was last in list: update last field in base */ /* node2 was last in list: update last field in base */
flst_write_addr(base + FLST_LAST, node1_addr, mtr); flst_write_addr(base + FLST_LAST, node1_addr, mtr);
} }
/* Update len of base node */ /* Update len of base node */
len = flst_get_len(base, mtr); len = flst_get_len(base, mtr);
ut_ad(len > 0); ut_ad(len > 0);
mlog_write_ulint(base + FLST_LEN, len - 1, MLOG_4BYTES, mtr); mlog_write_ulint(base + FLST_LEN, len - 1, MLOG_4BYTES, mtr);
} }
/************************************************************************ /************************************************************************
@ -344,14 +344,14 @@ flst_cut_end(
fil_addr_t node1_addr; fil_addr_t node1_addr;
fil_addr_t node2_addr; fil_addr_t node2_addr;
ulint len; ulint len;
ut_ad(mtr && node2 && base); ut_ad(mtr && node2 && base);
ut_ad(mtr_memo_contains(mtr, buf_block_align(base), ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
ut_ad(mtr_memo_contains(mtr, buf_block_align(node2), ut_ad(mtr_memo_contains(mtr, buf_block_align(node2),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
ut_ad(n_nodes > 0); ut_ad(n_nodes > 0);
buf_ptr_get_fsp_addr(node2, &space, &node2_addr); buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
node1_addr = flst_get_prev_addr(node2, mtr); node1_addr = flst_get_prev_addr(node2, mtr);
@ -367,7 +367,7 @@ flst_cut_end(
node1 = fut_get_ptr(space, node1_addr, RW_X_LATCH, node1 = fut_get_ptr(space, node1_addr, RW_X_LATCH,
mtr); mtr);
} }
flst_write_addr(node1 + FLST_NEXT, fil_addr_null, mtr); flst_write_addr(node1 + FLST_NEXT, fil_addr_null, mtr);
} else { } else {
/* node2 was first in list: update the field in base */ /* node2 was first in list: update the field in base */
@ -380,7 +380,7 @@ flst_cut_end(
len = flst_get_len(base, mtr); len = flst_get_len(base, mtr);
ut_ad(len >= n_nodes); ut_ad(len >= n_nodes);
mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr); mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr);
} }
/************************************************************************ /************************************************************************
@ -399,7 +399,7 @@ flst_truncate_end(
fil_addr_t node2_addr; fil_addr_t node2_addr;
ulint len; ulint len;
ulint space; ulint space;
ut_ad(mtr && node2 && base); ut_ad(mtr && node2 && base);
ut_ad(mtr_memo_contains(mtr, buf_block_align(base), ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
@ -408,7 +408,7 @@ flst_truncate_end(
if (n_nodes == 0) { if (n_nodes == 0) {
ut_ad(fil_addr_is_null(flst_get_next_addr(node2, mtr))); ut_ad(fil_addr_is_null(flst_get_next_addr(node2, mtr)));
return; return;
} }
@ -423,7 +423,7 @@ flst_truncate_end(
len = flst_get_len(base, mtr); len = flst_get_len(base, mtr);
ut_ad(len >= n_nodes); ut_ad(len >= n_nodes);
mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr); mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr);
} }
/************************************************************************ /************************************************************************
@ -443,7 +443,7 @@ flst_validate(
ulint len; ulint len;
ulint i; ulint i;
mtr_t mtr2; mtr_t mtr2;
ut_ad(base); ut_ad(base);
ut_ad(mtr_memo_contains(mtr1, buf_block_align(base), ut_ad(mtr_memo_contains(mtr1, buf_block_align(base),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
@ -470,7 +470,7 @@ flst_validate(
mtr_commit(&mtr2); /* Commit mtr2 each round to prevent buffer mtr_commit(&mtr2); /* Commit mtr2 each round to prevent buffer
becoming full */ becoming full */
} }
ut_a(fil_addr_is_null(node_addr)); ut_a(fil_addr_is_null(node_addr));
node_addr = flst_get_last(base, mtr1); node_addr = flst_get_last(base, mtr1);
@ -484,7 +484,7 @@ flst_validate(
mtr_commit(&mtr2); /* Commit mtr2 each round to prevent buffer mtr_commit(&mtr2); /* Commit mtr2 each round to prevent buffer
becoming full */ becoming full */
} }
ut_a(fil_addr_is_null(node_addr)); ut_a(fil_addr_is_null(node_addr));
return(TRUE); return(TRUE);
@ -501,10 +501,10 @@ flst_print(
{ {
buf_frame_t* frame; buf_frame_t* frame;
ulint len; ulint len;
ut_ad(base && mtr); ut_ad(base && mtr);
ut_ad(mtr_memo_contains(mtr, buf_block_align(base), ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
frame = buf_frame_align(base); frame = buf_frame_align(base);
len = flst_get_len(base, mtr); len = flst_get_len(base, mtr);
@ -512,7 +512,7 @@ flst_print(
fprintf(stderr, fprintf(stderr,
"FILE-BASED LIST:\n" "FILE-BASED LIST:\n"
"Base node in space %lu page %lu byte offset %lu; len %lu\n", "Base node in space %lu page %lu byte offset %lu; len %lu\n",
(ulong) buf_frame_get_space_id(frame), (ulong) buf_frame_get_space_id(frame),
(ulong) buf_frame_get_page_no(frame), (ulong) buf_frame_get_page_no(frame),
(ulong) (base - frame), (ulong) len); (ulong) (base - frame), (ulong) len);
} }

View File

@ -42,7 +42,7 @@ ha_create(
/* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail, /* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
but in practise it never should in this case, hence the asserts. */ but in practise it never should in this case, hence the asserts. */
if (n_mutexes == 0) { if (n_mutexes == 0) {
if (in_btr_search) { if (in_btr_search) {
table->heap = mem_heap_create_in_btr_search(4096); table->heap = mem_heap_create_in_btr_search(4096);
@ -53,7 +53,7 @@ ha_create(
return(table); return(table);
} }
hash_create_mutexes(table, n_mutexes, mutex_level); hash_create_mutexes(table, n_mutexes, mutex_level);
table->heaps = mem_alloc(n_mutexes * sizeof(void*)); table->heaps = mem_alloc(n_mutexes * sizeof(void*));
@ -66,7 +66,7 @@ ha_create(
table->heaps[i] = mem_heap_create_in_buffer(4096); table->heaps[i] = mem_heap_create_in_buffer(4096);
} }
} }
return(table); return(table);
} }
@ -119,7 +119,7 @@ ha_insert_for_fold(
prev_node = prev_node->next; prev_node = prev_node->next;
} }
/* We have to allocate a new chain node */ /* We have to allocate a new chain node */
node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t)); node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t));
@ -132,7 +132,7 @@ ha_insert_for_fold(
return(FALSE); return(FALSE);
} }
ha_node_set_data(node, data); ha_node_set_data(node, data);
if (table->adaptive) { if (table->adaptive) {
@ -151,7 +151,7 @@ ha_insert_for_fold(
return(TRUE); return(TRUE);
} }
while (prev_node->next != NULL) { while (prev_node->next != NULL) {
prev_node = prev_node->next; prev_node = prev_node->next;
@ -160,7 +160,7 @@ ha_insert_for_fold(
prev_node->next = node; prev_node->next = node;
return(TRUE); return(TRUE);
} }
/*************************************************************** /***************************************************************
Deletes a hash node. */ Deletes a hash node. */
@ -200,7 +200,7 @@ ha_delete(
ut_a(node); ut_a(node);
ha_delete_hash_node(table, node); ha_delete_hash_node(table, node);
} }
/************************************************************* /*************************************************************
Looks for an element when we know the pointer to the data, and updates Looks for an element when we know the pointer to the data, and updates
@ -269,7 +269,7 @@ ha_remove_all_nodes_to_page(
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
/* Check that all nodes really got deleted */ /* Check that all nodes really got deleted */
node = ha_chain_get_first(table, fold); node = ha_chain_get_first(table, fold);
while (node) { while (node) {
@ -281,20 +281,26 @@ ha_remove_all_nodes_to_page(
} }
/***************************************************************** /*****************************************************************
Validates a hash table. */ Validates a given range of the cells in hash table. */
ibool ibool
ha_validate( ha_validate(
/*========*/ /*========*/
/* out: TRUE if ok */ /* out: TRUE if ok */
hash_table_t* table) /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index) /* in: end index */
{ {
hash_cell_t* cell; hash_cell_t* cell;
ha_node_t* node; ha_node_t* node;
ibool ok = TRUE; ibool ok = TRUE;
ulint i; ulint i;
for (i = 0; i < hash_get_n_cells(table); i++) { ut_a(start_index <= end_index);
ut_a(start_index < hash_get_n_cells(table));
ut_a(end_index < hash_get_n_cells(table));
for (i = start_index; i <= end_index; i++) {
cell = hash_get_nth_cell(table, i); cell = hash_get_nth_cell(table, i);
@ -316,7 +322,7 @@ ha_validate(
} }
return(ok); return(ok);
} }
/***************************************************************** /*****************************************************************
Prints info of a hash table. */ Prints info of a hash table. */
@ -356,7 +362,7 @@ ha_print_info(
if (table->heap->free_block) { if (table->heap->free_block) {
n_bufs++; n_bufs++;
} }
fprintf(file, ", node heap has %lu buffer(s)\n", (ulong) n_bufs); fprintf(file, ", node heap has %lu buffer(s)\n", (ulong) n_bufs);
} }
} }

View File

@ -19,8 +19,8 @@ Reserves the mutex for a fold value in a hash table. */
void void
hash_mutex_enter( hash_mutex_enter(
/*=============*/ /*=============*/
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold) /* in: fold */ ulint fold) /* in: fold */
{ {
mutex_enter(hash_get_mutex(table, fold)); mutex_enter(hash_get_mutex(table, fold));
} }
@ -31,8 +31,8 @@ Releases the mutex for a fold value in a hash table. */
void void
hash_mutex_exit( hash_mutex_exit(
/*============*/ /*============*/
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold) /* in: fold */ ulint fold) /* in: fold */
{ {
mutex_exit(hash_get_mutex(table, fold)); mutex_exit(hash_get_mutex(table, fold));
} }
@ -43,7 +43,7 @@ Reserves all the mutexes of a hash table, in an ascending order. */
void void
hash_mutex_enter_all( hash_mutex_enter_all(
/*=================*/ /*=================*/
hash_table_t* table) /* in: hash table */ hash_table_t* table) /* in: hash table */
{ {
ulint i; ulint i;
@ -59,7 +59,7 @@ Releases all the mutexes of a hash table. */
void void
hash_mutex_exit_all( hash_mutex_exit_all(
/*================*/ /*================*/
hash_table_t* table) /* in: hash table */ hash_table_t* table) /* in: hash table */
{ {
ulint i; ulint i;
@ -84,13 +84,13 @@ hash_create(
hash_table_t* table; hash_table_t* table;
ulint i; ulint i;
hash_cell_t* cell; hash_cell_t* cell;
prime = ut_find_prime(n); prime = ut_find_prime(n);
table = mem_alloc(sizeof(hash_table_t)); table = mem_alloc(sizeof(hash_table_t));
array = ut_malloc(sizeof(hash_cell_t) * prime); array = ut_malloc(sizeof(hash_cell_t) * prime);
table->adaptive = FALSE; table->adaptive = FALSE;
table->array = array; table->array = array;
table->n_cells = prime; table->n_cells = prime;
@ -99,7 +99,7 @@ hash_create(
table->heaps = NULL; table->heaps = NULL;
table->heap = NULL; table->heap = NULL;
table->magic_n = HASH_TABLE_MAGIC_N; table->magic_n = HASH_TABLE_MAGIC_N;
/* Initialize the cell array */ /* Initialize the cell array */
for (i = 0; i < prime; i++) { for (i = 0; i < prime; i++) {

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,7 @@ optimization */
/* This flag ORed to latch mode says that we can ignore possible /* This flag ORed to latch mode says that we can ignore possible
UNIQUE definition on secondary indexes when we decide if we can use the UNIQUE definition on secondary indexes when we decide if we can use the
insert buffer to speed up inserts */ insert buffer to speed up inserts */
#define BTR_IGNORE_SEC_UNIQUE 2048 #define BTR_IGNORE_SEC_UNIQUE 2048
/****************************************************************** /******************************************************************
Gets the root node of a tree and x-latches it. */ Gets the root node of a tree and x-latches it. */
@ -144,7 +144,7 @@ UNIV_INLINE
ulint ulint
btr_node_ptr_get_child_page_no( btr_node_ptr_get_child_page_no(
/*===========================*/ /*===========================*/
/* out: child node address */ /* out: child node address */
rec_t* rec, /* in: node pointer record */ rec_t* rec, /* in: node pointer record */
const ulint* offsets);/* in: array returned by rec_get_offsets() */ const ulint* offsets);/* in: array returned by rec_get_offsets() */
/**************************************************************** /****************************************************************
@ -277,6 +277,7 @@ btr_node_ptr_delete(
dict_tree_t* tree, /* in: index tree */ dict_tree_t* tree, /* in: index tree */
page_t* page, /* in: page whose node pointer is deleted */ page_t* page, /* in: page whose node pointer is deleted */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
#ifdef UNIV_DEBUG
/**************************************************************** /****************************************************************
Checks that the node pointer to a page is appropriate. */ Checks that the node pointer to a page is appropriate. */
@ -287,6 +288,7 @@ btr_check_node_ptr(
dict_tree_t* tree, /* in: index tree */ dict_tree_t* tree, /* in: index tree */
page_t* page, /* in: index page */ page_t* page, /* in: index page */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
#endif /* UNIV_DEBUG */
/***************************************************************** /*****************************************************************
Tries to merge the page first to the left immediate brother if such a Tries to merge the page first to the left immediate brother if such a
brother exists, and the node pointers to the current page and to the brother exists, and the node pointers to the current page and to the
@ -374,7 +376,7 @@ void
btr_page_free( btr_page_free(
/*==========*/ /*==========*/
dict_tree_t* tree, /* in: index tree */ dict_tree_t* tree, /* in: index tree */
page_t* page, /* in: page to be freed, x-latched */ page_t* page, /* in: page to be freed, x-latched */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
/****************************************************************** /******************************************************************
Frees a file page used in an index tree. Can be used also to BLOB Frees a file page used in an index tree. Can be used also to BLOB
@ -385,7 +387,7 @@ void
btr_page_free_low( btr_page_free_low(
/*==============*/ /*==============*/
dict_tree_t* tree, /* in: index tree */ dict_tree_t* tree, /* in: index tree */
page_t* page, /* in: page to be freed, x-latched */ page_t* page, /* in: page to be freed, x-latched */
ulint level, /* in: page level */ ulint level, /* in: page level */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
#ifdef UNIV_BTR_PRINT #ifdef UNIV_BTR_PRINT
@ -412,7 +414,7 @@ the index. */
ibool ibool
btr_index_rec_validate( btr_index_rec_validate(
/*====================*/ /*===================*/
/* out: TRUE if ok */ /* out: TRUE if ok */
rec_t* rec, /* in: index record */ rec_t* rec, /* in: index record */
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
@ -429,11 +431,11 @@ btr_validate_tree(
dict_tree_t* tree, /* in: tree */ dict_tree_t* tree, /* in: tree */
trx_t* trx); /* in: transaction or NULL */ trx_t* trx); /* in: transaction or NULL */
#define BTR_N_LEAF_PAGES 1 #define BTR_N_LEAF_PAGES 1
#define BTR_TOTAL_SIZE 2 #define BTR_TOTAL_SIZE 2
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "btr0btr.ic" #include "btr0btr.ic"
#endif #endif
#endif #endif

View File

@ -28,7 +28,7 @@ btr_page_get(
page = buf_page_get(space, page_no, mode, mtr); page = buf_page_get(space, page_no, mode, mtr);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
if (mode != RW_NO_LATCH) { if (mode != RW_NO_LATCH) {
buf_page_dbg_add_level(page, SYNC_TREE_NODE); buf_page_dbg_add_level(page, SYNC_TREE_NODE);
} }
#endif #endif
@ -72,7 +72,7 @@ btr_page_get_level_low(
ulint level; ulint level;
ut_ad(page); ut_ad(page);
level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL); level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
ut_ad(level <= BTR_MAX_NODE_LEVEL); ut_ad(level <= BTR_MAX_NODE_LEVEL);
@ -92,7 +92,7 @@ btr_page_get_level(
{ {
ut_ad(page && mtr); ut_ad(page && mtr);
return(btr_page_get_level_low(page)); return(btr_page_get_level_low(page));
} }
/************************************************************ /************************************************************
@ -124,9 +124,9 @@ btr_page_get_next(
{ {
ut_ad(page && mtr); ut_ad(page && mtr);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page), ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX) MTR_MEMO_PAGE_X_FIX)
|| mtr_memo_contains(mtr, buf_block_align(page), || mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_S_FIX)); MTR_MEMO_PAGE_S_FIX));
return(mach_read_from_4(page + FIL_PAGE_NEXT)); return(mach_read_from_4(page + FIL_PAGE_NEXT));
} }
@ -157,7 +157,7 @@ btr_page_get_prev(
mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{ {
ut_ad(page && mtr); ut_ad(page && mtr);
return(mach_read_from_4(page + FIL_PAGE_PREV)); return(mach_read_from_4(page + FIL_PAGE_PREV));
} }
@ -182,7 +182,7 @@ UNIV_INLINE
ulint ulint
btr_node_ptr_get_child_page_no( btr_node_ptr_get_child_page_no(
/*===========================*/ /*===========================*/
/* out: child node address */ /* out: child node address */
rec_t* rec, /* in: node pointer record */ rec_t* rec, /* in: node pointer record */
const ulint* offsets)/* in: array returned by rec_get_offsets() */ const ulint* offsets)/* in: array returned by rec_get_offsets() */
{ {
@ -192,12 +192,12 @@ btr_node_ptr_get_child_page_no(
ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec)); ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
/* The child address is in the last field */ /* The child address is in the last field */
field = rec_get_nth_field(rec, offsets, field = rec_get_nth_field(rec, offsets,
rec_offs_n_fields(offsets) - 1, &len); rec_offs_n_fields(offsets) - 1, &len);
ut_ad(len == 4); ut_ad(len == 4);
page_no = mach_read_from_4(field); page_no = mach_read_from_4(field);
if (UNIV_UNLIKELY(page_no == 0)) { if (UNIV_UNLIKELY(page_no == 0)) {
@ -223,11 +223,11 @@ btr_leaf_page_release(
ut_ad(!mtr_memo_contains(mtr, buf_block_align(page), ut_ad(!mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_MODIFY)); MTR_MEMO_MODIFY));
if (latch_mode == BTR_SEARCH_LEAF) { if (latch_mode == BTR_SEARCH_LEAF) {
mtr_memo_release(mtr, buf_block_align(page), mtr_memo_release(mtr, buf_block_align(page),
MTR_MEMO_PAGE_S_FIX); MTR_MEMO_PAGE_S_FIX);
} else { } else {
ut_ad(latch_mode == BTR_MODIFY_LEAF); ut_ad(latch_mode == BTR_MODIFY_LEAF);
mtr_memo_release(mtr, buf_block_align(page), mtr_memo_release(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX); MTR_MEMO_PAGE_X_FIX);
} }
} }

View File

@ -72,7 +72,7 @@ UNIV_INLINE
void void
btr_cur_position( btr_cur_position(
/*=============*/ /*=============*/
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
rec_t* rec, /* in: record in tree */ rec_t* rec, /* in: record in tree */
btr_cur_t* cursor);/* in: cursor */ btr_cur_t* cursor);/* in: cursor */
/************************************************************************ /************************************************************************
@ -550,7 +550,7 @@ btr_push_update_extern_fields(
to have space for all fields in rec */ to have space for all fields in rec */
const ulint* offsets,/* in: array returned by rec_get_offsets() */ const ulint* offsets,/* in: array returned by rec_get_offsets() */
upd_t* update);/* in: update vector or NULL */ upd_t* update);/* in: update vector or NULL */
/*######################################################################*/ /*######################################################################*/
@ -697,5 +697,5 @@ extern ulint btr_cur_n_sea_old;
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "btr0cur.ic" #include "btr0cur.ic"
#endif #endif
#endif #endif

View File

@ -53,7 +53,8 @@ btr_cur_get_page(
btr_cur_t* cursor) /* in: tree cursor */ btr_cur_t* cursor) /* in: tree cursor */
{ {
page_t* page = buf_frame_align(page_cur_get_rec(&(cursor->page_cur))); page_t* page = buf_frame_align(page_cur_get_rec(&(cursor->page_cur)));
ut_ad(!!page_is_comp(page) == cursor->index->table->comp); ut_ad(!!page_is_comp(page)
== dict_table_is_comp(cursor->index->table));
return(page); return(page);
} }
@ -75,7 +76,7 @@ UNIV_INLINE
void void
btr_cur_position( btr_cur_position(
/*=============*/ /*=============*/
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
rec_t* rec, /* in: record in tree */ rec_t* rec, /* in: record in tree */
btr_cur_t* cursor) /* in: cursor */ btr_cur_t* cursor) /* in: cursor */
{ {
@ -96,7 +97,7 @@ btr_cur_compress_recommendation(
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
page_t* page; page_t* page;
ut_ad(mtr_memo_contains(mtr, buf_block_align( ut_ad(mtr_memo_contains(mtr, buf_block_align(
btr_cur_get_page(cursor)), btr_cur_get_page(cursor)),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
@ -104,27 +105,27 @@ btr_cur_compress_recommendation(
page = btr_cur_get_page(cursor); page = btr_cur_get_page(cursor);
if ((page_get_data_size(page) < BTR_CUR_PAGE_COMPRESS_LIMIT) if ((page_get_data_size(page) < BTR_CUR_PAGE_COMPRESS_LIMIT)
|| ((btr_page_get_next(page, mtr) == FIL_NULL) || ((btr_page_get_next(page, mtr) == FIL_NULL)
&& (btr_page_get_prev(page, mtr) == FIL_NULL))) { && (btr_page_get_prev(page, mtr) == FIL_NULL))) {
/* The page fillfactor has dropped below a predefined /* The page fillfactor has dropped below a predefined
minimum value OR the level in the B-tree contains just minimum value OR the level in the B-tree contains just
one page: we recommend compression if this is not the one page: we recommend compression if this is not the
root page. */ root page. */
if (dict_tree_get_page((cursor->index)->tree) if (dict_tree_get_page((cursor->index)->tree)
== buf_frame_get_page_no(page)) { == buf_frame_get_page_no(page)) {
/* It is the root page */ /* It is the root page */
return(FALSE); return(FALSE);
} }
return(TRUE); return(TRUE);
} }
return(FALSE); return(FALSE);
} }
/************************************************************************* /*************************************************************************
Checks if the record on which the cursor is placed can be deleted without Checks if the record on which the cursor is placed can be deleted without
@ -140,7 +141,7 @@ btr_cur_can_delete_without_compress(
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
page_t* page; page_t* page;
ut_ad(mtr_memo_contains(mtr, buf_block_align( ut_ad(mtr_memo_contains(mtr, buf_block_align(
btr_cur_get_page(cursor)), btr_cur_get_page(cursor)),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
@ -148,21 +149,21 @@ btr_cur_can_delete_without_compress(
page = btr_cur_get_page(cursor); page = btr_cur_get_page(cursor);
if ((page_get_data_size(page) - rec_size < BTR_CUR_PAGE_COMPRESS_LIMIT) if ((page_get_data_size(page) - rec_size < BTR_CUR_PAGE_COMPRESS_LIMIT)
|| ((btr_page_get_next(page, mtr) == FIL_NULL) || ((btr_page_get_next(page, mtr) == FIL_NULL)
&& (btr_page_get_prev(page, mtr) == FIL_NULL)) && (btr_page_get_prev(page, mtr) == FIL_NULL))
|| (page_get_n_recs(page) < 2)) { || (page_get_n_recs(page) < 2)) {
/* The page fillfactor will drop below a predefined /* The page fillfactor will drop below a predefined
minimum value, OR the level in the B-tree contains just minimum value, OR the level in the B-tree contains just
one page, OR the page will become empty: we recommend one page, OR the page will become empty: we recommend
compression if this is not the root page. */ compression if this is not the root page. */
if (dict_tree_get_page((cursor->index)->tree) if (dict_tree_get_page((cursor->index)->tree)
== buf_frame_get_page_no(page)) { == buf_frame_get_page_no(page)) {
/* It is the root page */ /* It is the root page */
return(TRUE); return(TRUE);
} }
return(FALSE); return(FALSE);

View File

@ -152,7 +152,7 @@ btr_pcur_open_on_user_rec(
ulint mode, /* in: PAGE_CUR_L, ... */ ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF or ulint latch_mode, /* in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */ BTR_MODIFY_LEAF */
btr_pcur_t* cursor, /* in: memory buffer for persistent btr_pcur_t* cursor, /* in: memory buffer for persistent
cursor */ cursor */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
/************************************************************************** /**************************************************************************
@ -208,7 +208,7 @@ btr_pcur_restore_position(
whose ordering fields are identical to whose ordering fields are identical to
the ones of the original user record */ the ones of the original user record */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /* in: detached persistent cursor */ btr_pcur_t* cursor, /* in: detached persistent cursor */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
/****************************************************************** /******************************************************************
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY, If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
@ -387,7 +387,7 @@ btr_pcur_is_on_user_rec(
btr_pcur_t* cursor, /* in: persistent cursor */ btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
/************************************************************* /*************************************************************
Checks if the persistent cursor is after the last user record on Checks if the persistent cursor is after the last user record on
a page. */ a page. */
UNIV_INLINE UNIV_INLINE
ibool ibool
@ -396,7 +396,7 @@ btr_pcur_is_after_last_on_page(
btr_pcur_t* cursor, /* in: persistent cursor */ btr_pcur_t* cursor, /* in: persistent cursor */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
/************************************************************* /*************************************************************
Checks if the persistent cursor is before the first user record on Checks if the persistent cursor is before the first user record on
a page. */ a page. */
UNIV_INLINE UNIV_INLINE
ibool ibool
@ -512,5 +512,5 @@ struct btr_pcur_struct{
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "btr0pcur.ic" #include "btr0pcur.ic"
#endif #endif
#endif #endif

View File

@ -102,7 +102,7 @@ btr_pcur_get_rec(
{ {
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
return(page_cur_get_rec(btr_pcur_get_page_cur(cursor))); return(page_cur_get_rec(btr_pcur_get_page_cur(cursor)));
} }
@ -152,7 +152,7 @@ btr_pcur_get_low_match(
} }
/************************************************************* /*************************************************************
Checks if the persistent cursor is after the last user record on Checks if the persistent cursor is after the last user record on
a page. */ a page. */
UNIV_INLINE UNIV_INLINE
ibool ibool
@ -164,12 +164,12 @@ btr_pcur_is_after_last_on_page(
UT_NOT_USED(mtr); UT_NOT_USED(mtr);
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor))); return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
} }
/************************************************************* /*************************************************************
Checks if the persistent cursor is before the first user record on Checks if the persistent cursor is before the first user record on
a page. */ a page. */
UNIV_INLINE UNIV_INLINE
ibool ibool
@ -181,7 +181,7 @@ btr_pcur_is_before_first_on_page(
UT_NOT_USED(mtr); UT_NOT_USED(mtr);
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor))); return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
} }
@ -196,9 +196,9 @@ btr_pcur_is_on_user_rec(
{ {
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
if ((btr_pcur_is_before_first_on_page(cursor, mtr)) if ((btr_pcur_is_before_first_on_page(cursor, mtr))
|| (btr_pcur_is_after_last_on_page(cursor, mtr))) { || (btr_pcur_is_after_last_on_page(cursor, mtr))) {
return(FALSE); return(FALSE);
} }
@ -218,7 +218,7 @@ btr_pcur_is_before_first_in_tree(
{ {
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
if (btr_page_get_prev(btr_pcur_get_page(cursor), mtr) != FIL_NULL) { if (btr_page_get_prev(btr_pcur_get_page(cursor), mtr) != FIL_NULL) {
return(FALSE); return(FALSE);
@ -239,7 +239,7 @@ btr_pcur_is_after_last_in_tree(
{ {
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
if (btr_page_get_next(btr_pcur_get_page(cursor), mtr) != FIL_NULL) { if (btr_page_get_next(btr_pcur_get_page(cursor), mtr) != FIL_NULL) {
return(FALSE); return(FALSE);
@ -260,7 +260,7 @@ btr_pcur_move_to_next_on_page(
UT_NOT_USED(mtr); UT_NOT_USED(mtr);
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
page_cur_move_to_next(btr_pcur_get_page_cur(cursor)); page_cur_move_to_next(btr_pcur_get_page_cur(cursor));
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
@ -278,7 +278,7 @@ btr_pcur_move_to_prev_on_page(
UT_NOT_USED(mtr); UT_NOT_USED(mtr);
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
page_cur_move_to_prev(btr_pcur_get_page_cur(cursor)); page_cur_move_to_prev(btr_pcur_get_page_cur(cursor));
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
@ -295,7 +295,7 @@ btr_pcur_move_to_last_on_page(
{ {
UT_NOT_USED(mtr); UT_NOT_USED(mtr);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
page_cur_set_after_last(buf_frame_align(btr_pcur_get_rec(cursor)), page_cur_set_after_last(buf_frame_align(btr_pcur_get_rec(cursor)),
btr_pcur_get_page_cur(cursor)); btr_pcur_get_page_cur(cursor));
@ -356,14 +356,14 @@ btr_pcur_move_to_next(
ut_ad(cursor->latch_mode != BTR_NO_LATCHES); ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
if (btr_pcur_is_after_last_on_page(cursor, mtr)) { if (btr_pcur_is_after_last_on_page(cursor, mtr)) {
if (btr_pcur_is_after_last_in_tree(cursor, mtr)) { if (btr_pcur_is_after_last_in_tree(cursor, mtr)) {
return(FALSE); return(FALSE);
} }
btr_pcur_move_to_next_page(cursor, mtr); btr_pcur_move_to_next_page(cursor, mtr);
return(TRUE); return(TRUE);
@ -371,7 +371,7 @@ btr_pcur_move_to_next(
btr_pcur_move_to_next_on_page(cursor, mtr); btr_pcur_move_to_next_on_page(cursor, mtr);
return(TRUE); return(TRUE);
} }
/****************************************************************** /******************************************************************
@ -388,12 +388,12 @@ btr_pcur_commit(
{ {
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED); ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
pcur->latch_mode = BTR_NO_LATCHES; pcur->latch_mode = BTR_NO_LATCHES;
mtr_commit(pcur->mtr); mtr_commit(pcur->mtr);
pcur->pos_state = BTR_PCUR_WAS_POSITIONED; pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
} }
/****************************************************************** /******************************************************************
Differs from btr_pcur_commit in that we can specify the mtr to commit. */ Differs from btr_pcur_commit in that we can specify the mtr to commit. */
@ -406,12 +406,12 @@ btr_pcur_commit_specify_mtr(
{ {
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED); ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
pcur->latch_mode = BTR_NO_LATCHES; pcur->latch_mode = BTR_NO_LATCHES;
mtr_commit(mtr); mtr_commit(mtr);
pcur->pos_state = BTR_PCUR_WAS_POSITIONED; pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
} }
/****************************************************************** /******************************************************************
Sets the pcur latch mode to BTR_NO_LATCHES. */ Sets the pcur latch mode to BTR_NO_LATCHES. */
@ -422,7 +422,7 @@ btr_pcur_detach(
btr_pcur_t* pcur) /* in: persistent cursor */ btr_pcur_t* pcur) /* in: persistent cursor */
{ {
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED); ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
pcur->latch_mode = BTR_NO_LATCHES; pcur->latch_mode = BTR_NO_LATCHES;
pcur->pos_state = BTR_PCUR_WAS_POSITIONED; pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
@ -440,7 +440,7 @@ btr_pcur_is_detached(
if (pcur->latch_mode == BTR_NO_LATCHES) { if (pcur->latch_mode == BTR_NO_LATCHES) {
return(TRUE); return(TRUE);
} }
return(FALSE); return(FALSE);
} }
@ -452,7 +452,7 @@ void
btr_pcur_init( btr_pcur_init(
/*==========*/ /*==========*/
btr_pcur_t* pcur) /* in: persistent cursor */ btr_pcur_t* pcur) /* in: persistent cursor */
{ {
pcur->old_stored = BTR_PCUR_OLD_NOT_STORED; pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
pcur->old_rec_buf = NULL; pcur->old_rec_buf = NULL;
pcur->old_rec = NULL; pcur->old_rec = NULL;
@ -485,7 +485,7 @@ btr_pcur_open(
cursor->latch_mode = latch_mode; cursor->latch_mode = latch_mode;
cursor->search_mode = mode; cursor->search_mode = mode;
/* Search with the tree cursor */ /* Search with the tree cursor */
btr_cursor = btr_pcur_get_btr_cur(cursor); btr_cursor = btr_pcur_get_btr_cur(cursor);
@ -527,7 +527,7 @@ btr_pcur_open_with_no_init(
cursor->latch_mode = latch_mode; cursor->latch_mode = latch_mode;
cursor->search_mode = mode; cursor->search_mode = mode;
/* Search with the tree cursor */ /* Search with the tree cursor */
btr_cursor = btr_pcur_get_btr_cur(cursor); btr_cursor = btr_pcur_get_btr_cur(cursor);
@ -591,7 +591,7 @@ btr_pcur_open_at_rnd_pos(
cursor->latch_mode = latch_mode; cursor->latch_mode = latch_mode;
cursor->search_mode = PAGE_CUR_G; cursor->search_mode = PAGE_CUR_G;
btr_pcur_init(cursor); btr_pcur_init(cursor);
btr_cur_open_at_rnd_pos(index, latch_mode, btr_cur_open_at_rnd_pos(index, latch_mode,
@ -601,7 +601,7 @@ btr_pcur_open_at_rnd_pos(
cursor->trx_if_known = NULL; cursor->trx_if_known = NULL;
} }
/****************************************************************** /******************************************************************
Frees the possible memory heap of a persistent cursor and sets the latch Frees the possible memory heap of a persistent cursor and sets the latch
mode of the persistent cursor to BTR_NO_LATCHES. */ mode of the persistent cursor to BTR_NO_LATCHES. */
@ -622,7 +622,7 @@ btr_pcur_close(
cursor->btr_cur.page_cur.rec = NULL; cursor->btr_cur.page_cur.rec = NULL;
cursor->old_rec = NULL; cursor->old_rec = NULL;
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
cursor->latch_mode = BTR_NO_LATCHES; cursor->latch_mode = BTR_NO_LATCHES;
cursor->pos_state = BTR_PCUR_NOT_POSITIONED; cursor->pos_state = BTR_PCUR_NOT_POSITIONED;

View File

@ -57,13 +57,13 @@ both have sensible values. */
ibool ibool
btr_search_guess_on_hash( btr_search_guess_on_hash(
/*=====================*/ /*=====================*/
/* out: TRUE if succeeded */ /* out: TRUE if succeeded */
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
btr_search_t* info, /* in: index search info */ btr_search_t* info, /* in: index search info */
dtuple_t* tuple, /* in: logical record */ dtuple_t* tuple, /* in: logical record */
ulint mode, /* in: PAGE_CUR_L, ... */ ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
btr_cur_t* cursor, /* out: tree cursor */ btr_cur_t* cursor, /* out: tree cursor */
ulint has_search_latch,/* in: latch mode the caller ulint has_search_latch,/* in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:
RW_S_LATCH, RW_X_LATCH, or 0 */ RW_S_LATCH, RW_X_LATCH, or 0 */
@ -169,7 +169,7 @@ struct btr_search_struct{
ulint n_hash_potential;/* number of consecutive searches which would ulint n_hash_potential;/* number of consecutive searches which would
have succeeded, or did succeed, using the hash have succeeded, or did succeed, using the hash
index */ index */
/*----------------------*/ /*----------------------*/
ulint n_fields; /* recommended prefix length for hash search: ulint n_fields; /* recommended prefix length for hash search:
number of full fields */ number of full fields */
ulint n_bytes; /* recommended prefix: number of bytes in ulint n_bytes; /* recommended prefix: number of bytes in
@ -250,4 +250,4 @@ much timeout. This is to reduce contention. */
#include "btr0sea.ic" #include "btr0sea.ic"
#endif #endif
#endif #endif

View File

@ -16,7 +16,7 @@ Updates the search info. */
void void
btr_search_info_update_slow( btr_search_info_update_slow(
/*========================*/ /*========================*/
btr_search_t* info, /* in: search info */ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor);/* in: cursor which was just positioned */ btr_cur_t* cursor);/* in: cursor which was just positioned */
/************************************************************************ /************************************************************************

View File

@ -15,7 +15,7 @@ Created 2/17/1996 Heikki Tuuri
#include "page0types.h" #include "page0types.h"
typedef struct btr_pcur_struct btr_pcur_t; typedef struct btr_pcur_struct btr_pcur_t;
typedef struct btr_cur_struct btr_cur_t; typedef struct btr_cur_struct btr_cur_t;
typedef struct btr_search_struct btr_search_t; typedef struct btr_search_struct btr_search_t;
#endif #endif

View File

@ -1,14 +1,14 @@
/* Innobase relational database engine; Copyright (C) 2001 Innobase Oy /* Innobase relational database engine; Copyright (C) 2001 Innobase Oy
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License 2 it under the terms of the GNU General Public License 2
as published by the Free Software Foundation in June 1991. as published by the Free Software Foundation in June 1991.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 2 You should have received a copy of the GNU General Public License 2
along with this program (in file COPYING); if not, write to the Free along with this program (in file COPYING); if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
@ -55,14 +55,14 @@ Created 11/5/1995 Heikki Tuuri
/* Magic value to use instead of checksums when they are disabled */ /* Magic value to use instead of checksums when they are disabled */
#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL #define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
extern buf_pool_t* buf_pool; /* The buffer pool of the database */ extern buf_pool_t* buf_pool; /* The buffer pool of the database */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
extern ibool buf_debug_prints;/* If this is set TRUE, the program extern ibool buf_debug_prints;/* If this is set TRUE, the program
prints info whenever read or flush prints info whenever read or flush
occurs */ occurs */
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
extern ulint srv_buf_pool_write_requests; /* variable to count write request extern ulint srv_buf_pool_write_requests; /* variable to count write request
issued */ issued */
/************************************************************************ /************************************************************************
Creates the buffer pool. */ Creates the buffer pool. */
@ -134,7 +134,7 @@ buf_frame_copy(
NOTE! The following macros should be used instead of buf_page_get_gen, NOTE! The following macros should be used instead of buf_page_get_gen,
to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed
in LA! */ in LA! */
#define buf_page_get(SP, OF, LA, MTR) buf_page_get_gen(\ #define buf_page_get(SP, OF, LA, MTR) buf_page_get_gen(\
SP, OF, LA, NULL,\ SP, OF, LA, NULL,\
BUF_GET, __FILE__, __LINE__, MTR) BUF_GET, __FILE__, __LINE__, MTR)
/****************************************************************** /******************************************************************
@ -143,13 +143,13 @@ read the contents of the page unless you know it is safe. Do not modify
the contents of the page! We have separated this case, because it is the contents of the page! We have separated this case, because it is
error-prone programming not to set a latch, and it should be used error-prone programming not to set a latch, and it should be used
with care. */ with care. */
#define buf_page_get_with_no_latch(SP, OF, MTR) buf_page_get_gen(\ #define buf_page_get_with_no_latch(SP, OF, MTR) buf_page_get_gen(\
SP, OF, RW_NO_LATCH, NULL,\ SP, OF, RW_NO_LATCH, NULL,\
BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR) BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR)
/****************************************************************** /******************************************************************
NOTE! The following macros should be used instead of buf_page_get_gen, to NOTE! The following macros should be used instead of buf_page_get_gen, to
improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed as LA! */ improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed as LA! */
#define buf_page_get_nowait(SP, OF, LA, MTR) buf_page_get_gen(\ #define buf_page_get_nowait(SP, OF, LA, MTR) buf_page_get_gen(\
SP, OF, LA, NULL,\ SP, OF, LA, NULL,\
BUF_GET_NOWAIT, __FILE__, __LINE__, MTR) BUF_GET_NOWAIT, __FILE__, __LINE__, MTR)
/****************************************************************** /******************************************************************
@ -266,7 +266,7 @@ the buffer pool. */
void void
buf_page_make_young( buf_page_make_young(
/*=================*/ /*================*/
buf_frame_t* frame); /* in: buffer frame of a file page */ buf_frame_t* frame); /* in: buffer frame of a file page */
/************************************************************************ /************************************************************************
Returns TRUE if the page can be found in the buffer pool hash table. NOTE Returns TRUE if the page can be found in the buffer pool hash table. NOTE
@ -380,7 +380,7 @@ buf_block_modify_clock_inc(
/* out: new value */ /* out: new value */
buf_block_t* block); /* in: block */ buf_block_t* block); /* in: block */
/************************************************************************ /************************************************************************
Returns the value of the modify clock. The caller must have an s-lock Returns the value of the modify clock. The caller must have an s-lock
or x-lock on the block. */ or x-lock on the block. */
UNIV_INLINE UNIV_INLINE
dulint dulint
@ -396,12 +396,12 @@ on 32-bit and 64-bit architectures. */
ulint ulint
buf_calc_page_new_checksum( buf_calc_page_new_checksum(
/*=======================*/ /*=======================*/
/* out: checksum */ /* out: checksum */
byte* page); /* in: buffer page */ byte* page); /* in: buffer page */
/************************************************************************ /************************************************************************
In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
looked at the first few bytes of the page. This calculates that old looked at the first few bytes of the page. This calculates that old
checksum. checksum.
NOTE: we must first store the new formula checksum to NOTE: we must first store the new formula checksum to
FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
because this takes that field as an input! */ because this takes that field as an input! */
@ -409,8 +409,8 @@ because this takes that field as an input! */
ulint ulint
buf_calc_page_old_checksum( buf_calc_page_old_checksum(
/*=======================*/ /*=======================*/
/* out: checksum */ /* out: checksum */
byte* page); /* in: buffer page */ byte* page); /* in: buffer page */
/************************************************************************ /************************************************************************
Checks if a page is corrupt. */ Checks if a page is corrupt. */
@ -648,7 +648,7 @@ Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
on the buffer frame. The io-handler must take care that the flag is cleared on the buffer frame. The io-handler must take care that the flag is cleared
and the lock released later. This is one of the functions which perform the and the lock released later. This is one of the functions which perform the
state transition NOT_USED => FILE_PAGE to a block (the other is state transition NOT_USED => FILE_PAGE to a block (the other is
buf_page_create). */ buf_page_create). */
buf_block_t* buf_block_t*
buf_page_init_for_read( buf_page_init_for_read(
@ -704,7 +704,7 @@ buf_get_free_list_len(void);
/*=======================*/ /*=======================*/
/* The buffer control block structure */ /* The buffer control block structure */
struct buf_block_struct{ struct buf_block_struct{
@ -745,8 +745,6 @@ struct buf_block_struct{
buffer pool which are index pages, buffer pool which are index pages,
but this flag is not set because but this flag is not set because
we do not keep track of all pages */ we do not keep track of all pages */
dict_index_t* index; /* index for which the adaptive
hash index has been created */
/* 2. Page flushing fields */ /* 2. Page flushing fields */
UT_LIST_NODE_T(buf_block_t) flush_list; UT_LIST_NODE_T(buf_block_t) flush_list;
@ -820,7 +818,7 @@ struct buf_block_struct{
/* 5. Hash search fields: NOTE that the first 4 fields are NOT /* 5. Hash search fields: NOTE that the first 4 fields are NOT
protected by any semaphore! */ protected by any semaphore! */
ulint n_hash_helps; /* counter which controls building ulint n_hash_helps; /* counter which controls building
of a new hash index for the page */ of a new hash index for the page */
ulint n_fields; /* recommended prefix length for hash ulint n_fields; /* recommended prefix length for hash
@ -832,8 +830,14 @@ struct buf_block_struct{
whether the leftmost record of several whether the leftmost record of several
records with the same prefix should be records with the same prefix should be
indexed in the hash index */ indexed in the hash index */
/* The following 4 fields are protected by btr_search_latch: */ /* These 6 fields may only be modified when we have
an x-latch on btr_search_latch AND
a) we are holding an s-latch or x-latch on block->lock or
b) we know that block->buf_fix_count == 0.
An exception to this is when we init or create a page
in the buffer pool in buf0buf.c. */
ibool is_hashed; /* TRUE if hash index has already been ibool is_hashed; /* TRUE if hash index has already been
built on this page; note that it does built on this page; note that it does
@ -850,6 +854,8 @@ struct buf_block_struct{
ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
BTR_SEARCH_RIGHT_SIDE in hash BTR_SEARCH_RIGHT_SIDE in hash
indexing */ indexing */
dict_index_t* index; /* Index for which the adaptive
hash index has been created. */
/* 6. Debug fields */ /* 6. Debug fields */
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
rw_lock_t debug_latch; /* in the debug version, each thread rw_lock_t debug_latch; /* in the debug version, each thread
@ -857,9 +863,9 @@ struct buf_block_struct{
an s-latch here; so we can use the an s-latch here; so we can use the
debug utilities in sync0rw */ debug utilities in sync0rw */
#endif #endif
ibool file_page_was_freed; ibool file_page_was_freed;
/* this is set to TRUE when fsp /* this is set to TRUE when fsp
frees a page in buffer pool */ frees a page in buffer pool */
}; };
#define BUF_BLOCK_MAGIC_N 41526563 #define BUF_BLOCK_MAGIC_N 41526563
@ -971,7 +977,7 @@ struct buf_pool_struct{
physical memory is mapped to a frame */ physical memory is mapped to a frame */
UT_LIST_BASE_NODE_T(buf_block_t) LRU; UT_LIST_BASE_NODE_T(buf_block_t) LRU;
/* base node of the LRU list */ /* base node of the LRU list */
buf_block_t* LRU_old; /* pointer to the about 3/8 oldest buf_block_t* LRU_old; /* pointer to the about 3/8 oldest
blocks in the LRU list; NULL if LRU blocks in the LRU list; NULL if LRU
length less than BUF_LRU_OLD_MIN_LEN */ length less than BUF_LRU_OLD_MIN_LEN */
ulint LRU_old_len; /* length of the LRU list from ulint LRU_old_len; /* length of the LRU list from
@ -1013,8 +1019,8 @@ MEMORY: is not in free list, LRU list, or flush list, nor page
FILE_PAGE: space and offset are defined, is in page hash table FILE_PAGE: space and offset are defined, is in page hash table
if io_fix == BUF_IO_WRITE, if io_fix == BUF_IO_WRITE,
pool: no_flush[block->flush_type] is in reset state, pool: no_flush[block->flush_type] is in reset state,
pool: n_flush[block->flush_type] > 0 pool: n_flush[block->flush_type] > 0
(1) if buf_fix_count == 0, then (1) if buf_fix_count == 0, then
is in LRU list, not in free list is in LRU list, not in free list
is in flush list, is in flush list,
@ -1023,23 +1029,23 @@ FILE_PAGE: space and offset are defined, is in page hash table
if and only if io_fix == BUF_IO_READ if and only if io_fix == BUF_IO_READ
is s-locked, is s-locked,
if and only if io_fix == BUF_IO_WRITE if and only if io_fix == BUF_IO_WRITE
(2) if buf_fix_count > 0, then (2) if buf_fix_count > 0, then
is not in LRU list, not in free list is not in LRU list, not in free list
is in flush list, is in flush list,
if and only if oldest_modification > 0 if and only if oldest_modification > 0
if io_fix == BUF_IO_READ, if io_fix == BUF_IO_READ,
is x-locked is x-locked
if io_fix == BUF_IO_WRITE, if io_fix == BUF_IO_WRITE,
is s-locked is s-locked
State transitions: State transitions:
NOT_USED => READY_FOR_USE NOT_USED => READY_FOR_USE
READY_FOR_USE => MEMORY READY_FOR_USE => MEMORY
READY_FOR_USE => FILE_PAGE READY_FOR_USE => FILE_PAGE
MEMORY => NOT_USED MEMORY => NOT_USED
FILE_PAGE => NOT_USED NOTE: This transition is allowed if and only if FILE_PAGE => NOT_USED NOTE: This transition is allowed if and only if
(1) buf_fix_count == 0, (1) buf_fix_count == 0,
(2) oldest_modification == 0, and (2) oldest_modification == 0, and
(3) io_fix == 0. (3) io_fix == 0.

View File

@ -41,7 +41,7 @@ buf_pool_get_curr_size(void)
/* out: size in bytes */ /* out: size in bytes */
{ {
return((buf_pool->n_frames) * UNIV_PAGE_SIZE); return((buf_pool->n_frames) * UNIV_PAGE_SIZE);
} }
/************************************************************************* /*************************************************************************
Gets the maximum size of buffer buf_pool in bytes. In the case of AWE, the Gets the maximum size of buffer buf_pool in bytes. In the case of AWE, the
@ -53,7 +53,7 @@ buf_pool_get_max_size(void)
/* out: size in bytes */ /* out: size in bytes */
{ {
return((buf_pool->n_frames) * UNIV_PAGE_SIZE); return((buf_pool->n_frames) * UNIV_PAGE_SIZE);
} }
/*********************************************************************** /***********************************************************************
Accessor function for block array. */ Accessor function for block array. */
@ -69,7 +69,7 @@ buf_pool_get_nth_block(
ut_ad(i < buf_pool->max_size); ut_ad(i < buf_pool->max_size);
return(i + buf_pool->blocks); return(i + buf_pool->blocks);
} }
/*********************************************************************** /***********************************************************************
Checks if a pointer points to the block array of the buffer pool (blocks, not Checks if a pointer points to the block array of the buffer pool (blocks, not
@ -82,13 +82,14 @@ buf_pool_is_block(
void* ptr) /* in: pointer to memory */ void* ptr) /* in: pointer to memory */
{ {
if ((buf_pool->blocks <= (buf_block_t*)ptr) if ((buf_pool->blocks <= (buf_block_t*)ptr)
&& ((buf_block_t*)ptr < buf_pool->blocks + buf_pool->max_size)) { && ((buf_block_t*)ptr < buf_pool->blocks
+ buf_pool->max_size)) {
return(TRUE); return(TRUE);
} }
return(FALSE); return(FALSE);
} }
/************************************************************************ /************************************************************************
Gets the smallest oldest_modification lsn for any page in the pool. Returns Gets the smallest oldest_modification lsn for any page in the pool. Returns
@ -102,7 +103,7 @@ buf_pool_get_oldest_modification(void)
{ {
buf_block_t* block; buf_block_t* block;
dulint lsn; dulint lsn;
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
block = UT_LIST_GET_LAST(buf_pool->flush_list); block = UT_LIST_GET_LAST(buf_pool->flush_list);
@ -130,7 +131,7 @@ buf_pool_clock_tic(void)
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(buf_pool->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
buf_pool->ulint_clock++; buf_pool->ulint_clock++;
return(buf_pool->ulint_clock); return(buf_pool->ulint_clock);
@ -148,12 +149,12 @@ buf_block_get_frame(
ut_ad(block); ut_ad(block);
ut_ad(block >= buf_pool->blocks); ut_ad(block >= buf_pool->blocks);
ut_ad(block < buf_pool->blocks + buf_pool->max_size); ut_ad(block < buf_pool->blocks + buf_pool->max_size);
ut_ad(block->state != BUF_BLOCK_NOT_USED); ut_ad(block->state != BUF_BLOCK_NOT_USED);
ut_ad((block->state != BUF_BLOCK_FILE_PAGE) ut_ad((block->state != BUF_BLOCK_FILE_PAGE)
|| (block->buf_fix_count > 0)); || (block->buf_fix_count > 0));
return(block->frame); return(block->frame);
} }
/************************************************************************* /*************************************************************************
Gets the space id of a block. */ Gets the space id of a block. */
@ -169,9 +170,9 @@ buf_block_get_space(
ut_ad(block < buf_pool->blocks + buf_pool->max_size); ut_ad(block < buf_pool->blocks + buf_pool->max_size);
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_ad(block->buf_fix_count > 0); ut_ad(block->buf_fix_count > 0);
return(block->space); return(block->space);
} }
/************************************************************************* /*************************************************************************
Gets the page number of a block. */ Gets the page number of a block. */
@ -187,9 +188,9 @@ buf_block_get_page_no(
ut_ad(block < buf_pool->blocks + buf_pool->max_size); ut_ad(block < buf_pool->blocks + buf_pool->max_size);
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_ad(block->buf_fix_count > 0); ut_ad(block->buf_fix_count > 0);
return(block->offset); return(block->offset);
} }
/*********************************************************************** /***********************************************************************
Gets the block to whose frame the pointer is pointing to. */ Gets the block to whose frame the pointer is pointing to. */
@ -208,9 +209,9 @@ buf_block_align(
frame_zero = buf_pool->frame_zero; frame_zero = buf_pool->frame_zero;
if (UNIV_UNLIKELY((ulint)ptr < (ulint)frame_zero) if (UNIV_UNLIKELY((ulint)ptr < (ulint)frame_zero)
|| UNIV_UNLIKELY((ulint)ptr > (ulint)(buf_pool->high_end))) { || UNIV_UNLIKELY((ulint)ptr > (ulint)(buf_pool->high_end))) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: trying to access a stray pointer %p\n" "InnoDB: Error: trying to access a stray pointer %p\n"
"InnoDB: buf pool start is at %p, end at %p\n" "InnoDB: buf pool start is at %p, end at %p\n"
@ -218,15 +219,15 @@ buf_block_align(
"InnoDB: corruption. If this happens in an InnoDB database recovery,\n" "InnoDB: corruption. If this happens in an InnoDB database recovery,\n"
"InnoDB: you can look from section 6.1 at http://www.innodb.com/ibman.html\n" "InnoDB: you can look from section 6.1 at http://www.innodb.com/ibman.html\n"
"InnoDB: how to force recovery.\n", "InnoDB: how to force recovery.\n",
ptr, frame_zero, ptr, frame_zero,
buf_pool->high_end); buf_pool->high_end);
ut_error; ut_error;
} }
block = *(buf_pool->blocks_of_frames + (((ulint)(ptr - frame_zero)) block = *(buf_pool->blocks_of_frames + (((ulint)(ptr - frame_zero))
>> UNIV_PAGE_SIZE_SHIFT)); >> UNIV_PAGE_SIZE_SHIFT));
return(block); return(block);
} }
/*********************************************************************** /***********************************************************************
Gets the frame the pointer is pointing to. */ Gets the frame the pointer is pointing to. */
@ -244,9 +245,9 @@ buf_frame_align(
frame = ut_align_down(ptr, UNIV_PAGE_SIZE); frame = ut_align_down(ptr, UNIV_PAGE_SIZE);
if (UNIV_UNLIKELY((ulint)frame < (ulint)(buf_pool->frame_zero)) if (UNIV_UNLIKELY((ulint)frame < (ulint)(buf_pool->frame_zero))
|| UNIV_UNLIKELY((ulint)frame >= (ulint)(buf_pool->high_end))) { || UNIV_UNLIKELY((ulint)frame >= (ulint)(buf_pool->high_end))) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: trying to access a stray pointer %p\n" "InnoDB: Error: trying to access a stray pointer %p\n"
"InnoDB: buf pool start is at %p, end at %p\n" "InnoDB: buf pool start is at %p, end at %p\n"
@ -254,7 +255,7 @@ buf_frame_align(
"InnoDB: corruption. If this happens in an InnoDB database recovery,\n" "InnoDB: corruption. If this happens in an InnoDB database recovery,\n"
"InnoDB: you can look from section 6.1 at http://www.innodb.com/ibman.html\n" "InnoDB: you can look from section 6.1 at http://www.innodb.com/ibman.html\n"
"InnoDB: how to force recovery.\n", "InnoDB: how to force recovery.\n",
ptr, buf_pool->frame_zero, ptr, buf_pool->frame_zero,
buf_pool->high_end); buf_pool->high_end);
ut_error; ut_error;
} }
@ -371,7 +372,7 @@ buf_page_address_fold(
ulint offset) /* in: offset of the page within space */ ulint offset) /* in: offset of the page within space */
{ {
return((space << 20) + space + offset); return((space << 20) + space + offset);
} }
/************************************************************************ /************************************************************************
This function is used to get info if there is an io operation This function is used to get info if there is an io operation
@ -411,7 +412,7 @@ buf_frame_get_newest_modification(
{ {
buf_block_t* block; buf_block_t* block;
dulint lsn; dulint lsn;
ut_ad(frame); ut_ad(frame);
block = buf_block_align(frame); block = buf_block_align(frame);
@ -448,7 +449,7 @@ buf_frame_modify_clock_inc(
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0)) ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0))
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
#endif /*UNIV_SYNC_DEBUG */ #endif /*UNIV_SYNC_DEBUG */
UT_DULINT_INC(block->modify_clock); UT_DULINT_INC(block->modify_clock);
@ -469,7 +470,7 @@ buf_block_modify_clock_inc(
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0)) ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0))
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
UT_DULINT_INC(block->modify_clock); UT_DULINT_INC(block->modify_clock);
@ -478,7 +479,7 @@ buf_block_modify_clock_inc(
} }
/************************************************************************ /************************************************************************
Returns the value of the modify clock. The caller must have an s-lock Returns the value of the modify clock. The caller must have an s-lock
or x-lock on the block. */ or x-lock on the block. */
UNIV_INLINE UNIV_INLINE
dulint dulint
@ -489,7 +490,7 @@ buf_block_get_modify_clock(
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED) ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
return(block->modify_clock); return(block->modify_clock);
@ -506,7 +507,7 @@ buf_block_buf_fix_inc_debug(
const char* file __attribute__ ((unused)), /* in: file name */ const char* file __attribute__ ((unused)), /* in: file name */
ulint line __attribute__ ((unused))) /* in: line */ ulint line __attribute__ ((unused))) /* in: line */
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ibool ret; ibool ret;
ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line); ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line);
@ -539,7 +540,7 @@ buf_page_hash_get(
{ {
buf_block_t* block; buf_block_t* block;
ulint fold; ulint fold;
ut_ad(buf_pool); ut_ad(buf_pool);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(buf_pool->mutex)));
@ -552,7 +553,7 @@ buf_page_hash_get(
HASH_SEARCH(hash, buf_pool->page_hash, fold, block, HASH_SEARCH(hash, buf_pool->page_hash, fold, block,
(block->space == space) && (block->offset == offset)); (block->space == space) && (block->offset == offset));
ut_a(block == NULL || block->state == BUF_BLOCK_FILE_PAGE); ut_a(block == NULL || block->state == BUF_BLOCK_FILE_PAGE);
return(block); return(block);
} }
@ -589,16 +590,16 @@ buf_page_get_release_on_io(
/* The page was not in the buffer buf_pool: release the latches /* The page was not in the buffer buf_pool: release the latches
down to the savepoint */ down to the savepoint */
mtr_rollback_to_savepoint(mtr, savepoint); mtr_rollback_to_savepoint(mtr, savepoint);
buf_page_get(space, offset, RW_S_LATCH, mtr); buf_page_get(space, offset, RW_S_LATCH, mtr);
/* When we get here, the page is in buffer, but we release /* When we get here, the page is in buffer, but we release
the latches again down to the savepoint, before returning */ the latches again down to the savepoint, before returning */
mtr_rollback_to_savepoint(mtr, savepoint); mtr_rollback_to_savepoint(mtr, savepoint);
return(NULL); return(NULL);
} }
@ -615,7 +616,7 @@ buf_page_release(
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
ulint buf_fix_count; ulint buf_fix_count;
ut_ad(block); ut_ad(block);
mutex_enter_fast(&(buf_pool->mutex)); mutex_enter_fast(&(buf_pool->mutex));
@ -654,9 +655,9 @@ void
buf_page_dbg_add_level( buf_page_dbg_add_level(
/*===================*/ /*===================*/
buf_frame_t* frame __attribute__((unused)), /* in: buffer page buf_frame_t* frame __attribute__((unused)), /* in: buffer page
where we have acquired latch */ where we have acquired latch */
ulint level __attribute__((unused))) /* in: latching order ulint level __attribute__((unused))) /* in: latching order
level */ level */
{ {
sync_thread_add_level(&(buf_block_align(frame)->lock), level); sync_thread_add_level(&(buf_block_align(frame)->lock), level);
} }

View File

@ -110,11 +110,11 @@ available to replacement in the free list and at the end of the LRU list (to
make sure that a read-ahead batch can be read efficiently in a single make sure that a read-ahead batch can be read efficiently in a single
sweep). */ sweep). */
#define BUF_FLUSH_FREE_BLOCK_MARGIN (5 + BUF_READ_AHEAD_AREA) #define BUF_FLUSH_FREE_BLOCK_MARGIN (5 + BUF_READ_AHEAD_AREA)
#define BUF_FLUSH_EXTRA_MARGIN (BUF_FLUSH_FREE_BLOCK_MARGIN / 4 + 100) #define BUF_FLUSH_EXTRA_MARGIN (BUF_FLUSH_FREE_BLOCK_MARGIN / 4 + 100)
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "buf0flu.ic" #include "buf0flu.ic"
#endif #endif
#endif #endif

View File

@ -48,11 +48,11 @@ buf_flush_note_modification(
ut_ad(ut_dulint_cmp(mtr->start_lsn, ut_dulint_zero) != 0); ut_ad(ut_dulint_cmp(mtr->start_lsn, ut_dulint_zero) != 0);
ut_ad(mtr->modifications); ut_ad(mtr->modifications);
ut_ad(ut_dulint_cmp(block->newest_modification, mtr->end_lsn) <= 0); ut_ad(ut_dulint_cmp(block->newest_modification, mtr->end_lsn) <= 0);
block->newest_modification = mtr->end_lsn; block->newest_modification = mtr->end_lsn;
if (ut_dulint_is_zero(block->oldest_modification)) { if (ut_dulint_is_zero(block->oldest_modification)) {
block->oldest_modification = mtr->start_lsn; block->oldest_modification = mtr->start_lsn;
ut_ad(!ut_dulint_is_zero(block->oldest_modification)); ut_ad(!ut_dulint_is_zero(block->oldest_modification));
@ -62,7 +62,7 @@ buf_flush_note_modification(
mtr->start_lsn) <= 0); mtr->start_lsn) <= 0);
} }
++srv_buf_pool_write_requests; ++srv_buf_pool_write_requests;
} }
/************************************************************************ /************************************************************************
@ -85,13 +85,13 @@ buf_flush_recv_note_modification(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
ut_ad(ut_dulint_cmp(block->newest_modification, end_lsn) <= 0); ut_ad(ut_dulint_cmp(block->newest_modification, end_lsn) <= 0);
block->newest_modification = end_lsn; block->newest_modification = end_lsn;
if (ut_dulint_is_zero(block->oldest_modification)) { if (ut_dulint_is_zero(block->oldest_modification)) {
block->oldest_modification = start_lsn; block->oldest_modification = start_lsn;
ut_ad(!ut_dulint_is_zero(block->oldest_modification)); ut_ad(!ut_dulint_is_zero(block->oldest_modification));

View File

@ -73,7 +73,7 @@ ibool
buf_LRU_search_and_free_block( buf_LRU_search_and_free_block(
/*==========================*/ /*==========================*/
/* out: TRUE if freed */ /* out: TRUE if freed */
ulint n_iterations); /* in: how many times this has been called ulint n_iterations); /* in: how many times this has been called
repeatedly without result: a high value means repeatedly without result: a high value means
that we should search farther; if value is that we should search farther; if value is
k < 10, then we only search k/10 * number k < 10, then we only search k/10 * number

View File

@ -19,23 +19,23 @@ Created 5/30/1994 Heikki Tuuri
typedef struct big_rec_struct big_rec_t; typedef struct big_rec_struct big_rec_t;
/* Some non-inlined functions used in the MySQL interface: */ /* Some non-inlined functions used in the MySQL interface: */
void void
dfield_set_data_noninline( dfield_set_data_noninline(
dfield_t* field, /* in: field */ dfield_t* field, /* in: field */
void* data, /* in: data */ void* data, /* in: data */
ulint len); /* in: length or UNIV_SQL_NULL */ ulint len); /* in: length or UNIV_SQL_NULL */
void* void*
dfield_get_data_noninline( dfield_get_data_noninline(
dfield_t* field); /* in: field */ dfield_t* field); /* in: field */
ulint ulint
dfield_get_len_noninline( dfield_get_len_noninline(
dfield_t* field); /* in: field */ dfield_t* field); /* in: field */
ulint ulint
dtuple_get_n_fields_noninline( dtuple_get_n_fields_noninline(
dtuple_t* tuple); /* in: tuple */ dtuple_t* tuple); /* in: tuple */
dfield_t* dfield_t*
dtuple_get_nth_field_noninline( dtuple_get_nth_field_noninline(
dtuple_t* tuple, /* in: tuple */ dtuple_t* tuple, /* in: tuple */
ulint n); /* in: index of field */ ulint n); /* in: index of field */
/************************************************************************* /*************************************************************************
@ -57,7 +57,7 @@ dfield_set_type(
/************************************************************************* /*************************************************************************
Gets pointer to the data in a field. */ Gets pointer to the data in a field. */
UNIV_INLINE UNIV_INLINE
void* void*
dfield_get_data( dfield_get_data(
/*============*/ /*============*/
/* out: pointer to data */ /* out: pointer to data */
@ -68,24 +68,24 @@ UNIV_INLINE
ulint ulint
dfield_get_len( dfield_get_len(
/*===========*/ /*===========*/
/* out: length of data; UNIV_SQL_NULL if /* out: length of data; UNIV_SQL_NULL if
SQL null data */ SQL null data */
dfield_t* field); /* in: field */ dfield_t* field); /* in: field */
/************************************************************************* /*************************************************************************
Sets length in a field. */ Sets length in a field. */
UNIV_INLINE UNIV_INLINE
void void
dfield_set_len( dfield_set_len(
/*===========*/ /*===========*/
dfield_t* field, /* in: field */ dfield_t* field, /* in: field */
ulint len); /* in: length or UNIV_SQL_NULL */ ulint len); /* in: length or UNIV_SQL_NULL */
/************************************************************************* /*************************************************************************
Sets pointer to the data and length in a field. */ Sets pointer to the data and length in a field. */
UNIV_INLINE UNIV_INLINE
void void
dfield_set_data( dfield_set_data(
/*============*/ /*============*/
dfield_t* field, /* in: field */ dfield_t* field, /* in: field */
const void* data, /* in: data */ const void* data, /* in: data */
ulint len); /* in: length or UNIV_SQL_NULL */ ulint len); /* in: length or UNIV_SQL_NULL */
/************************************************************************** /**************************************************************************
@ -99,10 +99,10 @@ data_write_sql_null(
/************************************************************************* /*************************************************************************
Copies the data and len fields. */ Copies the data and len fields. */
UNIV_INLINE UNIV_INLINE
void void
dfield_copy_data( dfield_copy_data(
/*=============*/ /*=============*/
dfield_t* field1, /* in: field to copy to */ dfield_t* field1, /* in: field to copy to */
dfield_t* field2);/* in: field to copy from */ dfield_t* field2);/* in: field to copy from */
/************************************************************************* /*************************************************************************
Copies a data field to another. */ Copies a data field to another. */
@ -134,19 +134,19 @@ dfield_data_is_binary_equal(
/************************************************************************* /*************************************************************************
Gets number of fields in a data tuple. */ Gets number of fields in a data tuple. */
UNIV_INLINE UNIV_INLINE
ulint ulint
dtuple_get_n_fields( dtuple_get_n_fields(
/*================*/ /*================*/
/* out: number of fields */ /* out: number of fields */
dtuple_t* tuple); /* in: tuple */ dtuple_t* tuple); /* in: tuple */
/************************************************************************* /*************************************************************************
Gets nth field of a tuple. */ Gets nth field of a tuple. */
UNIV_INLINE UNIV_INLINE
dfield_t* dfield_t*
dtuple_get_nth_field( dtuple_get_nth_field(
/*=================*/ /*=================*/
/* out: nth field */ /* out: nth field */
dtuple_t* tuple, /* in: tuple */ dtuple_t* tuple, /* in: tuple */
ulint n); /* in: index of field */ ulint n); /* in: index of field */
/************************************************************************* /*************************************************************************
Gets info bits in a data tuple. */ Gets info bits in a data tuple. */
@ -155,14 +155,14 @@ ulint
dtuple_get_info_bits( dtuple_get_info_bits(
/*=================*/ /*=================*/
/* out: info bits */ /* out: info bits */
dtuple_t* tuple); /* in: tuple */ dtuple_t* tuple); /* in: tuple */
/************************************************************************* /*************************************************************************
Sets info bits in a data tuple. */ Sets info bits in a data tuple. */
UNIV_INLINE UNIV_INLINE
void void
dtuple_set_info_bits( dtuple_set_info_bits(
/*=================*/ /*=================*/
dtuple_t* tuple, /* in: tuple */ dtuple_t* tuple, /* in: tuple */
ulint info_bits); /* in: info bits */ ulint info_bits); /* in: info bits */
/************************************************************************* /*************************************************************************
Gets number of fields used in record comparisons. */ Gets number of fields used in record comparisons. */
@ -189,10 +189,10 @@ UNIV_INLINE
dtuple_t* dtuple_t*
dtuple_create( dtuple_create(
/*==========*/ /*==========*/
/* out, own: created tuple */ /* out, own: created tuple */
mem_heap_t* heap, /* in: memory heap where the tuple mem_heap_t* heap, /* in: memory heap where the tuple
is created */ is created */
ulint n_fields); /* in: number of fields */ ulint n_fields); /* in: number of fields */
/************************************************************************* /*************************************************************************
Creates a dtuple for use in MySQL. */ Creates a dtuple for use in MySQL. */
@ -201,7 +201,7 @@ dtuple_t*
dtuple_create_for_mysql( dtuple_create_for_mysql(
/*====================*/ /*====================*/
/* out, own created dtuple */ /* out, own created dtuple */
void** heap, /* out: created memory heap */ void** heap, /* out: created memory heap */
ulint n_fields); /* in: number of fields */ ulint n_fields); /* in: number of fields */
/************************************************************************* /*************************************************************************
Frees a dtuple used in MySQL. */ Frees a dtuple used in MySQL. */
@ -212,7 +212,7 @@ dtuple_free_for_mysql(
void* heap); void* heap);
/************************************************************************* /*************************************************************************
Sets number of fields used in a tuple. Normally this is set in Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */ dtuple_create, but if you want later to set it smaller, you can use this. */
void void
dtuple_set_n_fields( dtuple_set_n_fields(
@ -314,12 +314,20 @@ dfield_print(
dfield_t* dfield);/* in: dfield */ dfield_t* dfield);/* in: dfield */
/***************************************************************** /*****************************************************************
Pretty prints a dfield value according to its data type. Also the hex string Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */ is printed if a string contains non-printable characters. */
void void
dfield_print_also_hex( dfield_print_also_hex(
/*==================*/ /*==================*/
dfield_t* dfield); /* in: dfield */ dfield_t* dfield); /* in: dfield */
/*****************************************************************
Print a dfield value using ut_print_buf. */
void
dfield_print_raw(
/*=============*/
FILE* f, /* in: output stream */
dfield_t* dfield); /* in: dfield */
/************************************************************** /**************************************************************
The following function prints the contents of a tuple. */ The following function prints the contents of a tuple. */
@ -395,13 +403,13 @@ struct dtuple_struct {
UT_LIST_NODE_T(dtuple_t) tuple_list; UT_LIST_NODE_T(dtuple_t) tuple_list;
/* data tuples can be linked into a /* data tuples can be linked into a
list using this field */ list using this field */
ulint magic_n; ulint magic_n;
}; };
#define DATA_TUPLE_MAGIC_N 65478679 #define DATA_TUPLE_MAGIC_N 65478679
/* A slot for a field in a big rec vector */ /* A slot for a field in a big rec vector */
typedef struct big_rec_field_struct big_rec_field_t; typedef struct big_rec_field_struct big_rec_field_t;
struct big_rec_field_struct { struct big_rec_field_struct {
ulint field_no; /* field number in record */ ulint field_no; /* field number in record */
ulint len; /* stored data len */ ulint len; /* stored data len */
@ -416,7 +424,7 @@ struct big_rec_struct {
ulint n_fields; /* number of stored fields */ ulint n_fields; /* number of stored fields */
big_rec_field_t* fields; /* stored fields */ big_rec_field_t* fields; /* stored fields */
}; };
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "data0data.ic" #include "data0data.ic"
#endif #endif

View File

@ -9,7 +9,9 @@ Created 5/30/1994 Heikki Tuuri
#include "mem0mem.h" #include "mem0mem.h"
#include "ut0rnd.h" #include "ut0rnd.h"
#ifdef UNIV_DEBUG
extern byte data_error; extern byte data_error;
#endif /* UNIV_DEBUG */
/************************************************************************* /*************************************************************************
Gets pointer to the type struct of SQL data field. */ Gets pointer to the type struct of SQL data field. */
@ -42,7 +44,7 @@ dfield_set_type(
/************************************************************************* /*************************************************************************
Gets pointer to the data in a field. */ Gets pointer to the data in a field. */
UNIV_INLINE UNIV_INLINE
void* void*
dfield_get_data( dfield_get_data(
/*============*/ /*============*/
/* out: pointer to data */ /* out: pointer to data */
@ -50,7 +52,7 @@ dfield_get_data(
{ {
ut_ad(field); ut_ad(field);
ut_ad((field->len == UNIV_SQL_NULL) ut_ad((field->len == UNIV_SQL_NULL)
|| (field->data != &data_error)); || (field->data != &data_error));
return(field->data); return(field->data);
} }
@ -61,13 +63,13 @@ UNIV_INLINE
ulint ulint
dfield_get_len( dfield_get_len(
/*===========*/ /*===========*/
/* out: length of data; UNIV_SQL_NULL if /* out: length of data; UNIV_SQL_NULL if
SQL null data */ SQL null data */
dfield_t* field) /* in: field */ dfield_t* field) /* in: field */
{ {
ut_ad(field); ut_ad(field);
ut_ad((field->len == UNIV_SQL_NULL) ut_ad((field->len == UNIV_SQL_NULL)
|| (field->data != &data_error)); || (field->data != &data_error));
return(field->len); return(field->len);
} }
@ -75,10 +77,10 @@ dfield_get_len(
/************************************************************************* /*************************************************************************
Sets length in a field. */ Sets length in a field. */
UNIV_INLINE UNIV_INLINE
void void
dfield_set_len( dfield_set_len(
/*===========*/ /*===========*/
dfield_t* field, /* in: field */ dfield_t* field, /* in: field */
ulint len) /* in: length or UNIV_SQL_NULL */ ulint len) /* in: length or UNIV_SQL_NULL */
{ {
ut_ad(field); ut_ad(field);
@ -89,10 +91,10 @@ dfield_set_len(
/************************************************************************* /*************************************************************************
Sets pointer to the data and length in a field. */ Sets pointer to the data and length in a field. */
UNIV_INLINE UNIV_INLINE
void void
dfield_set_data( dfield_set_data(
/*============*/ /*============*/
dfield_t* field, /* in: field */ dfield_t* field, /* in: field */
const void* data, /* in: data */ const void* data, /* in: data */
ulint len) /* in: length or UNIV_SQL_NULL */ ulint len) /* in: length or UNIV_SQL_NULL */
{ {
@ -105,10 +107,10 @@ dfield_set_data(
/************************************************************************* /*************************************************************************
Copies the data and len fields. */ Copies the data and len fields. */
UNIV_INLINE UNIV_INLINE
void void
dfield_copy_data( dfield_copy_data(
/*=============*/ /*=============*/
dfield_t* field1, /* in: field to copy to */ dfield_t* field1, /* in: field to copy to */
dfield_t* field2) /* in: field to copy from */ dfield_t* field2) /* in: field to copy from */
{ {
ut_ad(field1 && field2); ut_ad(field1 && field2);
@ -142,11 +144,12 @@ dfield_datas_are_binary_equal(
ulint len; ulint len;
len = field1->len; len = field1->len;
if ((len != field2->len) if ((len != field2->len)
|| ((len != UNIV_SQL_NULL) || ((len != UNIV_SQL_NULL)
&& (0 != ut_memcmp(field1->data, field2->data, len)))) { && (0 != ut_memcmp(field1->data, field2->data,
len)))) {
return(FALSE); return(FALSE);
} }
@ -160,7 +163,7 @@ ulint
dtuple_get_info_bits( dtuple_get_info_bits(
/*=================*/ /*=================*/
/* out: info bits */ /* out: info bits */
dtuple_t* tuple) /* in: tuple */ dtuple_t* tuple) /* in: tuple */
{ {
ut_ad(tuple); ut_ad(tuple);
@ -173,7 +176,7 @@ UNIV_INLINE
void void
dtuple_set_info_bits( dtuple_set_info_bits(
/*=================*/ /*=================*/
dtuple_t* tuple, /* in: tuple */ dtuple_t* tuple, /* in: tuple */
ulint info_bits) /* in: info bits */ ulint info_bits) /* in: info bits */
{ {
ut_ad(tuple); ut_ad(tuple);
@ -219,7 +222,7 @@ ulint
dtuple_get_n_fields( dtuple_get_n_fields(
/*================*/ /*================*/
/* out: number of fields */ /* out: number of fields */
dtuple_t* tuple) /* in: tuple */ dtuple_t* tuple) /* in: tuple */
{ {
ut_ad(tuple); ut_ad(tuple);
@ -229,11 +232,11 @@ dtuple_get_n_fields(
/************************************************************************* /*************************************************************************
Gets nth field of a tuple. */ Gets nth field of a tuple. */
UNIV_INLINE UNIV_INLINE
dfield_t* dfield_t*
dtuple_get_nth_field( dtuple_get_nth_field(
/*=================*/ /*=================*/
/* out: nth field */ /* out: nth field */
dtuple_t* tuple, /* in: tuple */ dtuple_t* tuple, /* in: tuple */
ulint n) /* in: index of field */ ulint n) /* in: index of field */
{ {
ut_ad(tuple); ut_ad(tuple);
@ -249,17 +252,17 @@ UNIV_INLINE
dtuple_t* dtuple_t*
dtuple_create( dtuple_create(
/*==========*/ /*==========*/
/* out, own: created tuple */ /* out, own: created tuple */
mem_heap_t* heap, /* in: memory heap where the tuple mem_heap_t* heap, /* in: memory heap where the tuple
is created */ is created */
ulint n_fields) /* in: number of fields */ ulint n_fields) /* in: number of fields */
{ {
dtuple_t* tuple; dtuple_t* tuple;
ut_ad(heap); ut_ad(heap);
tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t) tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t)
+ n_fields * sizeof(dfield_t)); + n_fields * sizeof(dfield_t));
tuple->info_bits = 0; tuple->info_bits = 0;
tuple->n_fields = n_fields; tuple->n_fields = n_fields;
tuple->n_fields_cmp = n_fields; tuple->n_fields_cmp = n_fields;
@ -270,14 +273,14 @@ dtuple_create(
{ /* In the debug version, initialize fields to an error value */ { /* In the debug version, initialize fields to an error value */
ulint i; ulint i;
for (i = 0; i < n_fields; i++) { for (i = 0; i < n_fields; i++) {
(tuple->fields + i)->data = &data_error; (tuple->fields + i)->data = &data_error;
dfield_get_type(tuple->fields + i)->mtype = DATA_ERROR; dfield_get_type(tuple->fields + i)->mtype = DATA_ERROR;
} }
} }
#endif #endif
return(tuple); return(tuple);
} }
/************************************************************** /**************************************************************
@ -292,10 +295,10 @@ dtuple_get_data_size(
dtuple_t* tuple) /* in: typed data tuple */ dtuple_t* tuple) /* in: typed data tuple */
{ {
dfield_t* field; dfield_t* field;
ulint n_fields; ulint n_fields;
ulint len; ulint len;
ulint i; ulint i;
ulint sum = 0; ulint sum = 0;
ut_ad(tuple); ut_ad(tuple);
ut_ad(dtuple_check_typed(tuple)); ut_ad(dtuple_check_typed(tuple));
@ -313,7 +316,7 @@ dtuple_get_data_size(
sum += len; sum += len;
} }
return(sum); return(sum);
} }
@ -328,7 +331,7 @@ dtuple_set_types_binary(
{ {
dtype_t* dfield_type; dtype_t* dfield_type;
ulint i; ulint i;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i)); dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
dtype_set(dfield_type, DATA_BINARY, 0, 0, 0); dtype_set(dfield_type, DATA_BINARY, 0, 0, 0);
@ -364,10 +367,10 @@ dtuple_fold(
field = dtuple_get_nth_field(tuple, i); field = dtuple_get_nth_field(tuple, i);
data = (byte*) dfield_get_data(field); data = (byte*) dfield_get_data(field);
len = dfield_get_len(field); len = dfield_get_len(field);
if (len != UNIV_SQL_NULL) { if (len != UNIV_SQL_NULL) {
fold = ut_fold_ulint_pair(fold, fold = ut_fold_ulint_pair(fold,
ut_fold_binary(data, len)); ut_fold_binary(data, len));
} }
} }
@ -376,17 +379,17 @@ dtuple_fold(
field = dtuple_get_nth_field(tuple, i); field = dtuple_get_nth_field(tuple, i);
data = (byte*) dfield_get_data(field); data = (byte*) dfield_get_data(field);
len = dfield_get_len(field); len = dfield_get_len(field);
if (len != UNIV_SQL_NULL) { if (len != UNIV_SQL_NULL) {
if (len > n_bytes) { if (len > n_bytes) {
len = n_bytes; len = n_bytes;
} }
fold = ut_fold_ulint_pair(fold, fold = ut_fold_ulint_pair(fold,
ut_fold_binary(data, len)); ut_fold_binary(data, len));
} }
} }
return(fold); return(fold);
} }
@ -423,7 +426,7 @@ dtuple_contains_null(
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (dfield_get_len(dtuple_get_nth_field(tuple, i)) if (dfield_get_len(dtuple_get_nth_field(tuple, i))
== UNIV_SQL_NULL) { == UNIV_SQL_NULL) {
return(TRUE); return(TRUE);
} }

View File

@ -13,13 +13,14 @@ Created 1/16/1996 Heikki Tuuri
extern ulint data_mysql_default_charset_coll; extern ulint data_mysql_default_charset_coll;
#define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8 #define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8
#define DATA_MYSQL_BINARY_CHARSET_COLL 63
/* SQL data type struct */ /* SQL data type struct */
typedef struct dtype_struct dtype_t; typedef struct dtype_struct dtype_t;
/* This variable is initialized as the standard binary variable length /* This variable is initialized as the standard binary variable length
data type */ data type */
extern dtype_t* dtype_binary; extern dtype_t* dtype_binary;
/*-------------------------------------------*/ /*-------------------------------------------*/
/* The 'MAIN TYPE' of a column */ /* The 'MAIN TYPE' of a column */
@ -101,7 +102,7 @@ InnoDB's own internal system tables have different precise types for their
columns, and for them the precise type is usually not used at all. columns, and for them the precise type is usually not used at all.
*/ */
#define DATA_ENGLISH 4 /* English language character string: this #define DATA_ENGLISH 4 /* English language character string: this
is a relic from pre-MySQL time and only used is a relic from pre-MySQL time and only used
for InnoDB's own system tables */ for InnoDB's own system tables */
#define DATA_ERROR 111 /* another relic from pre-MySQL time */ #define DATA_ERROR 111 /* another relic from pre-MySQL time */
@ -127,7 +128,7 @@ be less than 256 */
a row in a compressed form */ a row in a compressed form */
#define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a #define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a
compressed dulint form) */ compressed dulint form) */
#define DATA_N_SYS_COLS 4 /* number of system columns defined above */ #define DATA_N_SYS_COLS 4 /* number of system columns defined above */
/* Flags ORed to the precise data type */ /* Flags ORed to the precise data type */
#define DATA_NOT_NULL 256 /* this is ORed to the precise type when #define DATA_NOT_NULL 256 /* this is ORed to the precise type when
@ -311,7 +312,7 @@ dtype_get_pad_char(
/*===============*/ /*===============*/
/* out: padding character code, or /* out: padding character code, or
ULINT_UNDEFINED if no padding specified */ ULINT_UNDEFINED if no padding specified */
dtype_t* type); /* in: type */ const dtype_t* type); /* in: type */
/*************************************************************************** /***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */ Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE UNIV_INLINE

View File

@ -8,6 +8,7 @@ Created 1/16/1996 Heikki Tuuri
#include "mach0data.h" #include "mach0data.h"
#ifndef UNIV_HOTBACKUP
/********************************************************************** /**********************************************************************
Get the variable length bounds of the given character set. Get the variable length bounds of the given character set.
@ -20,6 +21,7 @@ innobase_get_cset_width(
ulint cset, /* in: MySQL charset-collation code */ ulint cset, /* in: MySQL charset-collation code */
ulint* mbminlen, /* out: minimum length of a char (in bytes) */ ulint* mbminlen, /* out: minimum length of a char (in bytes) */
ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */ ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */
#endif /* !UNIV_HOTBACKUP */
/************************************************************************* /*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */ Gets the MySQL charset-collation code for MySQL string types. */
@ -55,9 +57,21 @@ dtype_set_mblen(
{ {
ut_ad(type); ut_ad(type);
if (dtype_is_string_type(type->mtype)) { if (dtype_is_string_type(type->mtype)) {
#ifndef UNIV_HOTBACKUP
innobase_get_cset_width(dtype_get_charset_coll(type->prtype), innobase_get_cset_width(dtype_get_charset_coll(type->prtype),
&type->mbminlen, &type->mbmaxlen); &type->mbminlen, &type->mbmaxlen);
ut_ad(type->mbminlen <= type->mbmaxlen); ut_ad(type->mbminlen <= type->mbmaxlen);
#else /* !UNIV_HOTBACKUP */
#ifdef notdefined
printf("ibbackup: DEBUG: type->mtype=%lu, type->prtype=%lu\n",
type->mtype, type->prtype);
#endif
ut_a(type->mtype <= DATA_BINARY);
#ifdef notdefined
ut_a(type->prtype == (DATA_BINARY | DATA_NOT_NULL));
#endif
type->mbminlen = type->mbmaxlen = 1;
#endif /* !UNIV_HOTBACKUP */
} else { } else {
type->mbminlen = type->mbmaxlen = 0; type->mbminlen = type->mbmaxlen = 0;
} }
@ -77,7 +91,7 @@ dtype_set(
{ {
ut_ad(type); ut_ad(type);
ut_ad(mtype <= DATA_MTYPE_MAX); ut_ad(mtype <= DATA_MTYPE_MAX);
type->mtype = mtype; type->mtype = mtype;
type->prtype = prtype; type->prtype = prtype;
type->len = len; type->len = len;
@ -188,26 +202,35 @@ dtype_get_pad_char(
/*===============*/ /*===============*/
/* out: padding character code, or /* out: padding character code, or
ULINT_UNDEFINED if no padding specified */ ULINT_UNDEFINED if no padding specified */
dtype_t* type) /* in: type */ const dtype_t* type) /* in: type */
{ {
if (type->mtype == DATA_CHAR switch (type->mtype) {
|| type->mtype == DATA_VARCHAR case DATA_FIXBINARY:
|| type->mtype == DATA_BINARY case DATA_BINARY:
|| type->mtype == DATA_FIXBINARY if (UNIV_UNLIKELY(dtype_get_charset_coll(type->prtype)
|| type->mtype == DATA_MYSQL == DATA_MYSQL_BINARY_CHARSET_COLL)) {
|| type->mtype == DATA_VARMYSQL /* Starting from 5.0.18, do not pad
|| (type->mtype == DATA_BLOB VARBINARY or BINARY columns. */
&& (type->prtype & DATA_BINARY_TYPE) == 0)) { return(ULINT_UNDEFINED);
}
/* Fall through */
case DATA_CHAR:
case DATA_VARCHAR:
case DATA_MYSQL:
case DATA_VARMYSQL:
/* Space is the padding character for all char and binary /* Space is the padding character for all char and binary
strings, and starting from 5.0.3, also for TEXT strings. */ strings, and starting from 5.0.3, also for TEXT strings. */
return((ulint)' '); return(0x20);
case DATA_BLOB:
if ((type->prtype & DATA_BINARY_TYPE) == 0) {
return(0x20);
}
/* Fall through */
default:
/* No padding specified */
return(ULINT_UNDEFINED);
} }
/* No padding specified */
return(ULINT_UNDEFINED);
} }
/************************************************************************** /**************************************************************************
@ -233,7 +256,7 @@ dtype_new_store_for_order_and_null_size(
buf[0] = buf[0] | 128; buf[0] = buf[0] | 128;
} }
/* In versions < 4.1.2 we had: if (type->prtype & DATA_NONLATIN1) { /* In versions < 4.1.2 we had: if (type->prtype & DATA_NONLATIN1) {
buf[0] = buf[0] | 64; buf[0] = buf[0] | 64;
} }
*/ */
@ -262,20 +285,20 @@ dtype_read_for_order_and_null_size(
byte* buf) /* in: buffer for stored type order info */ byte* buf) /* in: buffer for stored type order info */
{ {
ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE); ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE);
type->mtype = buf[0] & 63; type->mtype = buf[0] & 63;
type->prtype = buf[1]; type->prtype = buf[1];
if (buf[0] & 128) { if (buf[0] & 128) {
type->prtype = type->prtype | DATA_BINARY_TYPE; type->prtype = type->prtype | DATA_BINARY_TYPE;
} }
type->len = mach_read_from_2(buf + 2); type->len = mach_read_from_2(buf + 2);
type->prtype = dtype_form_prtype(type->prtype, type->prtype = dtype_form_prtype(type->prtype,
data_mysql_default_charset_coll); data_mysql_default_charset_coll);
dtype_set_mblen(type); dtype_set_mblen(type);
} }
/************************************************************************** /**************************************************************************
Reads to a type the stored information which determines its alphabetical Reads to a type the stored information which determines its alphabetical
@ -293,7 +316,7 @@ dtype_new_read_for_order_and_null_size(
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE #if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE" #error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
#endif #endif
type->mtype = buf[0] & 63; type->mtype = buf[0] & 63;
type->prtype = buf[1]; type->prtype = buf[1];
@ -323,13 +346,12 @@ dtype_new_read_for_order_and_null_size(
charset_coll = data_mysql_default_charset_coll; charset_coll = data_mysql_default_charset_coll;
} }
type->prtype = dtype_form_prtype(type->prtype, charset_coll); type->prtype = dtype_form_prtype(type->prtype, charset_coll);
} }
dtype_set_mblen(type); dtype_set_mblen(type);
} }
#ifndef UNIV_HOTBACKUP
/*************************************************************************** /***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */ Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE UNIV_INLINE
@ -374,8 +396,13 @@ dtype_get_fixed_size(
if (type->prtype & DATA_BINARY_TYPE) { if (type->prtype & DATA_BINARY_TYPE) {
return(dtype_get_len(type)); return(dtype_get_len(type));
} else { } else {
#ifdef UNIV_HOTBACKUP
if (type->mbminlen == type->mbmaxlen) {
return(dtype_get_len(type));
}
#else /* UNIV_HOTBACKUP */
/* We play it safe here and ask MySQL for /* We play it safe here and ask MySQL for
mbminlen and mbmaxlen. Although mbminlen and mbmaxlen. Although
type->mbminlen and type->mbmaxlen are type->mbminlen and type->mbmaxlen are
initialized if and only if type->prtype initialized if and only if type->prtype
is (in one of the 3 functions in this file), is (in one of the 3 functions in this file),
@ -405,6 +432,7 @@ dtype_get_fixed_size(
if (mbminlen == mbmaxlen) { if (mbminlen == mbmaxlen) {
return(dtype_get_len(type)); return(dtype_get_len(type));
} }
#endif /* !UNIV_HOTBACKUP */
} }
/* fall through for variable-length charsets */ /* fall through for variable-length charsets */
case DATA_VARCHAR: case DATA_VARCHAR:
@ -412,7 +440,7 @@ dtype_get_fixed_size(
case DATA_DECIMAL: case DATA_DECIMAL:
case DATA_VARMYSQL: case DATA_VARMYSQL:
case DATA_BLOB: case DATA_BLOB:
return(0); return(0);
default: ut_error; default: ut_error;
} }
@ -470,13 +498,12 @@ dtype_get_min_size(
case DATA_DECIMAL: case DATA_DECIMAL:
case DATA_VARMYSQL: case DATA_VARMYSQL:
case DATA_BLOB: case DATA_BLOB:
return(0); return(0);
default: ut_error; default: ut_error;
} }
return(0); return(0);
} }
#endif /* !UNIV_HOTBACKUP */
/*************************************************************************** /***************************************************************************
Returns a stored SQL NULL size for a type. For fixed length types it is Returns a stored SQL NULL size for a type. For fixed length types it is

View File

@ -42,14 +42,14 @@ Created 5/24/1996 Heikki Tuuri
#define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint #define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint
to a table failed */ to a table failed */
#define DB_CORRUPTION 39 /* data structure corruption noticed */ #define DB_CORRUPTION 39 /* data structure corruption noticed */
#define DB_COL_APPEARS_TWICE_IN_INDEX 40 /* InnoDB cannot handle an index #define DB_COL_APPEARS_TWICE_IN_INDEX 40/* InnoDB cannot handle an index
where same column appears twice */ where same column appears twice */
#define DB_CANNOT_DROP_CONSTRAINT 41 /* dropping a foreign key constraint #define DB_CANNOT_DROP_CONSTRAINT 41 /* dropping a foreign key constraint
from a table failed */ from a table failed */
#define DB_NO_SAVEPOINT 42 /* no savepoint exists with the given #define DB_NO_SAVEPOINT 42 /* no savepoint exists with the given
name */ name */
#define DB_TABLESPACE_ALREADY_EXISTS 43 /* we cannot create a new single-table #define DB_TABLESPACE_ALREADY_EXISTS 43 /* we cannot create a new single-table
tablespace because a file of the same tablespace because a file of the same
name already exists */ name already exists */
#define DB_TABLESPACE_DELETED 44 /* tablespace does not exist or is #define DB_TABLESPACE_DELETED 44 /* tablespace does not exist or is
being dropped right now */ being dropped right now */
@ -63,11 +63,11 @@ Created 5/24/1996 Heikki Tuuri
table */ table */
/* The following are partial failure codes */ /* The following are partial failure codes */
#define DB_FAIL 1000 #define DB_FAIL 1000
#define DB_OVERFLOW 1001 #define DB_OVERFLOW 1001
#define DB_UNDERFLOW 1002 #define DB_UNDERFLOW 1002
#define DB_STRONG_FAIL 1003 #define DB_STRONG_FAIL 1003
#define DB_RECORD_NOT_FOUND 1500 #define DB_RECORD_NOT_FOUND 1500
#define DB_END_OF_INDEX 1501 #define DB_END_OF_INDEX 1501
#endif #endif

View File

@ -26,7 +26,7 @@ Gets a pointer to the dictionary header and x-latches its page. */
dict_hdr_t* dict_hdr_t*
dict_hdr_get( dict_hdr_get(
/*=========*/ /*=========*/
/* out: pointer to the dictionary header, /* out: pointer to the dictionary header,
page x-latched */ page x-latched */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
/************************************************************************** /**************************************************************************
@ -94,7 +94,7 @@ dict_create(void);
assigned as the id the number assigned as the id the number
DICT_IBUF_ID_MIN plus the space id */ DICT_IBUF_ID_MIN plus the space id */
#define DICT_IBUF_ID_MIN ut_dulint_create(0xFFFFFFFFUL, 0) #define DICT_IBUF_ID_MIN ut_dulint_create(0xFFFFFFFFUL, 0)
/* The offset of the dictionary header on the page */ /* The offset of the dictionary header on the page */
#define DICT_HDR FSEG_PAGE_DATA #define DICT_HDR FSEG_PAGE_DATA
@ -120,7 +120,7 @@ clustered index */
#define DICT_SYS_INDEXES_PAGE_NO_FIELD 8 #define DICT_SYS_INDEXES_PAGE_NO_FIELD 8
#define DICT_SYS_INDEXES_SPACE_NO_FIELD 7 #define DICT_SYS_INDEXES_SPACE_NO_FIELD 7
#define DICT_SYS_INDEXES_TYPE_FIELD 6 #define DICT_SYS_INDEXES_TYPE_FIELD 6
/* When a row id which is zero modulo this number (which must be a power of /* When a row id which is zero modulo this number (which must be a power of
two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is
updated */ updated */
@ -130,4 +130,4 @@ updated */
#include "dict0boot.ic" #include "dict0boot.ic"
#endif #endif
#endif #endif

View File

@ -28,7 +28,7 @@ dict_sys_get_new_row_id(void)
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
id = dict_sys->row_id; id = dict_sys->row_id;
if (0 == (ut_dulint_get_low(id) % DICT_HDR_ROW_ID_WRITE_MARGIN)) { if (0 == (ut_dulint_get_low(id) % DICT_HDR_ROW_ID_WRITE_MARGIN)) {
dict_hdr_flush_row_id(); dict_hdr_flush_row_id();
@ -39,7 +39,7 @@ dict_sys_get_new_row_id(void)
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
return(id); return(id);
} }
/************************************************************************** /**************************************************************************
Reads a row id from a record or other 6-byte stored form. */ Reads a row id from a record or other 6-byte stored form. */
@ -50,10 +50,12 @@ dict_sys_read_row_id(
/* out: row id */ /* out: row id */
byte* field) /* in: record field */ byte* field) /* in: record field */
{ {
ut_ad(DATA_ROW_ID_LEN == 6); #if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
#endif
return(mach_read_from_6(field)); return(mach_read_from_6(field));
} }
/************************************************************************** /**************************************************************************
Writes a row id to a record or other 6-byte stored form. */ Writes a row id to a record or other 6-byte stored form. */
@ -64,9 +66,11 @@ dict_sys_write_row_id(
byte* field, /* in: record field */ byte* field, /* in: record field */
dulint row_id) /* in: row id */ dulint row_id) /* in: row id */
{ {
ut_ad(DATA_ROW_ID_LEN == 6); #if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
#endif
mach_write_to_6(field, row_id); mach_write_to_6(field, row_id);
} }

View File

@ -15,7 +15,7 @@ Created 1/8/1996 Heikki Tuuri
#include "que0types.h" #include "que0types.h"
#include "row0types.h" #include "row0types.h"
#include "mtr0mtr.h" #include "mtr0mtr.h"
/************************************************************************* /*************************************************************************
Creates a table create graph. */ Creates a table create graph. */

View File

@ -26,6 +26,7 @@ Created 1/8/1996 Heikki Tuuri
#include "ut0byte.h" #include "ut0byte.h"
#include "trx0types.h" #include "trx0types.h"
#ifndef UNIV_HOTBACKUP
/********************************************************************** /**********************************************************************
Makes all characters in a NUL-terminated UTF-8 string lower case. */ Makes all characters in a NUL-terminated UTF-8 string lower case. */
@ -33,6 +34,7 @@ void
dict_casedn_str( dict_casedn_str(
/*============*/ /*============*/
char* a); /* in/out: string to put in lower case */ char* a); /* in/out: string to put in lower case */
#endif /* !UNIV_HOTBACKUP */
/************************************************************************ /************************************************************************
Get the database name length in a table name. */ Get the database name length in a table name. */
@ -197,7 +199,8 @@ dict_foreign_add_to_cache(
/*======================*/ /*======================*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
dict_foreign_t* foreign, /* in, own: foreign key constraint */ dict_foreign_t* foreign, /* in, own: foreign key constraint */
ibool check_types); /* in: TRUE=check type compatibility */ ibool check_charsets);/* in: TRUE=check charset
compatibility */
/************************************************************************* /*************************************************************************
Checks if a table is referenced by foreign keys. */ Checks if a table is referenced by foreign keys. */
@ -305,7 +308,7 @@ Checks if a table is in the dictionary cache. */
UNIV_INLINE UNIV_INLINE
dict_table_t* dict_table_t*
dict_table_check_if_in_cache_low( dict_table_check_if_in_cache_low(
/*==============================*/ /*=============================*/
/* out: table, NULL if not found */ /* out: table, NULL if not found */
const char* table_name); /* in: table name */ const char* table_name); /* in: table name */
/************************************************************************** /**************************************************************************
@ -484,6 +487,15 @@ dict_table_get_sys_col_no(
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
ulint sys); /* in: DATA_ROW_ID, ... */ ulint sys); /* in: DATA_ROW_ID, ... */
/************************************************************************ /************************************************************************
Check whether the table uses the compact page format. */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
/* out: TRUE if table uses the
compact page format */
const dict_table_t* table); /* in: table */
/************************************************************************
Checks if a column is in the ordering columns of the clustered index of a Checks if a column is in the ordering columns of the clustered index of a
table. Column prefixes are treated like whole columns. */ table. Column prefixes are treated like whole columns. */
@ -659,7 +671,6 @@ dict_index_add_col(
/*===============*/ /*===============*/
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
dict_col_t* col, /* in: column */ dict_col_t* col, /* in: column */
ulint order, /* in: order criterion */
ulint prefix_len); /* in: column prefix length */ ulint prefix_len); /* in: column prefix length */
/*********************************************************************** /***********************************************************************
Copies types of fields contained in index to tuple. */ Copies types of fields contained in index to tuple. */
@ -679,13 +690,6 @@ dict_index_get_tree(
/* out: index tree */ /* out: index tree */
dict_index_t* index); /* in: index */ dict_index_t* index); /* in: index */
/************************************************************************* /*************************************************************************
Gets the field order criterion. */
UNIV_INLINE
ulint
dict_field_get_order(
/*=================*/
dict_field_t* field);
/*************************************************************************
Gets the field column. */ Gets the field column. */
UNIV_INLINE UNIV_INLINE
dict_col_t* dict_col_t*
@ -770,7 +774,7 @@ dict_tree_build_node_ptr(
pointer */ pointer */
ulint page_no,/* in: page number to put in node pointer */ ulint page_no,/* in: page number to put in node pointer */
mem_heap_t* heap, /* in: memory heap where pointer created */ mem_heap_t* heap, /* in: memory heap where pointer created */
ulint level); /* in: level of rec in tree: 0 means leaf ulint level); /* in: level of rec in tree: 0 means leaf
level */ level */
/************************************************************************** /**************************************************************************
Copies an initial segment of a physical record, long enough to specify an Copies an initial segment of a physical record, long enough to specify an
@ -872,7 +876,7 @@ dict_update_statistics_low(
/*=======================*/ /*=======================*/
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
ibool has_dict_mutex);/* in: TRUE if the caller has the ibool has_dict_mutex);/* in: TRUE if the caller has the
dictionary mutex */ dictionary mutex */
/************************************************************************* /*************************************************************************
Calculates new estimates for table and index statistics. The statistics Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */ are used in query optimization. */
@ -940,13 +944,13 @@ struct dict_sys_struct{
header and flushed to a file; in header and flushed to a file; in
recovery this must be derived from recovery this must be derived from
the log records */ the log records */
hash_table_t* table_hash; /* hash table of the tables, based hash_table_t* table_hash; /* hash table of the tables, based
on name */ on name */
hash_table_t* table_id_hash; /* hash table of the tables, based hash_table_t* table_id_hash; /* hash table of the tables, based
on id */ on id */
hash_table_t* col_hash; /* hash table of the columns */ hash_table_t* col_hash; /* hash table of the columns */
UT_LIST_BASE_NODE_T(dict_table_t) UT_LIST_BASE_NODE_T(dict_table_t)
table_LRU; /* LRU list of tables */ table_LRU; /* LRU list of tables */
ulint size; /* varying space in bytes occupied ulint size; /* varying space in bytes occupied
by the data dictionary table and by the data dictionary table and
index objects */ index objects */

View File

@ -93,7 +93,7 @@ dict_table_get_n_user_cols(
ut_ad(table); ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(table->cached); ut_ad(table->cached);
return(table->n_cols - DATA_N_SYS_COLS); return(table->n_cols - DATA_N_SYS_COLS);
} }
@ -127,7 +127,7 @@ dict_table_get_n_cols(
ut_ad(table); ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(table->cached); ut_ad(table->cached);
return(table->n_cols); return(table->n_cols);
} }
@ -164,7 +164,7 @@ dict_table_get_sys_col(
ut_ad(sys < DATA_N_SYS_COLS); ut_ad(sys < DATA_N_SYS_COLS);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
col = dict_table_get_nth_col(table, table->n_cols col = dict_table_get_nth_col(table, table->n_cols
- DATA_N_SYS_COLS + sys); - DATA_N_SYS_COLS + sys);
ut_ad(col->type.mtype == DATA_SYS); ut_ad(col->type.mtype == DATA_SYS);
ut_ad(col->type.prtype == (sys | DATA_NOT_NULL)); ut_ad(col->type.prtype == (sys | DATA_NOT_NULL));
@ -189,6 +189,25 @@ dict_table_get_sys_col_no(
return(table->n_cols - DATA_N_SYS_COLS + sys); return(table->n_cols - DATA_N_SYS_COLS + sys);
} }
/************************************************************************
Check whether the table uses the compact page format. */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
/* out: TRUE if table uses the
compact page format */
const dict_table_t* table) /* in: table */
{
ut_ad(table);
#if DICT_TF_COMPACT != TRUE
#error
#endif
return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
}
/************************************************************************ /************************************************************************
Gets the number of fields in the internal representation of an index, Gets the number of fields in the internal representation of an index,
including fields added by the dictionary system. */ including fields added by the dictionary system. */
@ -202,7 +221,7 @@ dict_index_get_n_fields(
{ {
ut_ad(index); ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
return(index->n_fields); return(index->n_fields);
} }
@ -222,7 +241,7 @@ dict_index_get_n_unique(
ut_ad(index); ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(index->cached); ut_ad(index->cached);
return(index->n_uniq); return(index->n_uniq);
} }
@ -241,7 +260,7 @@ dict_index_get_n_unique_in_tree(
ut_ad(index); ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(index->cached); ut_ad(index->cached);
if (index->type & DICT_CLUSTERED) { if (index->type & DICT_CLUSTERED) {
return(dict_index_get_n_unique(index)); return(dict_index_get_n_unique(index));
@ -324,19 +343,6 @@ dict_index_get_tree(
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
return(index->tree); return(index->tree);
}
/*************************************************************************
Gets the field order criterion. */
UNIV_INLINE
ulint
dict_field_get_order(
/*=================*/
dict_field_t* field)
{
ut_ad(field);
return(field->order);
} }
/************************************************************************* /*************************************************************************
@ -494,13 +500,13 @@ Checks if a table is in the dictionary cache. */
UNIV_INLINE UNIV_INLINE
dict_table_t* dict_table_t*
dict_table_check_if_in_cache_low( dict_table_check_if_in_cache_low(
/*==============================*/ /*=============================*/
/* out: table, NULL if not found */ /* out: table, NULL if not found */
const char* table_name) /* in: table name */ const char* table_name) /* in: table name */
{ {
dict_table_t* table; dict_table_t* table;
ulint table_fold; ulint table_fold;
ut_ad(table_name); ut_ad(table_name);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
@ -525,14 +531,14 @@ dict_table_get_low(
const char* table_name) /* in: table name */ const char* table_name) /* in: table name */
{ {
dict_table_t* table; dict_table_t* table;
ut_ad(table_name); ut_ad(table_name);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
table = dict_table_check_if_in_cache_low(table_name); table = dict_table_check_if_in_cache_low(table_name);
if (table == NULL) { if (table == NULL) {
table = dict_load_table(table_name); table = dict_load_table(table_name);
} }
@ -557,7 +563,7 @@ dict_table_get_on_id_low(
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
UT_NOT_USED(trx); UT_NOT_USED(trx);
/* Look for the table name in the hash table */ /* Look for the table name in the hash table */
fold = ut_fold_dulint(table_id); fold = ut_fold_dulint(table_id);
@ -572,9 +578,9 @@ dict_table_get_on_id_low(
/* lock_push(trx, table, LOCK_DICT_MEM_FIX) */ /* lock_push(trx, table, LOCK_DICT_MEM_FIX) */
} }
/* TODO: should get the type information from MySQL */ /* TODO: should get the type information from MySQL */
return(table); return(table);
} }
@ -587,9 +593,9 @@ dict_table_release(
dict_table_t* table) /* in: table to be released */ dict_table_t* table) /* in: table to be released */
{ {
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
table->mem_fix--; table->mem_fix--;
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
} }
@ -604,7 +610,7 @@ dict_table_get_index(
const char* name) /* in: index name */ const char* name) /* in: index name */
{ {
dict_index_t* index = NULL; dict_index_t* index = NULL;
index = dict_table_get_first_index(table); index = dict_table_get_first_index(table);
while (index != NULL) { while (index != NULL) {
@ -614,7 +620,7 @@ dict_table_get_index(
} }
index = dict_table_get_next_index(index); index = dict_table_get_next_index(index);
} }
return(index); return(index);
} }

View File

@ -60,7 +60,7 @@ dict_table_t*
dict_load_table_on_id( dict_load_table_on_id(
/*==================*/ /*==================*/
/* out: table; NULL if table does not exist */ /* out: table; NULL if table does not exist */
dulint table_id); /* in: table id */ dulint table_id); /* in: table id */
/************************************************************************ /************************************************************************
This function is called when the database is booted. This function is called when the database is booted.
Loads system table index definitions except for the clustered index which Loads system table index definitions except for the clustered index which
@ -82,7 +82,8 @@ dict_load_foreigns(
/*===============*/ /*===============*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
const char* table_name, /* in: table name */ const char* table_name, /* in: table name */
ibool check_types); /* in: TRUE=check type compatibility */ ibool check_charsets);/* in: TRUE=check charsets
compatibility */
/************************************************************************ /************************************************************************
Prints to the standard output information on all tables found in the data Prints to the standard output information on all tables found in the data
dictionary system table. */ dictionary system table. */

View File

@ -29,12 +29,9 @@ Created 1/8/1996 Heikki Tuuri
combination of types */ combination of types */
#define DICT_CLUSTERED 1 /* clustered index */ #define DICT_CLUSTERED 1 /* clustered index */
#define DICT_UNIQUE 2 /* unique index */ #define DICT_UNIQUE 2 /* unique index */
#define DICT_UNIVERSAL 4 /* index which can contain records from any #define DICT_UNIVERSAL 4 /* index which can contain records from any
other index */ other index */
#define DICT_IBUF 8 /* insert buffer tree */ #define DICT_IBUF 8 /* insert buffer tree */
/* Flags for ordering an index field: OR'ing of the flags allowed */
#define DICT_DESCEND 1 /* in descending order (default ascending) */
/* Types for a table object */ /* Types for a table object */
#define DICT_TABLE_ORDINARY 1 #define DICT_TABLE_ORDINARY 1
@ -42,6 +39,9 @@ combination of types */
#define DICT_TABLE_CLUSTER 3 /* this means that the table is #define DICT_TABLE_CLUSTER 3 /* this means that the table is
really a cluster definition */ really a cluster definition */
/* Table flags */
#define DICT_TF_COMPACT 1 /* compact page format */
/************************************************************************** /**************************************************************************
Creates a table memory object. */ Creates a table memory object. */
@ -55,7 +55,7 @@ dict_mem_table_create(
is ignored if the table is made is ignored if the table is made
a member of a cluster */ a member of a cluster */
ulint n_cols, /* in: number of columns */ ulint n_cols, /* in: number of columns */
ibool comp); /* in: TRUE=compact page format */ ulint flags); /* in: table flags */
/************************************************************************** /**************************************************************************
Creates a cluster memory object. */ Creates a cluster memory object. */
@ -116,8 +116,6 @@ dict_mem_index_add_field(
/*=====================*/ /*=====================*/
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
const char* name, /* in: column name */ const char* name, /* in: column name */
ulint order, /* in: order criterion; 0 means an
ascending order */
ulint prefix_len); /* in: 0 or the column prefix length ulint prefix_len); /* in: 0 or the column prefix length
in a MySQL index like in a MySQL index like
INDEX (textcol(25)) */ INDEX (textcol(25)) */
@ -148,7 +146,7 @@ struct dict_col_struct{
const char* name; /* name */ const char* name; /* name */
dtype_t type; /* data type */ dtype_t type; /* data type */
dict_table_t* table; /* back pointer to table of this column */ dict_table_t* table; /* back pointer to table of this column */
ulint aux; /* this is used as an auxiliary variable ulint aux; /* this is used as an auxiliary variable
in some of the functions below */ in some of the functions below */
}; };
@ -163,8 +161,6 @@ UTF-8 charset. In that charset, a character may take at most 3 bytes. */
struct dict_field_struct{ struct dict_field_struct{
dict_col_t* col; /* pointer to the table column */ dict_col_t* col; /* pointer to the table column */
const char* name; /* name of the column */ const char* name; /* name of the column */
ulint order; /* flags for ordering this field:
DICT_DESCEND, ... */
ulint prefix_len; /* 0 or the length of the column ulint prefix_len; /* 0 or the length of the column
prefix in bytes in a MySQL index of prefix in bytes in a MySQL index of
type, e.g., INDEX (textcol(25)); type, e.g., INDEX (textcol(25));
@ -175,10 +171,6 @@ struct dict_field_struct{
ulint fixed_len; /* 0 or the fixed length of the ulint fixed_len; /* 0 or the fixed length of the
column if smaller than column if smaller than
DICT_MAX_INDEX_COL_LEN */ DICT_MAX_INDEX_COL_LEN */
ulint fixed_offs; /* offset to the field, or
ULINT_UNDEFINED if it is not fixed
within the record (due to preceding
variable-length fields) */
}; };
/* Data structure for an index tree */ /* Data structure for an index tree */
@ -280,7 +272,7 @@ struct dict_foreign_struct{
constraint is defined: we allow the constraint is defined: we allow the
indexes to contain more fields than indexes to contain more fields than
mentioned in the constraint, as long mentioned in the constraint, as long
as the first fields are as mentioned */ as the first fields are as mentioned */
dict_index_t* foreign_index; /* foreign index; we require that dict_index_t* foreign_index; /* foreign index; we require that
both tables contain explicitly defined both tables contain explicitly defined
indexes for the constraint: InnoDB indexes for the constraint: InnoDB
@ -311,6 +303,7 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */
struct dict_table_struct{ struct dict_table_struct{
dulint id; /* id of the table or cluster */ dulint id; /* id of the table or cluster */
ulint type; /* DICT_TABLE_ORDINARY, ... */ ulint type; /* DICT_TABLE_ORDINARY, ... */
ulint flags; /* DICT_TF_COMPACT, ... */
mem_heap_t* heap; /* memory heap */ mem_heap_t* heap; /* memory heap */
const char* name; /* table name */ const char* name; /* table name */
const char* dir_path_of_temp_table;/* NULL or the directory path const char* dir_path_of_temp_table;/* NULL or the directory path
@ -328,7 +321,6 @@ struct dict_table_struct{
ibool tablespace_discarded;/* this flag is set TRUE when the ibool tablespace_discarded;/* this flag is set TRUE when the
user calls DISCARD TABLESPACE on this table, user calls DISCARD TABLESPACE on this table,
and reset to FALSE in IMPORT TABLESPACE */ and reset to FALSE in IMPORT TABLESPACE */
ibool comp; /* flag: TRUE=compact page format */
hash_node_t name_hash; /* hash chain node */ hash_node_t name_hash; /* hash chain node */
hash_node_t id_hash; /* hash chain node */ hash_node_t id_hash; /* hash chain node */
ulint n_def; /* number of columns defined so far */ ulint n_def; /* number of columns defined so far */
@ -345,7 +337,7 @@ struct dict_table_struct{
which refer to this table */ which refer to this table */
UT_LIST_NODE_T(dict_table_t) UT_LIST_NODE_T(dict_table_t)
table_LRU; /* node of the LRU list of tables */ table_LRU; /* node of the LRU list of tables */
ulint mem_fix;/* count of how many times the table ulint mem_fix;/* count of how many times the table
and its indexes has been fixed in memory; and its indexes has been fixed in memory;
currently NOT used */ currently NOT used */
ulint n_mysql_handles_opened; ulint n_mysql_handles_opened;
@ -408,9 +400,9 @@ struct dict_table_struct{
database pages */ database pages */
ulint stat_sum_of_other_index_sizes; ulint stat_sum_of_other_index_sizes;
/* other indexes in database pages */ /* other indexes in database pages */
ibool stat_initialized; /* TRUE if statistics have ibool stat_initialized; /* TRUE if statistics have
been calculated the first time been calculated the first time
after database startup or table creation */ after database startup or table creation */
ulint stat_modified_counter; ulint stat_modified_counter;
/* when a row is inserted, updated, or deleted, /* when a row is inserted, updated, or deleted,
we add 1 to this number; we calculate new we add 1 to this number; we calculate new
@ -432,11 +424,11 @@ struct dict_table_struct{
inited; MySQL gets the init value by executing inited; MySQL gets the init value by executing
SELECT MAX(auto inc column) */ SELECT MAX(auto inc column) */
ib_longlong autoinc;/* autoinc counter value to give to the ib_longlong autoinc;/* autoinc counter value to give to the
next inserted row */ next inserted row */
ulint magic_n;/* magic number */ ulint magic_n;/* magic number */
}; };
#define DICT_TABLE_MAGIC_N 76333786 #define DICT_TABLE_MAGIC_N 76333786
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "dict0mem.ic" #include "dict0mem.ic"
#endif #endif

View File

@ -76,7 +76,7 @@ dyn_array_get_element(
/*==================*/ /*==================*/
/* out: pointer to element */ /* out: pointer to element */
dyn_array_t* arr, /* in: dyn array */ dyn_array_t* arr, /* in: dyn array */
ulint pos); /* in: position of element as bytes ulint pos); /* in: position of element as bytes
from array start */ from array start */
/**************************************************************** /****************************************************************
Returns the size of stored data in a dyn array. */ Returns the size of stored data in a dyn array. */
@ -140,11 +140,11 @@ dyn_push_string(
/* NOTE! Do not use the fields of the struct directly: the definition /* NOTE! Do not use the fields of the struct directly: the definition
appears here only for the compiler to know its size! */ appears here only for the compiler to know its size! */
struct dyn_block_struct{ struct dyn_block_struct{
mem_heap_t* heap; /* in the first block this is != NULL mem_heap_t* heap; /* in the first block this is != NULL
if dynamic allocation has been needed */ if dynamic allocation has been needed */
ulint used; /* number of data bytes used in this block */ ulint used; /* number of data bytes used in this block */
byte data[DYN_ARRAY_DATA_SIZE]; byte data[DYN_ARRAY_DATA_SIZE];
/* storage for array elements */ /* storage for array elements */
UT_LIST_BASE_NODE_T(dyn_block_t) base; UT_LIST_BASE_NODE_T(dyn_block_t) base;
/* linear list of dyn blocks: this node is /* linear list of dyn blocks: this node is
used only in the first block */ used only in the first block */
@ -163,4 +163,4 @@ struct dyn_block_struct{
#include "dyn0dyn.ic" #include "dyn0dyn.ic"
#endif #endif
#endif #endif

View File

@ -41,7 +41,7 @@ dyn_array_get_last_block(
if (arr->heap == NULL) { if (arr->heap == NULL) {
return(arr); return(arr);
} }
return(UT_LIST_GET_LAST(arr->base)); return(UT_LIST_GET_LAST(arr->base));
} }
@ -57,13 +57,13 @@ dyn_array_get_next_block(
dyn_block_t* block) /* in: dyn array block */ dyn_block_t* block) /* in: dyn array block */
{ {
ut_ad(arr && block); ut_ad(arr && block);
if (arr->heap == NULL) { if (arr->heap == NULL) {
ut_ad(arr == block); ut_ad(arr == block);
return(NULL); return(NULL);
} }
return(UT_LIST_GET_NEXT(list, block)); return(UT_LIST_GET_NEXT(list, block));
} }
@ -106,7 +106,9 @@ dyn_array_create(
size sizeof(dyn_array_t) */ size sizeof(dyn_array_t) */
{ {
ut_ad(arr); ut_ad(arr);
ut_ad(DYN_ARRAY_DATA_SIZE < DYN_BLOCK_FULL_FLAG); #if DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG
# error "DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG"
#endif
arr->heap = NULL; arr->heap = NULL;
arr->used = 0; arr->used = 0;
@ -153,13 +155,13 @@ dyn_array_push(
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
ut_ad(size <= DYN_ARRAY_DATA_SIZE); ut_ad(size <= DYN_ARRAY_DATA_SIZE);
ut_ad(size); ut_ad(size);
block = arr; block = arr;
used = block->used; used = block->used;
if (used + size > DYN_ARRAY_DATA_SIZE) { if (used + size > DYN_ARRAY_DATA_SIZE) {
/* Get the last array block */ /* Get the last array block */
block = dyn_array_get_last_block(arr); block = dyn_array_get_last_block(arr);
used = block->used; used = block->used;
@ -195,13 +197,13 @@ dyn_array_open(
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
ut_ad(size <= DYN_ARRAY_DATA_SIZE); ut_ad(size <= DYN_ARRAY_DATA_SIZE);
ut_ad(size); ut_ad(size);
block = arr; block = arr;
used = block->used; used = block->used;
if (used + size > DYN_ARRAY_DATA_SIZE) { if (used + size > DYN_ARRAY_DATA_SIZE) {
/* Get the last array block */ /* Get the last array block */
block = dyn_array_get_last_block(arr); block = dyn_array_get_last_block(arr);
used = block->used; used = block->used;
@ -217,7 +219,7 @@ dyn_array_open(
ut_ad(arr->buf_end == 0); ut_ad(arr->buf_end == 0);
arr->buf_end = used + size; arr->buf_end = used + size;
#endif #endif
return((block->data) + used); return((block->data) + used);
} }
@ -234,13 +236,13 @@ dyn_array_close(
ut_ad(arr); ut_ad(arr);
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
block = dyn_array_get_last_block(arr); block = dyn_array_get_last_block(arr);
ut_ad(arr->buf_end + block->data >= ptr); ut_ad(arr->buf_end + block->data >= ptr);
block->used = ptr - block->data; block->used = ptr - block->data;
ut_ad(block->used <= DYN_ARRAY_DATA_SIZE); ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
@ -256,7 +258,7 @@ dyn_array_get_element(
/*==================*/ /*==================*/
/* out: pointer to element */ /* out: pointer to element */
dyn_array_t* arr, /* in: dyn array */ dyn_array_t* arr, /* in: dyn array */
ulint pos) /* in: position of element as bytes ulint pos) /* in: position of element as bytes
from array start */ from array start */
{ {
dyn_block_t* block; dyn_block_t* block;
@ -267,7 +269,7 @@ dyn_array_get_element(
/* Get the first array block */ /* Get the first array block */
block = dyn_array_get_first_block(arr); block = dyn_array_get_first_block(arr);
if (arr->heap != NULL) { if (arr->heap != NULL) {
used = dyn_block_get_used(block); used = dyn_block_get_used(block);
@ -282,7 +284,7 @@ dyn_array_get_element(
ut_ad(block); ut_ad(block);
ut_ad(dyn_block_get_used(block) >= pos); ut_ad(dyn_block_get_used(block) >= pos);
return(block->data + pos); return(block->data + pos);
} }
@ -296,7 +298,7 @@ dyn_array_get_data_size(
dyn_array_t* arr) /* in: dyn array */ dyn_array_t* arr) /* in: dyn array */
{ {
dyn_block_t* block; dyn_block_t* block;
ulint sum = 0; ulint sum = 0;
ut_ad(arr); ut_ad(arr);
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N); ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
@ -305,7 +307,7 @@ dyn_array_get_data_size(
return(arr->used); return(arr->used);
} }
/* Get the first array block */ /* Get the first array block */
block = dyn_array_get_first_block(arr); block = dyn_array_get_first_block(arr);
@ -334,10 +336,10 @@ dyn_push_string(
n_copied = DYN_ARRAY_DATA_SIZE; n_copied = DYN_ARRAY_DATA_SIZE;
} else { } else {
n_copied = len; n_copied = len;
} }
memcpy(dyn_array_push(arr, n_copied), str, n_copied); memcpy(dyn_array_push(arr, n_copied), str, n_copied);
str += n_copied; str += n_copied;
len -= n_copied; len -= n_copied;
} }

View File

@ -77,7 +77,7 @@ Gets a iboolean value from a query node. */
UNIV_INLINE UNIV_INLINE
ibool ibool
eval_node_get_ibool_val( eval_node_get_ibool_val(
/*===================*/ /*====================*/
/* out: iboolean value */ /* out: iboolean value */
que_node_t* node); /* in: query graph node */ que_node_t* node); /* in: query graph node */
/********************************************************************* /*********************************************************************
@ -94,4 +94,4 @@ eval_cmp(
#include "eval0eval.ic" #include "eval0eval.ic"
#endif #endif
#endif #endif

View File

@ -54,7 +54,7 @@ eval_node_ensure_val_buf(
dfield_set_len(dfield, size); dfield_set_len(dfield, size);
data = dfield_get_data(dfield); data = dfield_get_data(dfield);
if (!data || que_node_get_val_buf_size(node) < size) { if (!data || que_node_get_val_buf_size(node) < size) {
data = eval_node_alloc_val_buf(node, size); data = eval_node_alloc_val_buf(node, size);
@ -77,7 +77,7 @@ eval_sym(
if (sym_node->indirection) { if (sym_node->indirection) {
/* The symbol table node is an alias for a variable or a /* The symbol table node is an alias for a variable or a
column */ column */
dfield_copy_data(que_node_get_val(sym_node), dfield_copy_data(que_node_get_val(sym_node),
que_node_get_val(sym_node->indirection)); que_node_get_val(sym_node->indirection));
} }
@ -97,7 +97,7 @@ eval_exp(
return; return;
} }
eval_func(exp_node); eval_func(exp_node);
} }
@ -116,13 +116,13 @@ eval_node_set_int_val(
dfield = que_node_get_val(node); dfield = que_node_get_val(node);
data = dfield_get_data(dfield); data = dfield_get_data(dfield);
if (data == NULL) { if (data == NULL) {
data = eval_node_alloc_val_buf(node, 4); data = eval_node_alloc_val_buf(node, 4);
} }
ut_ad(dfield_get_len(dfield) == 4); ut_ad(dfield_get_len(dfield) == 4);
mach_write_to_4(data, (ulint)val); mach_write_to_4(data, (ulint)val);
} }
@ -141,7 +141,7 @@ eval_node_get_int_val(
ut_ad(dfield_get_len(dfield) == 4); ut_ad(dfield_get_len(dfield) == 4);
return((int)mach_read_from_4(dfield_get_data(dfield))); return((int)mach_read_from_4(dfield_get_data(dfield)));
} }
/********************************************************************* /*********************************************************************
@ -149,7 +149,7 @@ Gets a iboolean value from a query node. */
UNIV_INLINE UNIV_INLINE
ibool ibool
eval_node_get_ibool_val( eval_node_get_ibool_val(
/*===================*/ /*====================*/
/* out: iboolean value */ /* out: iboolean value */
que_node_t* node) /* in: query graph node */ que_node_t* node) /* in: query graph node */
{ {
@ -159,7 +159,7 @@ eval_node_get_ibool_val(
dfield = que_node_get_val(node); dfield = que_node_get_val(node);
data = dfield_get_data(dfield); data = dfield_get_data(dfield);
ut_ad(data != NULL); ut_ad(data != NULL);
return(mach_read_from_1(data)); return(mach_read_from_1(data));
@ -170,7 +170,7 @@ Sets a iboolean value as the value of a function node. */
UNIV_INLINE UNIV_INLINE
void void
eval_node_set_ibool_val( eval_node_set_ibool_val(
/*===================*/ /*====================*/
func_node_t* func_node, /* in: function node */ func_node_t* func_node, /* in: function node */
ibool val) /* in: value to set */ ibool val) /* in: value to set */
{ {
@ -180,7 +180,7 @@ eval_node_set_ibool_val(
dfield = que_node_get_val(func_node); dfield = que_node_get_val(func_node);
data = dfield_get_data(dfield); data = dfield_get_data(dfield);
if (data == NULL) { if (data == NULL) {
/* Allocate 1 byte to hold the value */ /* Allocate 1 byte to hold the value */
@ -188,7 +188,7 @@ eval_node_set_ibool_val(
} }
ut_ad(dfield_get_len(dfield) == 1); ut_ad(dfield_get_len(dfield) == 1);
mach_write_to_1(data, val); mach_write_to_1(data, val);
} }
@ -204,7 +204,7 @@ eval_node_copy_and_alloc_val(
ulint len) /* in: string length or UNIV_SQL_NULL */ ulint len) /* in: string length or UNIV_SQL_NULL */
{ {
byte* data; byte* data;
if (len == UNIV_SQL_NULL) { if (len == UNIV_SQL_NULL) {
dfield_set_len(que_node_get_val(node), len); dfield_set_len(que_node_get_val(node), len);
@ -212,7 +212,7 @@ eval_node_copy_and_alloc_val(
} }
data = eval_node_ensure_val_buf(node, len); data = eval_node_ensure_val_buf(node, len);
ut_memcpy(data, str, len); ut_memcpy(data, str, len);
} }
@ -226,7 +226,7 @@ eval_node_copy_val(
que_node_t* node2) /* in: node to copy from */ que_node_t* node2) /* in: node to copy from */
{ {
dfield_t* dfield2; dfield_t* dfield2;
dfield2 = que_node_get_val(node2); dfield2 = que_node_get_val(node2);
eval_node_copy_and_alloc_val(node1, dfield_get_data(dfield2), eval_node_copy_and_alloc_val(node1, dfield_get_data(dfield2),

View File

@ -76,4 +76,4 @@ return_step(
#include "eval0proc.ic" #include "eval0proc.ic"
#endif #endif
#endif #endif

View File

@ -22,19 +22,19 @@ proc_step(
proc_node_t* node; proc_node_t* node;
ut_ad(thr); ut_ad(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_PROC); ut_ad(que_node_get_type(node) == QUE_NODE_PROC);
if (thr->prev_node == que_node_get_parent(node)) { if (thr->prev_node == que_node_get_parent(node)) {
/* Start execution from the first statement in the statement /* Start execution from the first statement in the statement
list */ list */
thr->run_node = node->stat_list; thr->run_node = node->stat_list;
} else { } else {
/* Move to the next statement */ /* Move to the next statement */
ut_ad(que_node_get_next(thr->prev_node) == NULL); ut_ad(que_node_get_next(thr->prev_node) == NULL);
thr->run_node = NULL; thr->run_node = NULL;
} }
@ -43,7 +43,7 @@ proc_step(
} }
return(thr); return(thr);
} }
/************************************************************************** /**************************************************************************
Performs an execution step of a procedure call node. */ Performs an execution step of a procedure call node. */
@ -57,15 +57,15 @@ proc_eval_step(
func_node_t* node; func_node_t* node;
ut_ad(thr); ut_ad(thr);
node = thr->run_node; node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_FUNC); ut_ad(que_node_get_type(node) == QUE_NODE_FUNC);
/* Evaluate the procedure */ /* Evaluate the procedure */
eval_exp(node); eval_exp(node);
thr->run_node = que_node_get_parent(node); thr->run_node = que_node_get_parent(node);
return(thr); return(thr);
} }

View File

@ -63,7 +63,20 @@ extern fil_addr_t fil_addr_null;
#define FIL_PAGE_LSN 16 /* lsn of the end of the newest #define FIL_PAGE_LSN 16 /* lsn of the end of the newest
modification log record to the page */ modification log record to the page */
#define FIL_PAGE_TYPE 24 /* file page type: FIL_PAGE_INDEX,..., #define FIL_PAGE_TYPE 24 /* file page type: FIL_PAGE_INDEX,...,
2 bytes */ 2 bytes.
The contents of this field can only
be trusted in the following case:
if the page is an uncompressed
B-tree index page, then it is
guaranteed that the value is
FIL_PAGE_INDEX.
The opposite does not hold.
In tablespaces created by
MySQL/InnoDB 5.1.7 or later, the
contents of this field is valid
for all uncompressed pages. */
#define FIL_PAGE_FILE_FLUSH_LSN 26 /* this is only defined for the #define FIL_PAGE_FILE_FLUSH_LSN 26 /* this is only defined for the
first page in a data file: the file first page in a data file: the file
has been flushed to disk at least up has been flushed to disk at least up
@ -79,14 +92,22 @@ extern fil_addr_t fil_addr_null;
to the last 4 bytes of FIL_PAGE_LSN */ to the last 4 bytes of FIL_PAGE_LSN */
#define FIL_PAGE_DATA_END 8 #define FIL_PAGE_DATA_END 8
/* File page types */ /* File page types (values of FIL_PAGE_TYPE) */
#define FIL_PAGE_INDEX 17855 #define FIL_PAGE_INDEX 17855 /* B-tree node */
#define FIL_PAGE_UNDO_LOG 2 #define FIL_PAGE_UNDO_LOG 2 /* Undo log page */
#define FIL_PAGE_INODE 3 #define FIL_PAGE_INODE 3 /* Index node */
#define FIL_PAGE_IBUF_FREE_LIST 4 #define FIL_PAGE_IBUF_FREE_LIST 4 /* Insert buffer free list */
/* File page types introduced in MySQL/InnoDB 5.1.7 */
#define FIL_PAGE_TYPE_ALLOCATED 0 /* Freshly allocated page */
#define FIL_PAGE_IBUF_BITMAP 5 /* Insert buffer bitmap */
#define FIL_PAGE_TYPE_SYS 6 /* System page */
#define FIL_PAGE_TYPE_TRX_SYS 7 /* Transaction system data */
#define FIL_PAGE_TYPE_FSP_HDR 8 /* File space header */
#define FIL_PAGE_TYPE_XDES 9 /* Extent descriptor page */
#define FIL_PAGE_TYPE_BLOB 10 /* Uncompressed BLOB page */
/* Space types */ /* Space types */
#define FIL_TABLESPACE 501 #define FIL_TABLESPACE 501
#define FIL_LOG 502 #define FIL_LOG 502
extern ulint fil_n_log_flushes; extern ulint fil_n_log_flushes;
@ -271,7 +292,7 @@ Decrements the count of pending insert buffer page merges. */
void void
fil_decr_pending_ibuf_merges( fil_decr_pending_ibuf_merges(
/*========================*/ /*=========================*/
ulint id); /* in: space id */ ulint id); /* in: space id */
/*********************************************************************** /***********************************************************************
Parses the body of a log record written about an .ibd file operation. That is, Parses the body of a log record written about an .ibd file operation. That is,
@ -289,13 +310,13 @@ datadir that we should use in replaying the file operations. */
byte* byte*
fil_op_log_parse_or_replay( fil_op_log_parse_or_replay(
/*=======================*/ /*=======================*/
/* out: end of log record, or NULL if the /* out: end of log record, or NULL if the
record was not completely contained between record was not completely contained between
ptr and end_ptr */ ptr and end_ptr */
byte* ptr, /* in: buffer containing the log record body, byte* ptr, /* in: buffer containing the log record body,
or an initial segment of it, if the record does or an initial segment of it, if the record does
not fir completely between ptr and end_ptr */ not fir completely between ptr and end_ptr */
byte* end_ptr, /* in: buffer end */ byte* end_ptr, /* in: buffer end */
ulint type, /* in: the type of this log record */ ulint type, /* in: the type of this log record */
ibool do_replay, /* in: TRUE if we want to replay the ibool do_replay, /* in: TRUE if we want to replay the
operation, and not just parse the log record */ operation, and not just parse the log record */
@ -619,7 +640,7 @@ void
fil_aio_wait( fil_aio_wait(
/*=========*/ /*=========*/
ulint segment); /* in: the number of the segment in the aio ulint segment); /* in: the number of the segment in the aio
array to wait for */ array to wait for */
/************************************************************************** /**************************************************************************
Flushes to disk possible writes cached by the OS. If the space does not exist Flushes to disk possible writes cached by the OS. If the space does not exist
or is being dropped, does not do anything. */ or is being dropped, does not do anything. */
@ -665,7 +686,7 @@ Sets the file page type. */
void void
fil_page_set_type( fil_page_set_type(
/*==============*/ /*==============*/
byte* page, /* in: file page */ byte* page, /* in: file page */
ulint type); /* in: type */ ulint type); /* in: type */
/************************************************************************* /*************************************************************************
Gets the file page type. */ Gets the file page type. */
@ -675,7 +696,7 @@ fil_page_get_type(
/*==============*/ /*==============*/
/* out: type; NOTE that if the type has not been /* out: type; NOTE that if the type has not been
written to page, the return value not defined */ written to page, the return value not defined */
byte* page); /* in: file page */ byte* page); /* in: file page */
typedef struct fil_space_struct fil_space_t; typedef struct fil_space_struct fil_space_t;

View File

@ -80,8 +80,8 @@ Reads the space id from the first page of a tablespace. */
ulint ulint
fsp_header_get_space_id( fsp_header_get_space_id(
/*====================*/ /*====================*/
/* out: space id, ULINT UNDEFINED if error */ /* out: space id, ULINT UNDEFINED if error */
page_t* page); /* in: first page of a tablespace */ page_t* page); /* in: first page of a tablespace */
/************************************************************************** /**************************************************************************
Writes the space id to a tablespace header. This function is used past the Writes the space id to a tablespace header. This function is used past the
buffer pool when we in fil0fil.c create a new single-table tablespace. */ buffer pool when we in fil0fil.c create a new single-table tablespace. */
@ -100,7 +100,7 @@ fsp_header_init(
/*============*/ /*============*/
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint size, /* in: current size in blocks */ ulint size, /* in: current size in blocks */
mtr_t* mtr); /* in: mini-transaction handle */ mtr_t* mtr); /* in: mini-transaction handle */
/************************************************************************** /**************************************************************************
Increases the space size field of a space. */ Increases the space size field of a space. */
@ -109,7 +109,7 @@ fsp_header_inc_size(
/*================*/ /*================*/
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint size_inc,/* in: size increment in pages */ ulint size_inc,/* in: size increment in pages */
mtr_t* mtr); /* in: mini-transaction handle */ mtr_t* mtr); /* in: mini-transaction handle */
/************************************************************************** /**************************************************************************
Creates a new segment. */ Creates a new segment. */
@ -158,7 +158,7 @@ ulint
fseg_n_reserved_pages( fseg_n_reserved_pages(
/*==================*/ /*==================*/
/* out: number of reserved pages */ /* out: number of reserved pages */
fseg_header_t* header, /* in: segment header */ fseg_header_t* header, /* in: segment header */
ulint* used, /* out: number of pages used (<= reserved) */ ulint* used, /* out: number of pages used (<= reserved) */
mtr_t* mtr); /* in: mtr handle */ mtr_t* mtr); /* in: mtr handle */
/************************************************************************** /**************************************************************************
@ -232,9 +232,9 @@ ibool
fsp_reserve_free_extents( fsp_reserve_free_extents(
/*=====================*/ /*=====================*/
/* out: TRUE if we were able to make the reservation */ /* out: TRUE if we were able to make the reservation */
ulint* n_reserved,/* out: number of extents actually reserved; if we ulint* n_reserved,/* out: number of extents actually reserved; if we
return TRUE and the tablespace size is < 64 pages, return TRUE and the tablespace size is < 64 pages,
then this can be 0, otherwise it is n_ext */ then this can be 0, otherwise it is n_ext */
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint n_ext, /* in: number of extents to reserve */ ulint n_ext, /* in: number of extents to reserve */
ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */ ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */

View File

@ -40,9 +40,9 @@ flst_write_addr(
ut_ad(mtr_memo_contains(mtr, buf_block_align(faddr), ut_ad(mtr_memo_contains(mtr, buf_block_align(faddr),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
mlog_write_ulint(faddr + FIL_ADDR_PAGE, addr.page, MLOG_4BYTES, mtr); mlog_write_ulint(faddr + FIL_ADDR_PAGE, addr.page, MLOG_4BYTES, mtr);
mlog_write_ulint(faddr + FIL_ADDR_BYTE, addr.boffset, mlog_write_ulint(faddr + FIL_ADDR_BYTE, addr.boffset,
MLOG_2BYTES, mtr); MLOG_2BYTES, mtr);
} }
/************************************************************************ /************************************************************************
@ -59,10 +59,10 @@ flst_read_addr(
ut_ad(faddr && mtr); ut_ad(faddr && mtr);
addr.page = mtr_read_ulint(faddr + FIL_ADDR_PAGE, MLOG_4BYTES, mtr); addr.page = mtr_read_ulint(faddr + FIL_ADDR_PAGE, MLOG_4BYTES, mtr);
addr.boffset = mtr_read_ulint(faddr + FIL_ADDR_BYTE, MLOG_2BYTES, addr.boffset = mtr_read_ulint(faddr + FIL_ADDR_BYTE, MLOG_2BYTES,
mtr); mtr);
return(addr); return(addr);
} }
/************************************************************************ /************************************************************************
@ -76,9 +76,9 @@ flst_init(
{ {
ut_ad(mtr_memo_contains(mtr, buf_block_align(base), ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
mlog_write_ulint(base + FLST_LEN, 0, MLOG_4BYTES, mtr); mlog_write_ulint(base + FLST_LEN, 0, MLOG_4BYTES, mtr);
flst_write_addr(base + FLST_FIRST, fil_addr_null, mtr); flst_write_addr(base + FLST_FIRST, fil_addr_null, mtr);
flst_write_addr(base + FLST_LAST, fil_addr_null, mtr); flst_write_addr(base + FLST_LAST, fil_addr_null, mtr);
} }
/************************************************************************ /************************************************************************

View File

@ -99,13 +99,15 @@ ha_remove_all_nodes_to_page(
ulint fold, /* in: fold value */ ulint fold, /* in: fold value */
page_t* page); /* in: buffer page */ page_t* page); /* in: buffer page */
/***************************************************************** /*****************************************************************
Validates a hash table. */ Validates a given range of the cells in hash table. */
ibool ibool
ha_validate( ha_validate(
/*========*/ /*========*/
/* out: TRUE if ok */ /* out: TRUE if ok */
hash_table_t* table); /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index); /* in: end index */
/***************************************************************** /*****************************************************************
Prints info of a hash table. */ Prints info of a hash table. */
@ -128,4 +130,4 @@ struct ha_node_struct {
#include "ha0ha.ic" #include "ha0ha.ic"
#endif #endif
#endif #endif

View File

@ -109,8 +109,8 @@ do {\
\ \
while (struct3333->NAME != DATA) {\ while (struct3333->NAME != DATA) {\
\ \
ut_a(struct3333);\
struct3333 = struct3333->NAME;\ struct3333 = struct3333->NAME;\
ut_a(struct3333);\
}\ }\
\ \
struct3333->NAME = DATA->NAME;\ struct3333->NAME = DATA->NAME;\
@ -153,8 +153,8 @@ hash_cell_t*
hash_get_nth_cell( hash_get_nth_cell(
/*==============*/ /*==============*/
/* out: pointer to cell */ /* out: pointer to cell */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint n); /* in: cell index */ ulint n); /* in: cell index */
/***************************************************************** /*****************************************************************
Returns the number of cells in a hash table. */ Returns the number of cells in a hash table. */
UNIV_INLINE UNIV_INLINE
@ -229,8 +229,8 @@ ulint
hash_get_mutex_no( hash_get_mutex_no(
/*==============*/ /*==============*/
/* out: mutex number */ /* out: mutex number */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold); /* in: fold */ ulint fold); /* in: fold */
/**************************************************************** /****************************************************************
Gets the nth heap in a hash table. */ Gets the nth heap in a hash table. */
UNIV_INLINE UNIV_INLINE
@ -238,8 +238,8 @@ mem_heap_t*
hash_get_nth_heap( hash_get_nth_heap(
/*==============*/ /*==============*/
/* out: mem heap */ /* out: mem heap */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint i); /* in: index of the heap */ ulint i); /* in: index of the heap */
/**************************************************************** /****************************************************************
Gets the heap for a fold value in a hash table. */ Gets the heap for a fold value in a hash table. */
UNIV_INLINE UNIV_INLINE
@ -247,8 +247,8 @@ mem_heap_t*
hash_get_heap( hash_get_heap(
/*==========*/ /*==========*/
/* out: mem heap */ /* out: mem heap */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold); /* in: fold */ ulint fold); /* in: fold */
/**************************************************************** /****************************************************************
Gets the nth mutex in a hash table. */ Gets the nth mutex in a hash table. */
UNIV_INLINE UNIV_INLINE
@ -256,8 +256,8 @@ mutex_t*
hash_get_nth_mutex( hash_get_nth_mutex(
/*===============*/ /*===============*/
/* out: mutex */ /* out: mutex */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint i); /* in: index of the mutex */ ulint i); /* in: index of the mutex */
/**************************************************************** /****************************************************************
Gets the mutex for a fold value in a hash table. */ Gets the mutex for a fold value in a hash table. */
UNIV_INLINE UNIV_INLINE
@ -265,38 +265,38 @@ mutex_t*
hash_get_mutex( hash_get_mutex(
/*===========*/ /*===========*/
/* out: mutex */ /* out: mutex */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold); /* in: fold */ ulint fold); /* in: fold */
/**************************************************************** /****************************************************************
Reserves the mutex for a fold value in a hash table. */ Reserves the mutex for a fold value in a hash table. */
void void
hash_mutex_enter( hash_mutex_enter(
/*=============*/ /*=============*/
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold); /* in: fold */ ulint fold); /* in: fold */
/**************************************************************** /****************************************************************
Releases the mutex for a fold value in a hash table. */ Releases the mutex for a fold value in a hash table. */
void void
hash_mutex_exit( hash_mutex_exit(
/*============*/ /*============*/
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold); /* in: fold */ ulint fold); /* in: fold */
/**************************************************************** /****************************************************************
Reserves all the mutexes of a hash table, in an ascending order. */ Reserves all the mutexes of a hash table, in an ascending order. */
void void
hash_mutex_enter_all( hash_mutex_enter_all(
/*=================*/ /*=================*/
hash_table_t* table); /* in: hash table */ hash_table_t* table); /* in: hash table */
/**************************************************************** /****************************************************************
Releases all the mutexes of a hash table. */ Releases all the mutexes of a hash table. */
void void
hash_mutex_exit_all( hash_mutex_exit_all(
/*================*/ /*================*/
hash_table_t* table); /* in: hash table */ hash_table_t* table); /* in: hash table */
struct hash_cell_struct{ struct hash_cell_struct{

View File

@ -15,8 +15,8 @@ hash_cell_t*
hash_get_nth_cell( hash_get_nth_cell(
/*==============*/ /*==============*/
/* out: pointer to cell */ /* out: pointer to cell */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint n) /* in: cell index */ ulint n) /* in: cell index */
{ {
ut_ad(n < table->n_cells); ut_ad(n < table->n_cells);
@ -55,8 +55,8 @@ ulint
hash_get_mutex_no( hash_get_mutex_no(
/*==============*/ /*==============*/
/* out: mutex number */ /* out: mutex number */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold) /* in: fold */ ulint fold) /* in: fold */
{ {
return(ut_2pow_remainder(fold, table->n_mutexes)); return(ut_2pow_remainder(fold, table->n_mutexes));
} }
@ -68,8 +68,8 @@ mem_heap_t*
hash_get_nth_heap( hash_get_nth_heap(
/*==============*/ /*==============*/
/* out: mem heap */ /* out: mem heap */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint i) /* in: index of the heap */ ulint i) /* in: index of the heap */
{ {
ut_ad(i < table->n_mutexes); ut_ad(i < table->n_mutexes);
@ -83,8 +83,8 @@ mem_heap_t*
hash_get_heap( hash_get_heap(
/*==========*/ /*==========*/
/* out: mem heap */ /* out: mem heap */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold) /* in: fold */ ulint fold) /* in: fold */
{ {
ulint i; ulint i;
@ -104,11 +104,11 @@ mutex_t*
hash_get_nth_mutex( hash_get_nth_mutex(
/*===============*/ /*===============*/
/* out: mutex */ /* out: mutex */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint i) /* in: index of the mutex */ ulint i) /* in: index of the mutex */
{ {
ut_ad(i < table->n_mutexes); ut_ad(i < table->n_mutexes);
return(table->mutexes + i); return(table->mutexes + i);
} }
@ -119,8 +119,8 @@ mutex_t*
hash_get_mutex( hash_get_mutex(
/*===========*/ /*===========*/
/* out: mutex */ /* out: mutex */
hash_table_t* table, /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint fold) /* in: fold */ ulint fold) /* in: fold */
{ {
ulint i; ulint i;

View File

@ -180,7 +180,7 @@ ibuf_page_low(
/*************************************************************************** /***************************************************************************
Frees excess pages from the ibuf free list. This function is called when an OS Frees excess pages from the ibuf free list. This function is called when an OS
thread calls fsp services to allocate a new file segment, or a new page to a thread calls fsp services to allocate a new file segment, or a new page to a
file segment, and the thread did not own the fsp latch before this call. */ file segment, and the thread did not own the fsp latch before this call. */
void void
ibuf_free_excess_pages( ibuf_free_excess_pages(
@ -304,4 +304,4 @@ for the file segment from which the pages for the ibuf tree are allocated */
#include "ibuf0ibuf.ic" #include "ibuf0ibuf.ic"
#endif #endif
#endif #endif

View File

@ -41,7 +41,7 @@ struct ibuf_data_struct{
/* If the ibuf meter exceeds this value, then the suitable inserts are made to /* If the ibuf meter exceeds this value, then the suitable inserts are made to
the insert buffer instead of directly to the disk page */ the insert buffer instead of directly to the disk page */
#define IBUF_THRESHOLD 50 #define IBUF_THRESHOLD 50
struct ibuf_struct{ struct ibuf_struct{
ulint size; /* current size of the ibuf index ulint size; /* current size of the ibuf index
@ -88,13 +88,13 @@ ibuf_should_try(
decide */ decide */
{ {
if (!(index->type & DICT_CLUSTERED) if (!(index->type & DICT_CLUSTERED)
&& (ignore_sec_unique || !(index->type & DICT_UNIQUE)) && (ignore_sec_unique || !(index->type & DICT_UNIQUE))
&& ibuf->meter > IBUF_THRESHOLD) { && ibuf->meter > IBUF_THRESHOLD) {
ibuf_flush_count++; ibuf_flush_count++;
if (ibuf_flush_count % 8 == 0) { if (ibuf_flush_count % 8 == 0) {
buf_LRU_try_free_flushed_blocks(); buf_LRU_try_free_flushed_blocks();
} }
@ -132,13 +132,13 @@ ibuf_index_page_calc_free_bits(
for the page */ for the page */
{ {
ulint n; ulint n;
n = max_ins_size / (UNIV_PAGE_SIZE / IBUF_PAGE_SIZE_PER_FREE_SPACE); n = max_ins_size / (UNIV_PAGE_SIZE / IBUF_PAGE_SIZE_PER_FREE_SPACE);
if (n == 3) { if (n == 3) {
n = 2; n = 2;
} }
if (n > 3) { if (n > 3) {
n = 3; n = 3;
} }
@ -206,8 +206,9 @@ ibuf_update_free_bits_if_full(
before = ibuf_index_page_calc_free_bits(max_ins_size); before = ibuf_index_page_calc_free_bits(max_ins_size);
if (max_ins_size >= increase) { if (max_ins_size >= increase) {
ut_ad(ULINT_UNDEFINED > UNIV_PAGE_SIZE); #if ULINT32_UNDEFINED <= UNIV_PAGE_SIZE
# error "ULINT32_UNDEFINED <= UNIV_PAGE_SIZE"
#endif
after = ibuf_index_page_calc_free_bits(max_ins_size after = ibuf_index_page_calc_free_bits(max_ins_size
- increase); - increase);
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG

View File

@ -224,7 +224,7 @@ lock_rec_restore_from_page_infimum(
rec_t* rec, /* in: record whose lock state is restored */ rec_t* rec, /* in: record whose lock state is restored */
page_t* page); /* in: page (rec is not necessarily on this page) page_t* page); /* in: page (rec is not necessarily on this page)
whose infimum stored the lock state; lock bits are whose infimum stored the lock state; lock bits are
reset on the infimum */ reset on the infimum */
/************************************************************************* /*************************************************************************
Returns TRUE if there are explicit record locks on a page. */ Returns TRUE if there are explicit record locks on a page. */
@ -427,7 +427,7 @@ to a lock. */
void void
lock_rec_unlock( lock_rec_unlock(
/*============*/ /*============*/
trx_t* trx, /* in: transaction that has set a record trx_t* trx, /* in: transaction that has set a record
lock */ lock */
rec_t* rec, /* in: record */ rec_t* rec, /* in: record */
ulint lock_mode); /* in: LOCK_S or LOCK_X */ ulint lock_mode); /* in: LOCK_S or LOCK_X */
@ -477,7 +477,7 @@ searching for a lock in the hash table. */
UNIV_INLINE UNIV_INLINE
ulint ulint
lock_rec_fold( lock_rec_fold(
/*===========*/ /*==========*/
/* out: folded value */ /* out: folded value */
ulint space, /* in: space */ ulint space, /* in: space */
ulint page_no);/* in: page number */ ulint page_no);/* in: page number */
@ -624,7 +624,7 @@ extern lock_sys_t* lock_sys;
waiting for its turn in the wait queue */ waiting for its turn in the wait queue */
/* Precise modes */ /* Precise modes */
#define LOCK_ORDINARY 0 /* this flag denotes an ordinary next-key lock #define LOCK_ORDINARY 0 /* this flag denotes an ordinary next-key lock
in contrast to LOCK_GAP or LOCK_REC_NOT_GAP */ in contrast to LOCK_GAP or LOCK_REC_NOT_GAP */
#define LOCK_GAP 512 /* this gap bit should be so high that #define LOCK_GAP 512 /* this gap bit should be so high that
it can be ORed to the other flags; it can be ORed to the other flags;
when this bit is set, it means that the when this bit is set, it means that the
@ -634,7 +634,7 @@ extern lock_sys_t* lock_sys;
the bit is set; locks of this type are created the bit is set; locks of this type are created
when records are removed from the index chain when records are removed from the index chain
of records */ of records */
#define LOCK_REC_NOT_GAP 1024 /* this bit means that the lock is only on #define LOCK_REC_NOT_GAP 1024 /* this bit means that the lock is only on
the index record and does NOT block inserts the index record and does NOT block inserts
to the gap before the index record; this is to the gap before the index record; this is
used in the case when we retrieve a record used in the case when we retrieve a record
@ -650,7 +650,7 @@ extern lock_sys_t* lock_sys;
remains set when the waiting lock is granted, remains set when the waiting lock is granted,
or if the lock is inherited to a neighboring or if the lock is inherited to a neighboring
record */ record */
/* When lock bits are reset, the following flags are available: */ /* When lock bits are reset, the following flags are available: */
#define LOCK_RELEASE_WAIT 1 #define LOCK_RELEASE_WAIT 1
#define LOCK_NOT_RELEASE_WAIT 2 #define LOCK_NOT_RELEASE_WAIT 2
@ -678,4 +678,4 @@ extern lock_sys_t* lock_sys;
#include "lock0lock.ic" #include "lock0lock.ic"
#endif #endif
#endif #endif

View File

@ -13,4 +13,4 @@ Created 5/7/1996 Heikki Tuuri
typedef struct lock_struct lock_t; typedef struct lock_struct lock_t;
typedef struct lock_sys_struct lock_sys_t; typedef struct lock_sys_struct lock_sys_t;
#endif #endif

View File

@ -19,7 +19,7 @@ typedef struct log_group_struct log_group_t;
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
extern ibool log_do_write; extern ibool log_do_write;
extern ibool log_debug_writes; extern ibool log_debug_writes;
#else /* UNIV_DEBUG */ #else /* UNIV_DEBUG */
# define log_do_write TRUE # define log_do_write TRUE
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
@ -493,9 +493,9 @@ Peeks the current lsn. */
ibool ibool
log_peek_lsn( log_peek_lsn(
/*=========*/ /*=========*/
/* out: TRUE if success, FALSE if could not get the /* out: TRUE if success, FALSE if could not get the
log system mutex */ log system mutex */
dulint* lsn); /* out: if returns TRUE, current lsn is here */ dulint* lsn); /* out: if returns TRUE, current lsn is here */
/************************************************************************** /**************************************************************************
Refreshes the statistics used to print per-second averages. */ Refreshes the statistics used to print per-second averages. */
@ -514,7 +514,7 @@ extern log_t* log_sys;
/* The counting of lsn's starts from this value: this must be non-zero */ /* The counting of lsn's starts from this value: this must be non-zero */
#define LOG_START_LSN ut_dulint_create(0, 16 * OS_FILE_LOG_BLOCK_SIZE) #define LOG_START_LSN ut_dulint_create(0, 16 * OS_FILE_LOG_BLOCK_SIZE)
#define LOG_BUFFER_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE) #define LOG_BUFFER_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE)
#define LOG_ARCHIVE_BUF_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE / 4) #define LOG_ARCHIVE_BUF_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE / 4)
/* Offsets of a log block header */ /* Offsets of a log block header */
@ -571,8 +571,8 @@ extern log_t* log_sys;
#define LOG_CHECKPOINT_ARRAY_END (LOG_CHECKPOINT_GROUP_ARRAY\ #define LOG_CHECKPOINT_ARRAY_END (LOG_CHECKPOINT_GROUP_ARRAY\
+ LOG_MAX_N_GROUPS * 8) + LOG_MAX_N_GROUPS * 8)
#define LOG_CHECKPOINT_CHECKSUM_1 LOG_CHECKPOINT_ARRAY_END #define LOG_CHECKPOINT_CHECKSUM_1 LOG_CHECKPOINT_ARRAY_END
#define LOG_CHECKPOINT_CHECKSUM_2 (4 + LOG_CHECKPOINT_ARRAY_END) #define LOG_CHECKPOINT_CHECKSUM_2 (4 + LOG_CHECKPOINT_ARRAY_END)
#define LOG_CHECKPOINT_FSP_FREE_LIMIT (8 + LOG_CHECKPOINT_ARRAY_END) #define LOG_CHECKPOINT_FSP_FREE_LIMIT (8 + LOG_CHECKPOINT_ARRAY_END)
/* current fsp free limit in /* current fsp free limit in
tablespace 0, in units of one tablespace 0, in units of one
@ -678,7 +678,7 @@ struct log_group_struct{
this buffer to the group */ this buffer to the group */
UT_LIST_NODE_T(log_group_t) UT_LIST_NODE_T(log_group_t)
log_groups; /* list of log groups */ log_groups; /* list of log groups */
}; };
struct log_struct{ struct log_struct{
byte pad[64]; /* padding to prevent other memory byte pad[64]; /* padding to prevent other memory
@ -731,13 +731,13 @@ struct log_struct{
be advanced, it is enough that the be advanced, it is enough that the
write i/o has been completed for all write i/o has been completed for all
log groups */ log groups */
dulint write_lsn; /* end lsn for the current running dulint write_lsn; /* end lsn for the current running
write */ write */
ulint write_end_offset;/* the data in buffer has been written ulint write_end_offset;/* the data in buffer has been written
up to this offset when the current up to this offset when the current
write ends: this field will then write ends: this field will then
be copied to buf_next_to_write */ be copied to buf_next_to_write */
dulint current_flush_lsn;/* end lsn for the current running dulint current_flush_lsn;/* end lsn for the current running
write + flush operation */ write + flush operation */
dulint flushed_to_disk_lsn; dulint flushed_to_disk_lsn;
/* how far we have written the log /* how far we have written the log
@ -774,11 +774,11 @@ struct log_struct{
called */ called */
/* Fields involved in checkpoints */ /* Fields involved in checkpoints */
ulint log_group_capacity; /* capacity of the log group; if ulint log_group_capacity; /* capacity of the log group; if
the checkpoint age exceeds this, it is the checkpoint age exceeds this, it is
a serious error because it is possible a serious error because it is possible
we will then overwrite log and spoil we will then overwrite log and spoil
crash recovery */ crash recovery */
ulint max_modified_age_async; ulint max_modified_age_async;
/* when this recommended value for lsn /* when this recommended value for lsn
- buf_pool_get_oldest_modification() - buf_pool_get_oldest_modification()

View File

@ -61,7 +61,7 @@ log_block_set_flush_bit(
} }
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field); mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
} }
/**************************************************************** /****************************************************************
Gets a log block number stored in the header. */ Gets a log block number stored in the header. */
@ -73,7 +73,7 @@ log_block_get_hdr_no(
header */ header */
byte* log_block) /* in: log block */ byte* log_block) /* in: log block */
{ {
return(~LOG_BLOCK_FLUSH_BIT_MASK return(~LOG_BLOCK_FLUSH_BIT_MASK
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)); & mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
} }
@ -90,7 +90,7 @@ log_block_set_hdr_no(
{ {
ut_ad(n > 0); ut_ad(n > 0);
ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK); ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK);
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n); mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
} }
@ -183,7 +183,7 @@ log_block_convert_lsn_to_no(
no = ut_dulint_get_low(lsn) / OS_FILE_LOG_BLOCK_SIZE; no = ut_dulint_get_low(lsn) / OS_FILE_LOG_BLOCK_SIZE;
no += (ut_dulint_get_high(lsn) % OS_FILE_LOG_BLOCK_SIZE) no += (ut_dulint_get_high(lsn) % OS_FILE_LOG_BLOCK_SIZE)
* 2 * (0x80000000UL / OS_FILE_LOG_BLOCK_SIZE); * 2 * (0x80000000UL / OS_FILE_LOG_BLOCK_SIZE);
no = no & 0x3FFFFFFFUL; no = no & 0x3FFFFFFFUL;
return(no + 1); return(no + 1);
@ -201,10 +201,10 @@ log_block_calc_checksum(
ulint sum; ulint sum;
ulint sh; ulint sh;
ulint i; ulint i;
sum = 1; sum = 1;
sh = 0; sh = 0;
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) { for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
sum = sum & 0x7FFFFFFFUL; sum = sum & 0x7FFFFFFFUL;
sum += (((ulint)(*(block + i))) << sh) + (ulint)(*(block + i)); sum += (((ulint)(*(block + i))) << sh) + (ulint)(*(block + i));
@ -260,7 +260,7 @@ log_block_init(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
no = log_block_convert_lsn_to_no(lsn); no = log_block_convert_lsn_to_no(lsn);
log_block_set_hdr_no(log_block, no); log_block_set_hdr_no(log_block, no);
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE); log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
@ -284,14 +284,14 @@ log_block_init_in_old_format(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
no = log_block_convert_lsn_to_no(lsn); no = log_block_convert_lsn_to_no(lsn);
log_block_set_hdr_no(log_block, no); log_block_set_hdr_no(log_block, no);
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
- LOG_BLOCK_CHECKSUM, no); - LOG_BLOCK_CHECKSUM, no);
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE); log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
log_block_set_first_rec_group(log_block, 0); log_block_set_first_rec_group(log_block, 0);
} }
/**************************************************************** /****************************************************************
Writes to the log the string given. The log must be released with Writes to the log the string given. The log must be released with
log_release. */ log_release. */
@ -318,29 +318,29 @@ log_reserve_and_write_fast(
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) { if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
/* The string does not fit within the current log block /* The string does not fit within the current log block
or the log block would become full */ or the log block would become full */
*success = FALSE; *success = FALSE;
mutex_exit(&(log->mutex)); mutex_exit(&(log->mutex));
return(ut_dulint_zero); return(ut_dulint_zero);
} }
*start_lsn = log->lsn; *start_lsn = log->lsn;
ut_memcpy(log->buf + log->buf_free, str, len); ut_memcpy(log->buf + log->buf_free, str, len);
log_block_set_data_len(ut_align_down(log->buf + log->buf_free, log_block_set_data_len(ut_align_down(log->buf + log->buf_free,
OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE),
data_len); data_len);
#ifdef UNIV_LOG_DEBUG #ifdef UNIV_LOG_DEBUG
log->old_buf_free = log->buf_free; log->old_buf_free = log->buf_free;
log->old_lsn = log->lsn; log->old_lsn = log->lsn;
#endif #endif
log->buf_free += len; log->buf_free += len;
ut_ad(log->buf_free <= log->buf_size); ut_ad(log->buf_free <= log->buf_size);
lsn = ut_dulint_add(log->lsn, len); lsn = ut_dulint_add(log->lsn, len);

View File

@ -341,14 +341,14 @@ extern ibool recv_recovery_on;
extern ibool recv_no_ibuf_operations; extern ibool recv_no_ibuf_operations;
extern ibool recv_needed_recovery; extern ibool recv_needed_recovery;
extern ibool recv_lsn_checks_on; extern ibool recv_lsn_checks_on;
#ifdef UNIV_HOTBACKUP #ifdef UNIV_HOTBACKUP
extern ibool recv_is_making_a_backup; extern ibool recv_is_making_a_backup;
#endif /* UNIV_HOTBACKUP */ #endif /* UNIV_HOTBACKUP */
extern ulint recv_max_parsed_page_no; extern ulint recv_max_parsed_page_no;
/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many /* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
times! */ times! */
#define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024) #define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024)
/* Size of block reads when the log groups are scanned forward to do a /* Size of block reads when the log groups are scanned forward to do a

View File

@ -1,6 +1,6 @@
/********************************************************************** /**********************************************************************
Utilities for converting data from the database file Utilities for converting data from the database file
to the machine format. to the machine format.
(c) 1995 Innobase Oy (c) 1995 Innobase Oy
@ -21,37 +21,37 @@ module. */
/*********************************************************** /***********************************************************
The following function is used to store data in one byte. */ The following function is used to store data in one byte. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_1( mach_write_to_1(
/*============*/ /*============*/
byte* b, /* in: pointer to byte where to store */ byte* b, /* in: pointer to byte where to store */
ulint n); /* in: ulint integer to be stored, >= 0, < 256 */ ulint n); /* in: ulint integer to be stored, >= 0, < 256 */
/************************************************************ /************************************************************
The following function is used to fetch data from one byte. */ The following function is used to fetch data from one byte. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_read_from_1( mach_read_from_1(
/*=============*/ /*=============*/
/* out: ulint integer, >= 0, < 256 */ /* out: ulint integer, >= 0, < 256 */
byte* b); /* in: pointer to byte */ byte* b); /* in: pointer to byte */
/*********************************************************** /***********************************************************
The following function is used to store data in two consecutive The following function is used to store data in two consecutive
bytes. We store the most significant byte to the lower address. */ bytes. We store the most significant byte to the lower address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_2( mach_write_to_2(
/*============*/ /*============*/
byte* b, /* in: pointer to two bytes where to store */ byte* b, /* in: pointer to two bytes where to store */
ulint n); /* in: ulint integer to be stored, >= 0, < 64k */ ulint n); /* in: ulint integer to be stored, >= 0, < 64k */
/************************************************************ /************************************************************
The following function is used to fetch data from two consecutive The following function is used to fetch data from two consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_read_from_2( mach_read_from_2(
/*=============*/ /*=============*/
/* out: ulint integer, >= 0, < 64k */ /* out: ulint integer, >= 0, < 64k */
byte* b); /* in: pointer to two bytes */ byte* b); /* in: pointer to two bytes */
/************************************************************ /************************************************************
The following function is used to convert a 16-bit data item The following function is used to convert a 16-bit data item
@ -77,38 +77,38 @@ mach_decode_2(
The following function is used to store data in 3 consecutive The following function is used to store data in 3 consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_3( mach_write_to_3(
/*============*/ /*============*/
byte* b, /* in: pointer to 3 bytes where to store */ byte* b, /* in: pointer to 3 bytes where to store */
ulint n); /* in: ulint integer to be stored */ ulint n); /* in: ulint integer to be stored */
/************************************************************ /************************************************************
The following function is used to fetch data from 3 consecutive The following function is used to fetch data from 3 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_read_from_3( mach_read_from_3(
/*=============*/ /*=============*/
/* out: ulint integer */ /* out: ulint integer */
byte* b); /* in: pointer to 3 bytes */ byte* b); /* in: pointer to 3 bytes */
/*********************************************************** /***********************************************************
The following function is used to store data in four consecutive The following function is used to store data in four consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_4( mach_write_to_4(
/*============*/ /*============*/
byte* b, /* in: pointer to four bytes where to store */ byte* b, /* in: pointer to four bytes where to store */
ulint n); /* in: ulint integer to be stored */ ulint n); /* in: ulint integer to be stored */
/************************************************************ /************************************************************
The following function is used to fetch data from 4 consecutive The following function is used to fetch data from 4 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_read_from_4( mach_read_from_4(
/*=============*/ /*=============*/
/* out: ulint integer */ /* out: ulint integer */
byte* b); /* in: pointer to four bytes */ byte* b); /* in: pointer to four bytes */
/************************************************************* /*************************************************************
Writes a ulint in a compressed form (1..5 bytes). */ Writes a ulint in a compressed form (1..5 bytes). */
UNIV_INLINE UNIV_INLINE
@ -116,8 +116,8 @@ ulint
mach_write_compressed( mach_write_compressed(
/*==================*/ /*==================*/
/* out: stored size in bytes */ /* out: stored size in bytes */
byte* b, /* in: pointer to memory where to store */ byte* b, /* in: pointer to memory where to store */
ulint n); /* in: ulint integer to be stored */ ulint n); /* in: ulint integer to be stored */
/************************************************************* /*************************************************************
Returns the size of an ulint when written in the compressed form. */ Returns the size of an ulint when written in the compressed form. */
UNIV_INLINE UNIV_INLINE
@ -125,7 +125,7 @@ ulint
mach_get_compressed_size( mach_get_compressed_size(
/*=====================*/ /*=====================*/
/* out: compressed size in bytes */ /* out: compressed size in bytes */
ulint n); /* in: ulint integer to be stored */ ulint n); /* in: ulint integer to be stored */
/************************************************************* /*************************************************************
Reads a ulint in a compressed form. */ Reads a ulint in a compressed form. */
UNIV_INLINE UNIV_INLINE
@ -133,61 +133,61 @@ ulint
mach_read_compressed( mach_read_compressed(
/*=================*/ /*=================*/
/* out: read integer */ /* out: read integer */
byte* b); /* in: pointer to memory from where to read */ byte* b); /* in: pointer to memory from where to read */
/*********************************************************** /***********************************************************
The following function is used to store data in 6 consecutive The following function is used to store data in 6 consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_6( mach_write_to_6(
/*============*/ /*============*/
byte* b, /* in: pointer to 6 bytes where to store */ byte* b, /* in: pointer to 6 bytes where to store */
dulint n); /* in: dulint integer to be stored */ dulint n); /* in: dulint integer to be stored */
/************************************************************ /************************************************************
The following function is used to fetch data from 6 consecutive The following function is used to fetch data from 6 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
dulint dulint
mach_read_from_6( mach_read_from_6(
/*=============*/ /*=============*/
/* out: dulint integer */ /* out: dulint integer */
byte* b); /* in: pointer to 6 bytes */ byte* b); /* in: pointer to 6 bytes */
/*********************************************************** /***********************************************************
The following function is used to store data in 7 consecutive The following function is used to store data in 7 consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_7( mach_write_to_7(
/*============*/ /*============*/
byte* b, /* in: pointer to 7 bytes where to store */ byte* b, /* in: pointer to 7 bytes where to store */
dulint n); /* in: dulint integer to be stored */ dulint n); /* in: dulint integer to be stored */
/************************************************************ /************************************************************
The following function is used to fetch data from 7 consecutive The following function is used to fetch data from 7 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
dulint dulint
mach_read_from_7( mach_read_from_7(
/*=============*/ /*=============*/
/* out: dulint integer */ /* out: dulint integer */
byte* b); /* in: pointer to 7 bytes */ byte* b); /* in: pointer to 7 bytes */
/*********************************************************** /***********************************************************
The following function is used to store data in 8 consecutive The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_8( mach_write_to_8(
/*============*/ /*============*/
byte* b, /* in: pointer to 8 bytes where to store */ byte* b, /* in: pointer to 8 bytes where to store */
dulint n); /* in: dulint integer to be stored */ dulint n); /* in: dulint integer to be stored */
/************************************************************ /************************************************************
The following function is used to fetch data from 8 consecutive The following function is used to fetch data from 8 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
dulint dulint
mach_read_from_8( mach_read_from_8(
/*=============*/ /*=============*/
/* out: dulint integer */ /* out: dulint integer */
byte* b); /* in: pointer to 8 bytes */ byte* b); /* in: pointer to 8 bytes */
/************************************************************* /*************************************************************
Writes a dulint in a compressed form (5..9 bytes). */ Writes a dulint in a compressed form (5..9 bytes). */
UNIV_INLINE UNIV_INLINE
@ -195,8 +195,8 @@ ulint
mach_dulint_write_compressed( mach_dulint_write_compressed(
/*=========================*/ /*=========================*/
/* out: size in bytes */ /* out: size in bytes */
byte* b, /* in: pointer to memory where to store */ byte* b, /* in: pointer to memory where to store */
dulint n); /* in: dulint integer to be stored */ dulint n); /* in: dulint integer to be stored */
/************************************************************* /*************************************************************
Returns the size of a dulint when written in the compressed form. */ Returns the size of a dulint when written in the compressed form. */
UNIV_INLINE UNIV_INLINE
@ -204,7 +204,7 @@ ulint
mach_dulint_get_compressed_size( mach_dulint_get_compressed_size(
/*============================*/ /*============================*/
/* out: compressed size in bytes */ /* out: compressed size in bytes */
dulint n); /* in: dulint integer to be stored */ dulint n); /* in: dulint integer to be stored */
/************************************************************* /*************************************************************
Reads a dulint in a compressed form. */ Reads a dulint in a compressed form. */
UNIV_INLINE UNIV_INLINE
@ -212,7 +212,7 @@ dulint
mach_dulint_read_compressed( mach_dulint_read_compressed(
/*========================*/ /*========================*/
/* out: read dulint */ /* out: read dulint */
byte* b); /* in: pointer to memory from where to read */ byte* b); /* in: pointer to memory from where to read */
/************************************************************* /*************************************************************
Writes a dulint in a compressed form (1..11 bytes). */ Writes a dulint in a compressed form (1..11 bytes). */
UNIV_INLINE UNIV_INLINE
@ -220,8 +220,8 @@ ulint
mach_dulint_write_much_compressed( mach_dulint_write_much_compressed(
/*==============================*/ /*==============================*/
/* out: size in bytes */ /* out: size in bytes */
byte* b, /* in: pointer to memory where to store */ byte* b, /* in: pointer to memory where to store */
dulint n); /* in: dulint integer to be stored */ dulint n); /* in: dulint integer to be stored */
/************************************************************* /*************************************************************
Returns the size of a dulint when written in the compressed form. */ Returns the size of a dulint when written in the compressed form. */
UNIV_INLINE UNIV_INLINE
@ -229,7 +229,7 @@ ulint
mach_dulint_get_much_compressed_size( mach_dulint_get_much_compressed_size(
/*=================================*/ /*=================================*/
/* out: compressed size in bytes */ /* out: compressed size in bytes */
dulint n); /* in: dulint integer to be stored */ dulint n); /* in: dulint integer to be stored */
/************************************************************* /*************************************************************
Reads a dulint in a compressed form. */ Reads a dulint in a compressed form. */
UNIV_INLINE UNIV_INLINE
@ -237,7 +237,7 @@ dulint
mach_dulint_read_much_compressed( mach_dulint_read_much_compressed(
/*=============================*/ /*=============================*/
/* out: read dulint */ /* out: read dulint */
byte* b); /* in: pointer to memory from where to read */ byte* b); /* in: pointer to memory from where to read */
/************************************************************* /*************************************************************
Reads a ulint in a compressed form if the log record fully contains it. */ Reads a ulint in a compressed form if the log record fully contains it. */
@ -246,9 +246,9 @@ mach_parse_compressed(
/*==================*/ /*==================*/
/* out: pointer to end of the stored field, NULL if /* out: pointer to end of the stored field, NULL if
not complete */ not complete */
byte* ptr, /* in: pointer to buffer from where to read */ byte* ptr, /* in: pointer to buffer from where to read */
byte* end_ptr,/* in: pointer to end of the buffer */ byte* end_ptr,/* in: pointer to end of the buffer */
ulint* val); /* out: read value */ ulint* val); /* out: read value */
/************************************************************* /*************************************************************
Reads a dulint in a compressed form if the log record fully contains it. */ Reads a dulint in a compressed form if the log record fully contains it. */
@ -257,9 +257,9 @@ mach_dulint_parse_compressed(
/*=========================*/ /*=========================*/
/* out: pointer to end of the stored field, NULL if /* out: pointer to end of the stored field, NULL if
not complete */ not complete */
byte* ptr, /* in: pointer to buffer from where to read */ byte* ptr, /* in: pointer to buffer from where to read */
byte* end_ptr,/* in: pointer to end of the buffer */ byte* end_ptr,/* in: pointer to end of the buffer */
dulint* val); /* out: read value */ dulint* val); /* out: read value */
/************************************************************* /*************************************************************
Reads a double. It is stored in a little-endian format. */ Reads a double. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
@ -267,31 +267,31 @@ double
mach_double_read( mach_double_read(
/*=============*/ /*=============*/
/* out: double read */ /* out: double read */
byte* b); /* in: pointer to memory from where to read */ byte* b); /* in: pointer to memory from where to read */
/************************************************************* /*************************************************************
Writes a double. It is stored in a little-endian format. */ Writes a double. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
void void
mach_double_write( mach_double_write(
/*==============*/ /*==============*/
byte* b, /* in: pointer to memory where to write */ byte* b, /* in: pointer to memory where to write */
double d); /* in: double */ double d); /* in: double */
/************************************************************* /*************************************************************
Reads a float. It is stored in a little-endian format. */ Reads a float. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
float float
mach_float_read( mach_float_read(
/*=============*/ /*============*/
/* out: float read */ /* out: float read */
byte* b); /* in: pointer to memory from where to read */ byte* b); /* in: pointer to memory from where to read */
/************************************************************* /*************************************************************
Writes a float. It is stored in a little-endian format. */ Writes a float. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
void void
mach_float_write( mach_float_write(
/*==============*/ /*=============*/
byte* b, /* in: pointer to memory where to write */ byte* b, /* in: pointer to memory where to write */
float d); /* in: float */ float d); /* in: float */
/************************************************************* /*************************************************************
Reads a ulint stored in the little-endian format. */ Reads a ulint stored in the little-endian format. */
UNIV_INLINE UNIV_INLINE
@ -326,7 +326,7 @@ mach_write_to_2_little_endian(
/*==========================*/ /*==========================*/
byte* dest, /* in: where to write */ byte* dest, /* in: where to write */
ulint n); /* in: unsigned long int to write */ ulint n); /* in: unsigned long int to write */
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "mach0data.ic" #include "mach0data.ic"
#endif #endif

View File

@ -1,6 +1,6 @@
/********************************************************************** /**********************************************************************
Utilities for converting data from the database file Utilities for converting data from the database file
to the machine format. to the machine format.
(c) 1995 Innobase Oy (c) 1995 Innobase Oy
@ -10,11 +10,11 @@ Created 11/28/1995 Heikki Tuuri
/*********************************************************** /***********************************************************
The following function is used to store data in one byte. */ The following function is used to store data in one byte. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_1( mach_write_to_1(
/*============*/ /*============*/
byte* b, /* in: pointer to byte where to store */ byte* b, /* in: pointer to byte where to store */
ulint n) /* in: ulint integer to be stored, >= 0, < 256 */ ulint n) /* in: ulint integer to be stored, >= 0, < 256 */
{ {
ut_ad(b); ut_ad(b);
ut_ad(n <= 0xFFUL); ut_ad(n <= 0xFFUL);
@ -25,11 +25,11 @@ mach_write_to_1(
/************************************************************ /************************************************************
The following function is used to fetch data from one byte. */ The following function is used to fetch data from one byte. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_read_from_1( mach_read_from_1(
/*=============*/ /*=============*/
/* out: ulint integer, >= 0, < 256 */ /* out: ulint integer, >= 0, < 256 */
byte* b) /* in: pointer to byte */ byte* b) /* in: pointer to byte */
{ {
ut_ad(b); ut_ad(b);
return((ulint)(b[0])); return((ulint)(b[0]));
@ -39,11 +39,11 @@ mach_read_from_1(
The following function is used to store data in two consecutive The following function is used to store data in two consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_2( mach_write_to_2(
/*============*/ /*============*/
byte* b, /* in: pointer to two bytes where to store */ byte* b, /* in: pointer to two bytes where to store */
ulint n) /* in: ulint integer to be stored */ ulint n) /* in: ulint integer to be stored */
{ {
ut_ad(b); ut_ad(b);
ut_ad(n <= 0xFFFFUL); ut_ad(n <= 0xFFFFUL);
@ -56,16 +56,16 @@ mach_write_to_2(
The following function is used to fetch data from 2 consecutive The following function is used to fetch data from 2 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_read_from_2( mach_read_from_2(
/*=============*/ /*=============*/
/* out: ulint integer */ /* out: ulint integer */
byte* b) /* in: pointer to 2 bytes */ byte* b) /* in: pointer to 2 bytes */
{ {
ut_ad(b); ut_ad(b);
return( ((ulint)(b[0]) << 8) return( ((ulint)(b[0]) << 8)
+ (ulint)(b[1]) + (ulint)(b[1])
); );
} }
/************************************************************ /************************************************************
@ -103,11 +103,11 @@ mach_decode_2(
The following function is used to store data in 3 consecutive The following function is used to store data in 3 consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_3( mach_write_to_3(
/*============*/ /*============*/
byte* b, /* in: pointer to 3 bytes where to store */ byte* b, /* in: pointer to 3 bytes where to store */
ulint n) /* in: ulint integer to be stored */ ulint n) /* in: ulint integer to be stored */
{ {
ut_ad(b); ut_ad(b);
ut_ad(n <= 0xFFFFFFUL); ut_ad(n <= 0xFFFFFFUL);
@ -121,28 +121,28 @@ mach_write_to_3(
The following function is used to fetch data from 3 consecutive The following function is used to fetch data from 3 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_read_from_3( mach_read_from_3(
/*=============*/ /*=============*/
/* out: ulint integer */ /* out: ulint integer */
byte* b) /* in: pointer to 3 bytes */ byte* b) /* in: pointer to 3 bytes */
{ {
ut_ad(b); ut_ad(b);
return( ((ulint)(b[0]) << 16) return( ((ulint)(b[0]) << 16)
+ ((ulint)(b[1]) << 8) + ((ulint)(b[1]) << 8)
+ (ulint)(b[2]) + (ulint)(b[2])
); );
} }
/*********************************************************** /***********************************************************
The following function is used to store data in four consecutive The following function is used to store data in four consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_4( mach_write_to_4(
/*============*/ /*============*/
byte* b, /* in: pointer to four bytes where to store */ byte* b, /* in: pointer to four bytes where to store */
ulint n) /* in: ulint integer to be stored */ ulint n) /* in: ulint integer to be stored */
{ {
ut_ad(b); ut_ad(b);
@ -154,7 +154,7 @@ mach_write_to_4(
__asm MOV EAX, n __asm MOV EAX, n
__asm BSWAP EAX /* Intel is little-endian, must swap bytes */ __asm BSWAP EAX /* Intel is little-endian, must swap bytes */
__asm MOV n, EAX __asm MOV n, EAX
*((ulint*)b) = n; *((ulint*)b) = n;
#else #else
b[0] = (byte)(n >> 24); b[0] = (byte)(n >> 24);
@ -168,11 +168,11 @@ mach_write_to_4(
The following function is used to fetch data from 4 consecutive The following function is used to fetch data from 4 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_read_from_4( mach_read_from_4(
/*=============*/ /*=============*/
/* out: ulint integer */ /* out: ulint integer */
byte* b) /* in: pointer to four bytes */ byte* b) /* in: pointer to four bytes */
{ {
#if (0 == 1) && !defined(__STDC__) && defined(UNIV_INTEL) && (UNIV_WORD_SIZE == 4) && defined(UNIV_VISUALC) #if (0 == 1) && !defined(__STDC__) && defined(UNIV_INTEL) && (UNIV_WORD_SIZE == 4) && defined(UNIV_VISUALC)
/* We do not use this even on Intel, because unaligned accesses may /* We do not use this even on Intel, because unaligned accesses may
@ -194,7 +194,7 @@ mach_read_from_4(
+ ((ulint)(b[1]) << 16) + ((ulint)(b[1]) << 16)
+ ((ulint)(b[2]) << 8) + ((ulint)(b[2]) << 8)
+ (ulint)(b[3]) + (ulint)(b[3])
); );
#endif #endif
} }
@ -203,15 +203,15 @@ Writes a ulint in a compressed form where the first byte codes the
length of the stored ulint. We look at the most significant bits of length of the stored ulint. We look at the most significant bits of
the byte. If the most significant bit is zero, it means 1-byte storage, the byte. If the most significant bit is zero, it means 1-byte storage,
else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0, else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,
it means 3-byte storage, else if 4th is 0, it means 4-byte storage, it means 3-byte storage, else if 4th is 0, it means 4-byte storage,
else the storage is 5-byte. */ else the storage is 5-byte. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mach_write_compressed( mach_write_compressed(
/*==================*/ /*==================*/
/* out: compressed size in bytes */ /* out: compressed size in bytes */
byte* b, /* in: pointer to memory where to store */ byte* b, /* in: pointer to memory where to store */
ulint n) /* in: ulint integer (< 2^32) to be stored */ ulint n) /* in: ulint integer (< 2^32) to be stored */
{ {
ut_ad(b); ut_ad(b);
@ -241,7 +241,7 @@ ulint
mach_get_compressed_size( mach_get_compressed_size(
/*=====================*/ /*=====================*/
/* out: compressed size in bytes */ /* out: compressed size in bytes */
ulint n) /* in: ulint integer (< 2^32) to be stored */ ulint n) /* in: ulint integer (< 2^32) to be stored */
{ {
if (n < 0x80UL) { if (n < 0x80UL) {
return(1); return(1);
@ -263,7 +263,7 @@ ulint
mach_read_compressed( mach_read_compressed(
/*=================*/ /*=================*/
/* out: read integer (< 2^32) */ /* out: read integer (< 2^32) */
byte* b) /* in: pointer to memory from where to read */ byte* b) /* in: pointer to memory from where to read */
{ {
ulint flag; ulint flag;
@ -289,11 +289,11 @@ mach_read_compressed(
The following function is used to store data in 8 consecutive The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_8( mach_write_to_8(
/*============*/ /*============*/
byte* b, /* in: pointer to 8 bytes where to store */ byte* b, /* in: pointer to 8 bytes where to store */
dulint n) /* in: dulint integer to be stored */ dulint n) /* in: dulint integer to be stored */
{ {
ut_ad(b); ut_ad(b);
@ -305,11 +305,11 @@ mach_write_to_8(
The following function is used to fetch data from 8 consecutive The following function is used to fetch data from 8 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
dulint dulint
mach_read_from_8( mach_read_from_8(
/*=============*/ /*=============*/
/* out: dulint integer */ /* out: dulint integer */
byte* b) /* in: pointer to 8 bytes */ byte* b) /* in: pointer to 8 bytes */
{ {
ulint high; ulint high;
ulint low; ulint low;
@ -319,18 +319,18 @@ mach_read_from_8(
high = mach_read_from_4(b); high = mach_read_from_4(b);
low = mach_read_from_4(b + 4); low = mach_read_from_4(b + 4);
return(ut_dulint_create(high, low)); return(ut_dulint_create(high, low));
} }
/*********************************************************** /***********************************************************
The following function is used to store data in 7 consecutive The following function is used to store data in 7 consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_7( mach_write_to_7(
/*============*/ /*============*/
byte* b, /* in: pointer to 7 bytes where to store */ byte* b, /* in: pointer to 7 bytes where to store */
dulint n) /* in: dulint integer to be stored */ dulint n) /* in: dulint integer to be stored */
{ {
ut_ad(b); ut_ad(b);
@ -342,11 +342,11 @@ mach_write_to_7(
The following function is used to fetch data from 7 consecutive The following function is used to fetch data from 7 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
dulint dulint
mach_read_from_7( mach_read_from_7(
/*=============*/ /*=============*/
/* out: dulint integer */ /* out: dulint integer */
byte* b) /* in: pointer to 7 bytes */ byte* b) /* in: pointer to 7 bytes */
{ {
ulint high; ulint high;
ulint low; ulint low;
@ -356,18 +356,18 @@ mach_read_from_7(
high = mach_read_from_3(b); high = mach_read_from_3(b);
low = mach_read_from_4(b + 3); low = mach_read_from_4(b + 3);
return(ut_dulint_create(high, low)); return(ut_dulint_create(high, low));
} }
/*********************************************************** /***********************************************************
The following function is used to store data in 6 consecutive The following function is used to store data in 6 consecutive
bytes. We store the most significant byte to the lowest address. */ bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE UNIV_INLINE
void void
mach_write_to_6( mach_write_to_6(
/*============*/ /*============*/
byte* b, /* in: pointer to 6 bytes where to store */ byte* b, /* in: pointer to 6 bytes where to store */
dulint n) /* in: dulint integer to be stored */ dulint n) /* in: dulint integer to be stored */
{ {
ut_ad(b); ut_ad(b);
@ -379,11 +379,11 @@ mach_write_to_6(
The following function is used to fetch data from 6 consecutive The following function is used to fetch data from 6 consecutive
bytes. The most significant byte is at the lowest address. */ bytes. The most significant byte is at the lowest address. */
UNIV_INLINE UNIV_INLINE
dulint dulint
mach_read_from_6( mach_read_from_6(
/*=============*/ /*=============*/
/* out: dulint integer */ /* out: dulint integer */
byte* b) /* in: pointer to 7 bytes */ byte* b) /* in: pointer to 7 bytes */
{ {
ulint high; ulint high;
ulint low; ulint low;
@ -393,7 +393,7 @@ mach_read_from_6(
high = mach_read_from_2(b); high = mach_read_from_2(b);
low = mach_read_from_4(b + 2); low = mach_read_from_4(b + 2);
return(ut_dulint_create(high, low)); return(ut_dulint_create(high, low));
} }
/************************************************************* /*************************************************************
@ -403,8 +403,8 @@ ulint
mach_dulint_write_compressed( mach_dulint_write_compressed(
/*=========================*/ /*=========================*/
/* out: size in bytes */ /* out: size in bytes */
byte* b, /* in: pointer to memory where to store */ byte* b, /* in: pointer to memory where to store */
dulint n) /* in: dulint integer to be stored */ dulint n) /* in: dulint integer to be stored */
{ {
ulint size; ulint size;
@ -423,7 +423,7 @@ ulint
mach_dulint_get_compressed_size( mach_dulint_get_compressed_size(
/*============================*/ /*============================*/
/* out: compressed size in bytes */ /* out: compressed size in bytes */
dulint n) /* in: dulint integer to be stored */ dulint n) /* in: dulint integer to be stored */
{ {
return(4 + mach_get_compressed_size(ut_dulint_get_high(n))); return(4 + mach_get_compressed_size(ut_dulint_get_high(n)));
} }
@ -435,7 +435,7 @@ dulint
mach_dulint_read_compressed( mach_dulint_read_compressed(
/*========================*/ /*========================*/
/* out: read dulint */ /* out: read dulint */
byte* b) /* in: pointer to memory from where to read */ byte* b) /* in: pointer to memory from where to read */
{ {
ulint high; ulint high;
ulint low; ulint low;
@ -449,7 +449,7 @@ mach_dulint_read_compressed(
low = mach_read_from_4(b + size); low = mach_read_from_4(b + size);
return(ut_dulint_create(high, low)); return(ut_dulint_create(high, low));
} }
/************************************************************* /*************************************************************
@ -459,17 +459,17 @@ ulint
mach_dulint_write_much_compressed( mach_dulint_write_much_compressed(
/*==============================*/ /*==============================*/
/* out: size in bytes */ /* out: size in bytes */
byte* b, /* in: pointer to memory where to store */ byte* b, /* in: pointer to memory where to store */
dulint n) /* in: dulint integer to be stored */ dulint n) /* in: dulint integer to be stored */
{ {
ulint size; ulint size;
ut_ad(b); ut_ad(b);
if (ut_dulint_get_high(n) == 0) { if (ut_dulint_get_high(n) == 0) {
return(mach_write_compressed(b, ut_dulint_get_low(n))); return(mach_write_compressed(b, ut_dulint_get_low(n)));
} }
*b = (byte)0xFF; *b = (byte)0xFF;
size = 1 + mach_write_compressed(b + 1, ut_dulint_get_high(n)); size = 1 + mach_write_compressed(b + 1, ut_dulint_get_high(n));
@ -485,14 +485,14 @@ ulint
mach_dulint_get_much_compressed_size( mach_dulint_get_much_compressed_size(
/*=================================*/ /*=================================*/
/* out: compressed size in bytes */ /* out: compressed size in bytes */
dulint n) /* in: dulint integer to be stored */ dulint n) /* in: dulint integer to be stored */
{ {
if (0 == ut_dulint_get_high(n)) { if (0 == ut_dulint_get_high(n)) {
return(mach_get_compressed_size(ut_dulint_get_low(n))); return(mach_get_compressed_size(ut_dulint_get_low(n)));
} }
return(1 + mach_get_compressed_size(ut_dulint_get_high(n)) return(1 + mach_get_compressed_size(ut_dulint_get_high(n))
+ mach_get_compressed_size(ut_dulint_get_low(n))); + mach_get_compressed_size(ut_dulint_get_low(n)));
} }
/************************************************************* /*************************************************************
@ -502,7 +502,7 @@ dulint
mach_dulint_read_much_compressed( mach_dulint_read_much_compressed(
/*=============================*/ /*=============================*/
/* out: read dulint */ /* out: read dulint */
byte* b) /* in: pointer to memory from where to read */ byte* b) /* in: pointer to memory from where to read */
{ {
ulint high; ulint high;
ulint low; ulint low;
@ -521,7 +521,7 @@ mach_dulint_read_much_compressed(
low = mach_read_compressed(b + size); low = mach_read_compressed(b + size);
return(ut_dulint_create(high, low)); return(ut_dulint_create(high, low));
} }
/************************************************************* /*************************************************************
@ -531,9 +531,9 @@ double
mach_double_read( mach_double_read(
/*=============*/ /*=============*/
/* out: double read */ /* out: double read */
byte* b) /* in: pointer to memory from where to read */ byte* b) /* in: pointer to memory from where to read */
{ {
double d; double d;
ulint i; ulint i;
byte* ptr; byte* ptr;
@ -547,7 +547,7 @@ mach_double_read(
#endif #endif
} }
return(d); return(d);
} }
/************************************************************* /*************************************************************
@ -556,8 +556,8 @@ UNIV_INLINE
void void
mach_double_write( mach_double_write(
/*==============*/ /*==============*/
byte* b, /* in: pointer to memory where to write */ byte* b, /* in: pointer to memory where to write */
double d) /* in: double */ double d) /* in: double */
{ {
ulint i; ulint i;
byte* ptr; byte* ptr;
@ -578,11 +578,11 @@ Reads a float. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
float float
mach_float_read( mach_float_read(
/*=============*/ /*============*/
/* out: float read */ /* out: float read */
byte* b) /* in: pointer to memory from where to read */ byte* b) /* in: pointer to memory from where to read */
{ {
float d; float d;
ulint i; ulint i;
byte* ptr; byte* ptr;
@ -596,7 +596,7 @@ mach_float_read(
#endif #endif
} }
return(d); return(d);
} }
/************************************************************* /*************************************************************
@ -604,9 +604,9 @@ Writes a float. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
void void
mach_float_write( mach_float_write(
/*==============*/ /*=============*/
byte* b, /* in: pointer to memory where to write */ byte* b, /* in: pointer to memory where to write */
float d) /* in: float */ float d) /* in: float */
{ {
ulint i; ulint i;
byte* ptr; byte* ptr;
@ -639,7 +639,7 @@ mach_read_from_n_little_endian(
ut_ad(buf_size > 0); ut_ad(buf_size > 0);
ptr = buf + buf_size; ptr = buf + buf_size;
for (;;) { for (;;) {
ptr--; ptr--;
@ -671,7 +671,7 @@ mach_write_to_n_little_endian(
ut_ad(dest_size > 0); ut_ad(dest_size > 0);
end = dest + dest_size; end = dest + dest_size;
for (;;) { for (;;) {
*dest = (byte)(n & 0xFF); *dest = (byte)(n & 0xFF);
@ -681,7 +681,7 @@ mach_write_to_n_little_endian(
if (dest == end) { if (dest == end) {
break; break;
} }
} }
ut_ad(n == 0); ut_ad(n == 0);

View File

@ -11,11 +11,11 @@ Created 6/9/1994 Heikki Tuuri
check fields whose sizes are given below */ check fields whose sizes are given below */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
#define MEM_FIELD_HEADER_SIZE ut_calc_align(2 * sizeof(ulint),\ #define MEM_FIELD_HEADER_SIZE ut_calc_align(2 * sizeof(ulint),\
UNIV_MEM_ALIGNMENT) UNIV_MEM_ALIGNMENT)
#define MEM_FIELD_TRAILER_SIZE sizeof(ulint) #define MEM_FIELD_TRAILER_SIZE sizeof(ulint)
#else #else
#define MEM_FIELD_HEADER_SIZE 0 #define MEM_FIELD_HEADER_SIZE 0
#endif #endif
@ -25,8 +25,7 @@ UNIV_MEM_ALIGNMENT. In the debug version there are also
check fields at the both ends of the field. */ check fields at the both ends of the field. */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
#define MEM_SPACE_NEEDED(N) ut_calc_align((N) + MEM_FIELD_HEADER_SIZE\ #define MEM_SPACE_NEEDED(N) ut_calc_align((N) + MEM_FIELD_HEADER_SIZE\
+ MEM_FIELD_TRAILER_SIZE,\ + MEM_FIELD_TRAILER_SIZE, UNIV_MEM_ALIGNMENT)
UNIV_MEM_ALIGNMENT)
#else #else
#define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT) #define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT)
#endif #endif
@ -41,23 +40,23 @@ of blocks. */
void void
mem_heap_validate_or_print( mem_heap_validate_or_print(
/*=======================*/ /*=======================*/
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
byte* top, /* in: calculate and validate only until byte* top, /* in: calculate and validate only until
this top pointer in the heap is reached, this top pointer in the heap is reached,
if this pointer is NULL, ignored */ if this pointer is NULL, ignored */
ibool print, /* in: if TRUE, prints the contents ibool print, /* in: if TRUE, prints the contents
of the heap; works only in of the heap; works only in
the debug version */ the debug version */
ibool* error, /* out: TRUE if error */ ibool* error, /* out: TRUE if error */
ulint* us_size,/* out: allocated memory ulint* us_size,/* out: allocated memory
(for the user) in the heap, (for the user) in the heap,
if a NULL pointer is passed as this if a NULL pointer is passed as this
argument, it is ignored; in the argument, it is ignored; in the
non-debug version this is always -1 */ non-debug version this is always -1 */
ulint* ph_size,/* out: physical size of the heap, ulint* ph_size,/* out: physical size of the heap,
if a NULL pointer is passed as this if a NULL pointer is passed as this
argument, it is ignored */ argument, it is ignored */
ulint* n_blocks); /* out: number of blocks in the heap, ulint* n_blocks); /* out: number of blocks in the heap,
if a NULL pointer is passed as this if a NULL pointer is passed as this
argument, it is ignored */ argument, it is ignored */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
@ -115,7 +114,7 @@ the neighborhood of a given pointer. */
void void
mem_analyze_corruption( mem_analyze_corruption(
/*===================*/ /*===================*/
byte* ptr); /* in: pointer to place of possible corruption */ void* ptr); /* in: pointer to place of possible corruption */
/********************************************************************* /*********************************************************************
Prints information of dynamic memory usage and currently allocated memory Prints information of dynamic memory usage and currently allocated memory
heaps or buffers. Can only be used in the debug version. */ heaps or buffers. Can only be used in the debug version. */

View File

@ -34,8 +34,8 @@ Used to initialize allocated memory. */
void void
mem_init_buf( mem_init_buf(
/*=========*/ /*=========*/
byte* buf, /* in: pointer to buffer */ byte* buf, /* in: pointer to buffer */
ulint n); /* in: length of buffer */ ulint n); /* in: length of buffer */
/******************************************************************* /*******************************************************************
Initializes a buffer to a random combination of hex DE and AD. Initializes a buffer to a random combination of hex DE and AD.
Used to erase freed memory.*/ Used to erase freed memory.*/
@ -43,8 +43,8 @@ Used to erase freed memory.*/
void void
mem_erase_buf( mem_erase_buf(
/*==========*/ /*==========*/
byte* buf, /* in: pointer to buffer */ byte* buf, /* in: pointer to buffer */
ulint n); /* in: length of buffer */ ulint n); /* in: length of buffer */
/******************************************************************* /*******************************************************************
Inserts a created memory heap to the hash table of Inserts a created memory heap to the hash table of
current allocated memory heaps. current allocated memory heaps.

View File

@ -49,8 +49,8 @@ the size is not specified, i.e., 0 is given as the parameter in the call of
create. The standard size is the maximum (payload) size of the blocks used for create. The standard size is the maximum (payload) size of the blocks used for
allocations of small buffers. */ allocations of small buffers. */
#define MEM_BLOCK_START_SIZE 64 #define MEM_BLOCK_START_SIZE 64
#define MEM_BLOCK_STANDARD_SIZE 8000 #define MEM_BLOCK_STANDARD_SIZE 8000
/* If a memory heap is allowed to grow into the buffer pool, the following /* If a memory heap is allowed to grow into the buffer pool, the following
is the maximum size for a single allocated buffer: */ is the maximum size for a single allocated buffer: */
@ -67,24 +67,21 @@ mem_init(
Use this macro instead of the corresponding function! Macro for memory Use this macro instead of the corresponding function! Macro for memory
heap creation. */ heap creation. */
#define mem_heap_create(N) mem_heap_create_func(\ #define mem_heap_create(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_DYNAMIC,\ (N), NULL, MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
__FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Macro for memory Use this macro instead of the corresponding function! Macro for memory
heap creation. */ heap creation. */
#define mem_heap_create_in_buffer(N) mem_heap_create_func(\ #define mem_heap_create_in_buffer(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_BUFFER,\ (N), NULL, MEM_HEAP_BUFFER, __FILE__, __LINE__)
__FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Macro for memory Use this macro instead of the corresponding function! Macro for memory
heap creation. */ heap creation. */
#define mem_heap_create_in_btr_search(N) mem_heap_create_func(\ #define mem_heap_create_in_btr_search(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_BTR_SEARCH |\ (N), NULL, MEM_HEAP_BTR_SEARCH | MEM_HEAP_BUFFER,\
MEM_HEAP_BUFFER,\ __FILE__, __LINE__)
__FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Macro for fast Use this macro instead of the corresponding function! Macro for fast
memory heap creation. An initial block of memory B is given by the memory heap creation. An initial block of memory B is given by the
@ -92,8 +89,7 @@ caller, N is its size, and this memory block is not freed by
mem_heap_free. See the parameter comment in mem_heap_create_func below. */ mem_heap_free. See the parameter comment in mem_heap_create_func below. */
#define mem_heap_fast_create(N, B) mem_heap_create_func(\ #define mem_heap_fast_create(N, B) mem_heap_create_func(\
(N), (B), MEM_HEAP_DYNAMIC,\ (N), (B), MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
__FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Macro for memory Use this macro instead of the corresponding function! Macro for memory
@ -114,7 +110,7 @@ mem_heap_create_func(
MEM_HEAP_BTR_SEARCH type heaps)*/ MEM_HEAP_BTR_SEARCH type heaps)*/
ulint n, /* in: desired start block size, ulint n, /* in: desired start block size,
this means that a single user buffer this means that a single user buffer
of size n will fit in the block, of size n will fit in the block,
0 creates a default size block; 0 creates a default size block;
if init_block is not NULL, n tells if init_block is not NULL, n tells
its size in bytes */ its size in bytes */
@ -128,7 +124,7 @@ mem_heap_create_func(
block is not unintentionally erased block is not unintentionally erased
(if allocated in the stack), before (if allocated in the stack), before
the memory heap is explicitly freed. */ the memory heap is explicitly freed. */
ulint type, /* in: heap type */ ulint type, /* in: heap type */
const char* file_name, /* in: file name where created */ const char* file_name, /* in: file name where created */
ulint line); /* in: line where created */ ulint line); /* in: line where created */
/********************************************************************* /*********************************************************************
@ -139,9 +135,9 @@ UNIV_INLINE
void void
mem_heap_free_func( mem_heap_free_func(
/*===============*/ /*===============*/
mem_heap_t* heap, /* in, own: heap to be freed */ mem_heap_t* heap, /* in, own: heap to be freed */
const char* file_name, /* in: file name where freed */ const char* file_name, /* in: file name where freed */
ulint line); /* in: line where freed */ ulint line); /* in: line where freed */
/******************************************************************* /*******************************************************************
Allocates n bytes of memory from a memory heap. */ Allocates n bytes of memory from a memory heap. */
UNIV_INLINE UNIV_INLINE
@ -151,8 +147,8 @@ mem_heap_alloc(
/* out: allocated storage, NULL if did not /* out: allocated storage, NULL if did not
succeed (only possible for succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps) */ MEM_HEAP_BTR_SEARCH type heaps) */
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
ulint n); /* in: number of bytes; if the heap is allowed ulint n); /* in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */ <= MEM_MAX_ALLOC_IN_BUF */
/********************************************************************* /*********************************************************************
@ -160,9 +156,9 @@ Returns a pointer to the heap top. */
UNIV_INLINE UNIV_INLINE
byte* byte*
mem_heap_get_heap_top( mem_heap_get_heap_top(
/*==================*/ /*==================*/
/* out: pointer to the heap top */ /* out: pointer to the heap top */
mem_heap_t* heap); /* in: memory heap */ mem_heap_t* heap); /* in: memory heap */
/********************************************************************* /*********************************************************************
Frees the space in a memory heap exceeding the pointer given. The Frees the space in a memory heap exceeding the pointer given. The
pointer must have been acquired from mem_heap_get_heap_top. The first pointer must have been acquired from mem_heap_get_heap_top. The first
@ -171,7 +167,7 @@ UNIV_INLINE
void void
mem_heap_free_heap_top( mem_heap_free_heap_top(
/*===================*/ /*===================*/
mem_heap_t* heap, /* in: heap from which to free */ mem_heap_t* heap, /* in: heap from which to free */
byte* old_top);/* in: pointer to old top of heap */ byte* old_top);/* in: pointer to old top of heap */
/********************************************************************* /*********************************************************************
Empties a memory heap. The first memory block of the heap is not freed. */ Empties a memory heap. The first memory block of the heap is not freed. */
@ -179,48 +175,48 @@ UNIV_INLINE
void void
mem_heap_empty( mem_heap_empty(
/*===========*/ /*===========*/
mem_heap_t* heap); /* in: heap to empty */ mem_heap_t* heap); /* in: heap to empty */
/********************************************************************* /*********************************************************************
Returns a pointer to the topmost element in a memory heap. Returns a pointer to the topmost element in a memory heap.
The size of the element must be given. */ The size of the element must be given. */
UNIV_INLINE UNIV_INLINE
void* void*
mem_heap_get_top( mem_heap_get_top(
/*=============*/ /*=============*/
/* out: pointer to the topmost element */ /* out: pointer to the topmost element */
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
ulint n); /* in: size of the topmost element */ ulint n); /* in: size of the topmost element */
/********************************************************************* /*********************************************************************
Frees the topmost element in a memory heap. Frees the topmost element in a memory heap.
The size of the element must be given. */ The size of the element must be given. */
UNIV_INLINE UNIV_INLINE
void void
mem_heap_free_top( mem_heap_free_top(
/*==============*/ /*==============*/
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
ulint n); /* in: size of the topmost element */ ulint n); /* in: size of the topmost element */
/********************************************************************* /*********************************************************************
Returns the space in bytes occupied by a memory heap. */ Returns the space in bytes occupied by a memory heap. */
UNIV_INLINE UNIV_INLINE
ulint ulint
mem_heap_get_size( mem_heap_get_size(
/*==============*/ /*==============*/
mem_heap_t* heap); /* in: heap */ mem_heap_t* heap); /* in: heap */
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Use this macro instead of the corresponding function!
Macro for memory buffer allocation */ Macro for memory buffer allocation */
#define mem_alloc(N) mem_alloc_func((N), __FILE__, __LINE__) #define mem_alloc(N) mem_alloc_func((N), __FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Use this macro instead of the corresponding function!
Macro for memory buffer allocation */ Macro for memory buffer allocation */
#define mem_alloc_noninline(N) mem_alloc_func_noninline(\ #define mem_alloc_noninline(N) mem_alloc_func_noninline(\
(N), __FILE__, __LINE__) (N), __FILE__, __LINE__)
/******************************************************************* /*******************************************************************
NOTE: Use the corresponding macro instead of this function. NOTE: Use the corresponding macro instead of this function.
Allocates a single buffer of memory from the dynamic memory of Allocates a single buffer of memory from the dynamic memory of
the C compiler. Is like malloc of C. The buffer must be freed the C compiler. Is like malloc of C. The buffer must be freed
with mem_free. */ with mem_free. */
UNIV_INLINE UNIV_INLINE
void* void*
@ -234,7 +230,7 @@ mem_alloc_func(
/******************************************************************* /*******************************************************************
NOTE: Use the corresponding macro instead of this function. NOTE: Use the corresponding macro instead of this function.
Allocates a single buffer of memory from the dynamic memory of Allocates a single buffer of memory from the dynamic memory of
the C compiler. Is like malloc of C. The buffer must be freed the C compiler. Is like malloc of C. The buffer must be freed
with mem_free. */ with mem_free. */
void* void*
@ -249,7 +245,7 @@ mem_alloc_func_noninline(
Use this macro instead of the corresponding function! Use this macro instead of the corresponding function!
Macro for memory buffer freeing */ Macro for memory buffer freeing */
#define mem_free(PTR) mem_free_func((PTR), __FILE__, __LINE__) #define mem_free(PTR) mem_free_func((PTR), __FILE__, __LINE__)
/******************************************************************* /*******************************************************************
NOTE: Use the corresponding macro instead of this function. NOTE: Use the corresponding macro instead of this function.
Frees a single buffer of storage from Frees a single buffer of storage from
@ -326,11 +322,11 @@ mem_validate_all_blocks(void);
#endif #endif
/*#######################################################################*/ /*#######################################################################*/
/* The info header of a block in a memory heap */ /* The info header of a block in a memory heap */
struct mem_block_info_struct { struct mem_block_info_struct {
ulint magic_n;/* magic number for debugging */ ulint magic_n;/* magic number for debugging */
char file_name[8];/* file name where the mem heap was created */ char file_name[8];/* file name where the mem heap was created */
ulint line; /* line number where the mem heap was created */ ulint line; /* line number where the mem heap was created */
UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the
@ -340,23 +336,23 @@ struct mem_block_info_struct {
and prev in the list. The first block allocated and prev in the list. The first block allocated
to the heap is also the first block in this list, to the heap is also the first block in this list,
though it also contains the base node of the list. */ though it also contains the base node of the list. */
ulint len; /* physical length of this block in bytes */ ulint len; /* physical length of this block in bytes */
ulint type; /* type of heap: MEM_HEAP_DYNAMIC, or ulint type; /* type of heap: MEM_HEAP_DYNAMIC, or
MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */ MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */
ibool init_block; /* TRUE if this is the first block used in fast ibool init_block; /* TRUE if this is the first block used in fast
creation of a heap: the memory will be freed creation of a heap: the memory will be freed
by the creator, not by mem_heap_free */ by the creator, not by mem_heap_free */
ulint free; /* offset in bytes of the first free position for ulint free; /* offset in bytes of the first free position for
user data in the block */ user data in the block */
ulint start; /* the value of the struct field 'free' at the ulint start; /* the value of the struct field 'free' at the
creation of the block */ creation of the block */
byte* free_block; byte* free_block;
/* if the MEM_HEAP_BTR_SEARCH bit is set in type, /* if the MEM_HEAP_BTR_SEARCH bit is set in type,
and this is the heap root, this can contain an and this is the heap root, this can contain an
allocated buffer frame, which can be appended as a allocated buffer frame, which can be appended as a
free block to the heap, if we need more space; free block to the heap, if we need more space;
otherwise, this is NULL */ otherwise, this is NULL */
#ifdef MEM_PERIODIC_CHECK #ifdef MEM_PERIODIC_CHECK
UT_LIST_NODE_T(mem_block_t) mem_block_list; UT_LIST_NODE_T(mem_block_t) mem_block_list;
/* List of all mem blocks allocated; protected /* List of all mem blocks allocated; protected
by the mem_comm_pool mutex */ by the mem_comm_pool mutex */
@ -367,7 +363,7 @@ struct mem_block_info_struct {
#define MEM_FREED_BLOCK_MAGIC_N 547711122 #define MEM_FREED_BLOCK_MAGIC_N 547711122
/* Header size for a memory heap block */ /* Header size for a memory heap block */
#define MEM_BLOCK_HEADER_SIZE ut_calc_align(sizeof(mem_block_info_t),\ #define MEM_BLOCK_HEADER_SIZE ut_calc_align(sizeof(mem_block_info_t),\
UNIV_MEM_ALIGNMENT) UNIV_MEM_ALIGNMENT)
#include "mem0dbg.h" #include "mem0dbg.h"
@ -375,4 +371,4 @@ struct mem_block_info_struct {
#include "mem0mem.ic" #include "mem0mem.ic"
#endif #endif
#endif #endif

View File

@ -53,7 +53,7 @@ mem_heap_add_block(
/* out: created block, NULL if did not /* out: created block, NULL if did not
succeed (only possible for succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps)*/ MEM_HEAP_BTR_SEARCH type heaps)*/
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
ulint n); /* in: number of bytes user needs */ ulint n); /* in: number of bytes user needs */
UNIV_INLINE UNIV_INLINE
@ -131,25 +131,25 @@ mem_heap_alloc(
/* out: allocated storage, NULL if did not /* out: allocated storage, NULL if did not
succeed (only possible for succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps) */ MEM_HEAP_BTR_SEARCH type heaps) */
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
ulint n) /* in: number of bytes; if the heap is allowed ulint n) /* in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */ <= MEM_MAX_ALLOC_IN_BUF */
{ {
mem_block_t* block; mem_block_t* block;
void* buf; void* buf;
ulint free; ulint free;
ut_ad(mem_heap_check(heap)); ut_ad(mem_heap_check(heap));
block = UT_LIST_GET_LAST(heap->base); block = UT_LIST_GET_LAST(heap->base);
ut_ad(!(block->type & MEM_HEAP_BUFFER) || (n <= MEM_MAX_ALLOC_IN_BUF)); ut_ad(!(block->type & MEM_HEAP_BUFFER) || (n <= MEM_MAX_ALLOC_IN_BUF));
/* Check if there is enough space in block. If not, create a new /* Check if there is enough space in block. If not, create a new
block to the heap */ block to the heap */
if (mem_block_get_len(block) if (mem_block_get_len(block)
< mem_block_get_free(block) + MEM_SPACE_NEEDED(n)) { < mem_block_get_free(block) + MEM_SPACE_NEEDED(n)) {
block = mem_heap_add_block(heap, n); block = mem_heap_add_block(heap, n);
@ -187,13 +187,13 @@ Returns a pointer to the heap top. */
UNIV_INLINE UNIV_INLINE
byte* byte*
mem_heap_get_heap_top( mem_heap_get_heap_top(
/*==================*/ /*==================*/
/* out: pointer to the heap top */ /* out: pointer to the heap top */
mem_heap_t* heap) /* in: memory heap */ mem_heap_t* heap) /* in: memory heap */
{ {
mem_block_t* block; mem_block_t* block;
byte* buf; byte* buf;
ut_ad(mem_heap_check(heap)); ut_ad(mem_heap_check(heap));
block = UT_LIST_GET_LAST(heap->base); block = UT_LIST_GET_LAST(heap->base);
@ -201,7 +201,7 @@ mem_heap_get_heap_top(
buf = (byte*)block + mem_block_get_free(block); buf = (byte*)block + mem_block_get_free(block);
return(buf); return(buf);
} }
/********************************************************************* /*********************************************************************
Frees the space in a memory heap exceeding the pointer given. The Frees the space in a memory heap exceeding the pointer given. The
@ -211,19 +211,19 @@ UNIV_INLINE
void void
mem_heap_free_heap_top( mem_heap_free_heap_top(
/*===================*/ /*===================*/
mem_heap_t* heap, /* in: heap from which to free */ mem_heap_t* heap, /* in: heap from which to free */
byte* old_top)/* in: pointer to old top of heap */ byte* old_top)/* in: pointer to old top of heap */
{ {
mem_block_t* block; mem_block_t* block;
mem_block_t* prev_block; mem_block_t* prev_block;
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
ibool error; ibool error;
ulint total_size; ulint total_size;
ulint size; ulint size;
#endif #endif
ut_ad(mem_heap_check(heap)); ut_ad(mem_heap_check(heap));
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
/* Validate the heap and get its total allocated size */ /* Validate the heap and get its total allocated size */
@ -247,7 +247,7 @@ mem_heap_free_heap_top(
break; break;
} }
/* Store prev_block value before freeing the current block /* Store prev_block value before freeing the current block
(the current block will be erased in freeing) */ (the current block will be erased in freeing) */
@ -257,17 +257,17 @@ mem_heap_free_heap_top(
block = prev_block; block = prev_block;
} }
ut_ad(block); ut_ad(block);
/* Set the free field of block */ /* Set the free field of block */
mem_block_set_free(block, old_top - (byte*)block); mem_block_set_free(block, old_top - (byte*)block);
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
/* In the debug version erase block from top up */ /* In the debug version erase block from top up */
mem_erase_buf(old_top, (byte*)block + block->len - old_top); mem_erase_buf(old_top, (byte*)block + block->len - old_top);
/* Update allocated memory count */ /* Update allocated memory count */
@ -279,9 +279,9 @@ mem_heap_free_heap_top(
/* If free == start, we may free the block if it is not the first /* If free == start, we may free the block if it is not the first
one */ one */
if ((heap != block) && (mem_block_get_free(block) == if ((heap != block) && (mem_block_get_free(block) ==
mem_block_get_start(block))) { mem_block_get_start(block))) {
mem_heap_block_free(heap, block); mem_heap_block_free(heap, block);
} }
} }
@ -292,14 +292,14 @@ UNIV_INLINE
void void
mem_heap_empty( mem_heap_empty(
/*===========*/ /*===========*/
mem_heap_t* heap) /* in: heap to empty */ mem_heap_t* heap) /* in: heap to empty */
{ {
mem_heap_free_heap_top(heap, (byte*)heap + mem_block_get_start(heap)); mem_heap_free_heap_top(heap, (byte*)heap + mem_block_get_start(heap));
if (heap->free_block) { if (heap->free_block) {
mem_heap_free_block_free(heap); mem_heap_free_block_free(heap);
} }
} }
/********************************************************************* /*********************************************************************
Returns a pointer to the topmost element in a memory heap. The size of the Returns a pointer to the topmost element in a memory heap. The size of the
@ -307,14 +307,14 @@ element must be given. */
UNIV_INLINE UNIV_INLINE
void* void*
mem_heap_get_top( mem_heap_get_top(
/*=============*/ /*=============*/
/* out: pointer to the topmost element */ /* out: pointer to the topmost element */
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
ulint n) /* in: size of the topmost element */ ulint n) /* in: size of the topmost element */
{ {
mem_block_t* block; mem_block_t* block;
void* buf; void* buf;
ut_ad(mem_heap_check(heap)); ut_ad(mem_heap_check(heap));
block = UT_LIST_GET_LAST(heap->base); block = UT_LIST_GET_LAST(heap->base);
@ -326,7 +326,7 @@ mem_heap_get_top(
/* In the debug version, advance buf to point at the storage which /* In the debug version, advance buf to point at the storage which
was given to the caller in the allocation*/ was given to the caller in the allocation*/
buf = (byte*)buf + MEM_FIELD_HEADER_SIZE; buf = (byte*)buf + MEM_FIELD_HEADER_SIZE;
/* Check that the field lengths agree */ /* Check that the field lengths agree */
@ -334,7 +334,7 @@ mem_heap_get_top(
#endif #endif
return(buf); return(buf);
} }
/********************************************************************* /*********************************************************************
Frees the topmost element in a memory heap. The size of the element must be Frees the topmost element in a memory heap. The size of the element must be
@ -342,12 +342,12 @@ given. */
UNIV_INLINE UNIV_INLINE
void void
mem_heap_free_top( mem_heap_free_top(
/*==============*/ /*==============*/
mem_heap_t* heap, /* in: memory heap */ mem_heap_t* heap, /* in: memory heap */
ulint n) /* in: size of the topmost element */ ulint n) /* in: size of the topmost element */
{ {
mem_block_t* block; mem_block_t* block;
ut_ad(mem_heap_check(heap)); ut_ad(mem_heap_check(heap));
block = UT_LIST_GET_LAST(heap->base); block = UT_LIST_GET_LAST(heap->base);
@ -365,9 +365,9 @@ mem_heap_free_top(
/* If free == start, we may free the block if it is not the first /* If free == start, we may free the block if it is not the first
one */ one */
if ((heap != block) && (mem_block_get_free(block) == if ((heap != block) && (mem_block_get_free(block) ==
mem_block_get_start(block))) { mem_block_get_start(block))) {
mem_heap_block_free(heap, block); mem_heap_block_free(heap, block);
} }
} }
@ -385,7 +385,7 @@ mem_heap_create_func(
MEM_HEAP_BTR_SEARCH type heaps)*/ MEM_HEAP_BTR_SEARCH type heaps)*/
ulint n, /* in: desired start block size, ulint n, /* in: desired start block size,
this means that a single user buffer this means that a single user buffer
of size n will fit in the block, of size n will fit in the block,
0 creates a default size block; 0 creates a default size block;
if init_block is not NULL, n tells if init_block is not NULL, n tells
its size in bytes */ its size in bytes */
@ -399,25 +399,25 @@ mem_heap_create_func(
block is not unintentionally erased block is not unintentionally erased
(if allocated in the stack), before (if allocated in the stack), before
the memory heap is explicitly freed. */ the memory heap is explicitly freed. */
ulint type, /* in: heap type */ ulint type, /* in: heap type */
const char* file_name, /* in: file name where created */ const char* file_name, /* in: file name where created */
ulint line) /* in: line where created */ ulint line) /* in: line where created */
{ {
mem_block_t* block; mem_block_t* block;
if (n > 0) { if (n > 0) {
block = mem_heap_create_block(NULL, n, init_block, type, block = mem_heap_create_block(NULL, n, init_block, type,
file_name, line); file_name, line);
} else { } else {
block = mem_heap_create_block(NULL, MEM_BLOCK_START_SIZE, block = mem_heap_create_block(NULL, MEM_BLOCK_START_SIZE,
init_block, type, file_name, line); init_block, type, file_name, line);
} }
if (block == NULL) { if (block == NULL) {
return(NULL); return(NULL);
} }
UT_LIST_INIT(block->base); UT_LIST_INIT(block->base);
/* Add the created block itself as the first block in the list */ /* Add the created block itself as the first block in the list */
@ -428,7 +428,7 @@ mem_heap_create_func(
mem_hash_insert(block, file_name, line); mem_hash_insert(block, file_name, line);
#endif #endif
return(block); return(block);
} }
@ -440,16 +440,16 @@ UNIV_INLINE
void void
mem_heap_free_func( mem_heap_free_func(
/*===============*/ /*===============*/
mem_heap_t* heap, /* in, own: heap to be freed */ mem_heap_t* heap, /* in, own: heap to be freed */
const char* file_name __attribute__((unused)), const char* file_name __attribute__((unused)),
/* in: file name where freed */ /* in: file name where freed */
ulint line __attribute__((unused))) ulint line __attribute__((unused)))
{ {
mem_block_t* block; mem_block_t* block;
mem_block_t* prev_block; mem_block_t* prev_block;
ut_ad(mem_heap_check(heap)); ut_ad(mem_heap_check(heap));
block = UT_LIST_GET_LAST(heap->base); block = UT_LIST_GET_LAST(heap->base);
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
@ -457,15 +457,15 @@ mem_heap_free_func(
/* In the debug version remove the heap from the hash table of heaps /* In the debug version remove the heap from the hash table of heaps
and check its consistency */ and check its consistency */
mem_hash_remove(heap, file_name, line); mem_hash_remove(heap, file_name, line);
#endif #endif
if (heap->free_block) { if (heap->free_block) {
mem_heap_free_block_free(heap); mem_heap_free_block_free(heap);
} }
while (block != NULL) { while (block != NULL) {
/* Store the contents of info before freeing current block /* Store the contents of info before freeing current block
(it is erased in freeing) */ (it is erased in freeing) */
@ -480,7 +480,7 @@ mem_heap_free_func(
/******************************************************************* /*******************************************************************
NOTE: Use the corresponding macro instead of this function. NOTE: Use the corresponding macro instead of this function.
Allocates a single buffer of memory from the dynamic memory of Allocates a single buffer of memory from the dynamic memory of
the C compiler. Is like malloc of C. The buffer must be freed the C compiler. Is like malloc of C. The buffer must be freed
with mem_free. */ with mem_free. */
UNIV_INLINE UNIV_INLINE
void* void*
@ -492,8 +492,8 @@ mem_alloc_func(
ulint line /* in: line where created */ ulint line /* in: line where created */
) )
{ {
mem_heap_t* heap; mem_heap_t* heap;
void* buf; void* buf;
heap = mem_heap_create_func(n, NULL, MEM_HEAP_DYNAMIC, file_name, heap = mem_heap_create_func(n, NULL, MEM_HEAP_DYNAMIC, file_name,
line); line);
@ -523,10 +523,10 @@ mem_free_func(
ulint line /* in: line where created */ ulint line /* in: line where created */
) )
{ {
mem_heap_t* heap; mem_heap_t* heap;
heap = (mem_heap_t*)((byte*)ptr - MEM_BLOCK_HEADER_SIZE heap = (mem_heap_t*)((byte*)ptr - MEM_BLOCK_HEADER_SIZE
- MEM_FIELD_HEADER_SIZE); - MEM_FIELD_HEADER_SIZE);
mem_heap_free_func(heap, file_name, line); mem_heap_free_func(heap, file_name, line);
} }
@ -536,16 +536,16 @@ UNIV_INLINE
ulint ulint
mem_heap_get_size( mem_heap_get_size(
/*==============*/ /*==============*/
mem_heap_t* heap) /* in: heap */ mem_heap_t* heap) /* in: heap */
{ {
mem_block_t* block; mem_block_t* block;
ulint size = 0; ulint size = 0;
ut_ad(mem_heap_check(heap)); ut_ad(mem_heap_check(heap));
block = heap; block = heap;
while (block != NULL) { while (block != NULL) {
size += mem_block_get_len(block); size += mem_block_get_len(block);
block = UT_LIST_GET_NEXT(list, block); block = UT_LIST_GET_NEXT(list, block);

View File

@ -25,14 +25,14 @@ struct mem_area_struct{
ulint size_and_free; /* memory area size is obtained by ulint size_and_free; /* memory area size is obtained by
anding with ~MEM_AREA_FREE; area in anding with ~MEM_AREA_FREE; area in
a free list if ANDing with a free list if ANDing with
MEM_AREA_FREE results in nonzero */ MEM_AREA_FREE results in nonzero */
UT_LIST_NODE_T(mem_area_t) UT_LIST_NODE_T(mem_area_t)
free_list; /* free list node */ free_list; /* free list node */
}; };
/* Each memory area takes this many extra bytes for control information */ /* Each memory area takes this many extra bytes for control information */
#define MEM_AREA_EXTRA_SIZE (ut_calc_align(sizeof(struct mem_area_struct),\ #define MEM_AREA_EXTRA_SIZE (ut_calc_align(sizeof(struct mem_area_struct),\
UNIV_MEM_ALIGNMENT)) UNIV_MEM_ALIGNMENT))
/************************************************************************ /************************************************************************
Creates a memory pool. */ Creates a memory pool. */
@ -97,7 +97,7 @@ Prints info of a memory pool. */
void void
mem_pool_print_info( mem_pool_print_info(
/*================*/ /*================*/
FILE* outfile,/* in: output file to write to */ FILE* outfile,/* in: output file to write to */
mem_pool_t* pool); /* in: memory pool */ mem_pool_t* pool); /* in: memory pool */
@ -105,4 +105,4 @@ mem_pool_print_info(
#include "mem0pool.ic" #include "mem0pool.ic"
#endif #endif
#endif #endif

View File

@ -73,10 +73,18 @@ mlog_catenate_ulint(
mlog = &(mtr->log); mlog = &(mtr->log);
ut_ad(MLOG_1BYTE == 1); #if MLOG_1BYTE != 1
ut_ad(MLOG_2BYTES == 2); # error "MLOG_1BYTE != 1"
ut_ad(MLOG_4BYTES == 4); #endif
#if MLOG_2BYTES != 2
# error "MLOG_2BYTES != 2"
#endif
#if MLOG_4BYTES != 4
# error "MLOG_4BYTES != 4"
#endif
#if MLOG_8BYTES != 8
# error "MLOG_8BYTES != 8"
#endif
ptr = dyn_array_push(mlog, type); ptr = dyn_array_push(mlog, type);
if (type == MLOG_4BYTES) { if (type == MLOG_4BYTES) {
@ -86,7 +94,7 @@ mlog_catenate_ulint(
} else { } else {
ut_ad(type == MLOG_1BYTE); ut_ad(type == MLOG_1BYTE);
mach_write_to_1(ptr, val); mach_write_to_1(ptr, val);
} }
} }
/************************************************************ /************************************************************
@ -156,7 +164,7 @@ mlog_write_initial_log_record_fast(
ulint space; ulint space;
ulint offset; ulint offset;
ut_ad(mtr_memo_contains(mtr, buf_block_align(ptr), ut_ad(mtr_memo_contains(mtr, buf_block_align(ptr),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
ut_ad(type <= MLOG_BIGGEST_TYPE); ut_ad(type <= MLOG_BIGGEST_TYPE);
ut_ad(ptr && log_ptr); ut_ad(ptr && log_ptr);
@ -167,7 +175,7 @@ mlog_write_initial_log_record_fast(
offset = buf_block_get_page_no(block); offset = buf_block_get_page_no(block);
mach_write_to_1(log_ptr, type); mach_write_to_1(log_ptr, type);
log_ptr++; log_ptr++;
log_ptr += mach_write_compressed(log_ptr, space); log_ptr += mach_write_compressed(log_ptr, space);
log_ptr += mach_write_compressed(log_ptr, offset); log_ptr += mach_write_compressed(log_ptr, offset);
@ -188,7 +196,7 @@ mlog_write_initial_log_record_fast(
} }
#endif #endif
return(log_ptr); return(log_ptr);
} }
/************************************************************ /************************************************************
Writes a log record about an .ibd file create/delete/rename. */ Writes a log record about an .ibd file create/delete/rename. */
@ -216,4 +224,4 @@ mlog_write_initial_log_record_for_file_op(
mtr->n_log_recs++; mtr->n_log_recs++;
return(log_ptr); return(log_ptr);
} }

View File

@ -27,7 +27,7 @@ Created 11/26/1995 Heikki Tuuri
(operations in fsp0fsp.* ) */ (operations in fsp0fsp.* ) */
#define MTR_LOG_SHORT_INSERTS 24 /* inserts are logged in a shorter #define MTR_LOG_SHORT_INSERTS 24 /* inserts are logged in a shorter
form */ form */
/* Types for the mlock objects to store in the mtr memo; NOTE that the /* Types for the mlock objects to store in the mtr memo; NOTE that the
first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */ first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
#define MTR_MEMO_PAGE_S_FIX RW_S_LATCH #define MTR_MEMO_PAGE_S_FIX RW_S_LATCH
@ -47,31 +47,31 @@ flag value must give the length also! */
has been called only once, has been called only once,
this flag is ORed to the type this flag is ORed to the type
of that first log record */ of that first log record */
#define MLOG_1BYTE ((byte)1) /* one byte is written */ #define MLOG_1BYTE (1) /* one byte is written */
#define MLOG_2BYTES ((byte)2) /* 2 bytes ... */ #define MLOG_2BYTES (2) /* 2 bytes ... */
#define MLOG_4BYTES ((byte)4) /* 4 bytes ... */ #define MLOG_4BYTES (4) /* 4 bytes ... */
#define MLOG_8BYTES ((byte)8) /* 8 bytes ... */ #define MLOG_8BYTES (8) /* 8 bytes ... */
#define MLOG_REC_INSERT ((byte)9) /* record insert */ #define MLOG_REC_INSERT ((byte)9) /* record insert */
#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /* mark clustered index record #define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /* mark clustered index record
deleted */ deleted */
#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /* mark secondary index record #define MLOG_REC_SEC_DELETE_MARK ((byte)11) /* mark secondary index record
deleted */ deleted */
#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /* update of a record, #define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /* update of a record,
preserves record field sizes */ preserves record field sizes */
#define MLOG_REC_DELETE ((byte)14) /* delete a record from a #define MLOG_REC_DELETE ((byte)14) /* delete a record from a
page */ page */
#define MLOG_LIST_END_DELETE ((byte)15) /* delete record list end on #define MLOG_LIST_END_DELETE ((byte)15) /* delete record list end on
index page */ index page */
#define MLOG_LIST_START_DELETE ((byte)16) /* delete record list start on #define MLOG_LIST_START_DELETE ((byte)16) /* delete record list start on
index page */ index page */
#define MLOG_LIST_END_COPY_CREATED ((byte)17) /* copy record list end to a #define MLOG_LIST_END_COPY_CREATED ((byte)17) /* copy record list end to a
new created index page */ new created index page */
#define MLOG_PAGE_REORGANIZE ((byte)18) /* reorganize an index page */ #define MLOG_PAGE_REORGANIZE ((byte)18) /* reorganize an index page */
#define MLOG_PAGE_CREATE ((byte)19) /* create an index page */ #define MLOG_PAGE_CREATE ((byte)19) /* create an index page */
#define MLOG_UNDO_INSERT ((byte)20) /* insert entry in an undo #define MLOG_UNDO_INSERT ((byte)20) /* insert entry in an undo
log */ log */
#define MLOG_UNDO_ERASE_END ((byte)21) /* erase an undo log page end */ #define MLOG_UNDO_ERASE_END ((byte)21) /* erase an undo log page end */
#define MLOG_UNDO_INIT ((byte)22) /* initialize a page in an #define MLOG_UNDO_INIT ((byte)22) /* initialize a page in an
undo log */ undo log */
#define MLOG_UNDO_HDR_DISCARD ((byte)23) /* discard an update undo log #define MLOG_UNDO_HDR_DISCARD ((byte)23) /* discard an update undo log
header */ header */
@ -132,9 +132,9 @@ flag value must give the length also! */
#define MLOG_BIGGEST_TYPE ((byte)46) /* biggest value (used in #define MLOG_BIGGEST_TYPE ((byte)46) /* biggest value (used in
asserts) */ asserts) */
/******************************************************************* /*******************************************************************
Starts a mini-transaction and creates a mini-transaction handle Starts a mini-transaction and creates a mini-transaction handle
and buffer in the memory buffer given by the caller. */ and buffer in the memory buffer given by the caller. */
UNIV_INLINE UNIV_INLINE
mtr_t* mtr_t*
@ -144,7 +144,7 @@ mtr_start(
the mtr handle */ the mtr handle */
mtr_t* mtr); /* in: memory buffer for the mtr buffer */ mtr_t* mtr); /* in: memory buffer for the mtr buffer */
/******************************************************************* /*******************************************************************
Starts a mini-transaction and creates a mini-transaction handle Starts a mini-transaction and creates a mini-transaction handle
and buffer in the memory buffer given by the caller. */ and buffer in the memory buffer given by the caller. */
mtr_t* mtr_t*
@ -187,7 +187,7 @@ mtr_release_s_latch_at_savepoint(
/*=============================*/ /*=============================*/
mtr_t* mtr, /* in: mtr */ mtr_t* mtr, /* in: mtr */
ulint savepoint, /* in: savepoint */ ulint savepoint, /* in: savepoint */
rw_lock_t* lock); /* in: latch to release */ rw_lock_t* lock); /* in: latch to release */
/******************************************************************* /*******************************************************************
Gets the logging mode of a mini-transaction. */ Gets the logging mode of a mini-transaction. */
UNIV_INLINE UNIV_INLINE
@ -220,7 +220,7 @@ Reads 8 bytes from a file page buffered in the buffer pool. */
dulint dulint
mtr_read_dulint( mtr_read_dulint(
/*===========*/ /*============*/
/* out: value read */ /* out: value read */
byte* ptr, /* in: pointer from where to read */ byte* ptr, /* in: pointer from where to read */
mtr_t* mtr); /* in: mini-transaction handle */ mtr_t* mtr); /* in: mini-transaction handle */
@ -336,7 +336,7 @@ struct mtr_struct{
#define MTR_ACTIVE 12231 #define MTR_ACTIVE 12231
#define MTR_COMMITTING 56456 #define MTR_COMMITTING 56456
#define MTR_COMMITTED 34676 #define MTR_COMMITTED 34676
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "mtr0mtr.ic" #include "mtr0mtr.ic"
#endif #endif

View File

@ -11,7 +11,7 @@ Created 11/26/1995 Heikki Tuuri
#include "mach0data.h" #include "mach0data.h"
/******************************************************************* /*******************************************************************
Starts a mini-transaction and creates a mini-transaction handle Starts a mini-transaction and creates a mini-transaction handle
and a buffer in the memory buffer given by the caller. */ and a buffer in the memory buffer given by the caller. */
UNIV_INLINE UNIV_INLINE
mtr_t* mtr_t*
@ -33,7 +33,7 @@ mtr_start(
mtr->magic_n = MTR_MAGIC_N; mtr->magic_n = MTR_MAGIC_N;
#endif #endif
return(mtr); return(mtr);
} }
/******************************************************* /*******************************************************
Pushes an object to an mtr memo stack. */ Pushes an object to an mtr memo stack. */
@ -49,12 +49,12 @@ mtr_memo_push(
mtr_memo_slot_t* slot; mtr_memo_slot_t* slot;
ut_ad(object); ut_ad(object);
ut_ad(type >= MTR_MEMO_PAGE_S_FIX); ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
ut_ad(type <= MTR_MEMO_X_LOCK); ut_ad(type <= MTR_MEMO_X_LOCK);
ut_ad(mtr); ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->magic_n == MTR_MAGIC_N);
memo = &(mtr->memo); memo = &(mtr->memo);
slot = dyn_array_push(memo, sizeof(mtr_memo_slot_t)); slot = dyn_array_push(memo, sizeof(mtr_memo_slot_t));
@ -72,11 +72,11 @@ mtr_set_savepoint(
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
dyn_array_t* memo; dyn_array_t* memo;
ut_ad(mtr); ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->magic_n == MTR_MAGIC_N);
memo = &(mtr->memo); memo = &(mtr->memo);
return(dyn_array_get_data_size(memo)); return(dyn_array_get_data_size(memo));
} }
@ -90,11 +90,11 @@ mtr_release_s_latch_at_savepoint(
/*=============================*/ /*=============================*/
mtr_t* mtr, /* in: mtr */ mtr_t* mtr, /* in: mtr */
ulint savepoint, /* in: savepoint */ ulint savepoint, /* in: savepoint */
rw_lock_t* lock) /* in: latch to release */ rw_lock_t* lock) /* in: latch to release */
{ {
mtr_memo_slot_t* slot; mtr_memo_slot_t* slot;
dyn_array_t* memo; dyn_array_t* memo;
ut_ad(mtr); ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE); ut_ad(mtr->state == MTR_ACTIVE);
@ -102,7 +102,7 @@ mtr_release_s_latch_at_savepoint(
memo = &(mtr->memo); memo = &(mtr->memo);
ut_ad(dyn_array_get_data_size(memo) > savepoint); ut_ad(dyn_array_get_data_size(memo) > savepoint);
slot = dyn_array_get_element(memo, savepoint); slot = dyn_array_get_element(memo, savepoint);
ut_ad(slot->object == lock); ut_ad(slot->object == lock);

View File

@ -28,8 +28,8 @@ extern ibool os_aio_print_debug;
extern ulint os_file_n_pending_preads; extern ulint os_file_n_pending_preads;
extern ulint os_file_n_pending_pwrites; extern ulint os_file_n_pending_pwrites;
extern ulint os_n_pending_reads; extern ulint os_n_pending_reads;
extern ulint os_n_pending_writes; extern ulint os_n_pending_writes;
#ifdef __WIN__ #ifdef __WIN__
@ -75,7 +75,7 @@ log. */
#define OS_FILE_OPEN_RETRY 56 /* for os_file_create() on #define OS_FILE_OPEN_RETRY 56 /* for os_file_create() on
the first ibdata file */ the first ibdata file */
#define OS_FILE_READ_ONLY 333 #define OS_FILE_READ_ONLY 333
#define OS_FILE_READ_WRITE 444 #define OS_FILE_READ_WRITE 444
#define OS_FILE_READ_ALLOW_DELETE 555 /* for ibbackup */ #define OS_FILE_READ_ALLOW_DELETE 555 /* for ibbackup */
@ -91,9 +91,10 @@ log. */
#define OS_FILE_NOT_FOUND 71 #define OS_FILE_NOT_FOUND 71
#define OS_FILE_DISK_FULL 72 #define OS_FILE_DISK_FULL 72
#define OS_FILE_ALREADY_EXISTS 73 #define OS_FILE_ALREADY_EXISTS 73
#define OS_FILE_AIO_RESOURCES_RESERVED 74 /* wait for OS aio resources #define OS_FILE_PATH_ERROR 74
#define OS_FILE_AIO_RESOURCES_RESERVED 75 /* wait for OS aio resources
to become available again */ to become available again */
#define OS_FILE_ERROR_NOT_SPECIFIED 75 #define OS_FILE_ERROR_NOT_SPECIFIED 76
/* Types for aio operations */ /* Types for aio operations */
#define OS_FILE_READ 10 #define OS_FILE_READ 10
@ -109,7 +110,7 @@ log. */
pages or ibuf bitmap pages */ pages or ibuf bitmap pages */
#define OS_AIO_IBUF 22 /* Asynchronous i/o for ibuf pages or ibuf #define OS_AIO_IBUF 22 /* Asynchronous i/o for ibuf pages or ibuf
bitmap pages */ bitmap pages */
#define OS_AIO_LOG 23 /* Asynchronous i/o for the log */ #define OS_AIO_LOG 23 /* Asynchronous i/o for the log */
#define OS_AIO_SYNC 24 /* Asynchronous i/o where the calling thread #define OS_AIO_SYNC 24 /* Asynchronous i/o where the calling thread
will itself wait for the i/o to complete, will itself wait for the i/o to complete,
doing also the job of the i/o-handler thread; doing also the job of the i/o-handler thread;
@ -124,12 +125,12 @@ log. */
in the call of os_aio(...), in the call of os_aio(...),
if the caller wants to post several i/o if the caller wants to post several i/o
requests in a batch, and only after that requests in a batch, and only after that
wake the i/o-handler thread; this has wake the i/o-handler thread; this has
effect only in simulated aio */ effect only in simulated aio */
#define OS_WIN31 1 #define OS_WIN31 1
#define OS_WIN95 2 #define OS_WIN95 2
#define OS_WINNT 3 #define OS_WINNT 3
#define OS_WIN2000 4 #define OS_WIN2000 4
extern ulint os_n_file_reads; extern ulint os_n_file_reads;
extern ulint os_n_file_writes; extern ulint os_n_file_writes;
@ -138,10 +139,10 @@ extern ulint os_n_fsyncs;
/* File types for directory entry data type */ /* File types for directory entry data type */
enum os_file_type_enum{ enum os_file_type_enum{
OS_FILE_TYPE_UNKNOWN = 0, OS_FILE_TYPE_UNKNOWN = 0,
OS_FILE_TYPE_FILE, /* regular file */ OS_FILE_TYPE_FILE, /* regular file */
OS_FILE_TYPE_DIR, /* directory */ OS_FILE_TYPE_DIR, /* directory */
OS_FILE_TYPE_LINK /* symbolic link */ OS_FILE_TYPE_LINK /* symbolic link */
}; };
typedef enum os_file_type_enum os_file_type_t; typedef enum os_file_type_enum os_file_type_t;
@ -156,14 +157,14 @@ struct os_file_stat_struct{
char name[OS_FILE_MAX_PATH]; /* path to a file */ char name[OS_FILE_MAX_PATH]; /* path to a file */
os_file_type_t type; /* file type */ os_file_type_t type; /* file type */
ib_longlong size; /* file size */ ib_longlong size; /* file size */
time_t ctime; /* creation time */ time_t ctime; /* creation time */
time_t mtime; /* modification time */ time_t mtime; /* modification time */
time_t atime; /* access time */ time_t atime; /* access time */
}; };
typedef struct os_file_stat_struct os_file_stat_t; typedef struct os_file_stat_struct os_file_stat_t;
#ifdef __WIN__ #ifdef __WIN__
typedef HANDLE os_file_dir_t; /* directory stream */ typedef HANDLE os_file_dir_t; /* directory stream */
#else #else
typedef DIR* os_file_dir_t; /* directory stream */ typedef DIR* os_file_dir_t; /* directory stream */
#endif #endif
@ -174,7 +175,7 @@ Gets the operating system version. Currently works only on Windows. */
ulint ulint
os_get_os_version(void); os_get_os_version(void);
/*===================*/ /*===================*/
/* out: OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */ /* out: OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */
/******************************************************************** /********************************************************************
Creates the seek mutexes used in positioned reads and writes. */ Creates the seek mutexes used in positioned reads and writes. */
@ -182,12 +183,15 @@ void
os_io_init_simple(void); os_io_init_simple(void);
/*===================*/ /*===================*/
/*************************************************************************** /***************************************************************************
Creates a temporary file. */ Creates a temporary file. This function is like tmpfile(3), but
the temporary file is created in the MySQL temporary directory.
On Netware, this function is like tmpfile(3), because the C run-time
library of Netware does not expose the delete-on-close flag. */
FILE* FILE*
os_file_create_tmpfile(void); os_file_create_tmpfile(void);
/*========================*/ /*========================*/
/* out: temporary file handle (never NULL) */ /* out: temporary file handle, or NULL on error */
/*************************************************************************** /***************************************************************************
The os_file_opendir() function opens a directory stream corresponding to the The os_file_opendir() function opens a directory stream corresponding to the
directory named by the dirname argument. The directory stream is positioned directory named by the dirname argument. The directory stream is positioned
@ -256,7 +260,7 @@ os_file_create_simple(
opened (if does not exist, error), or opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created OS_FILE_CREATE if a new file is created
(if exists, error), or (if exists, error), or
OS_FILE_CREATE_PATH if new file OS_FILE_CREATE_PATH if new file
(if exists, error) and subdirectories along (if exists, error) and subdirectories along
its path are created (if needed)*/ its path are created (if needed)*/
ulint access_type,/* in: OS_FILE_READ_ONLY or ulint access_type,/* in: OS_FILE_READ_ONLY or
@ -430,7 +434,7 @@ os_file_read(
offset where to read */ offset where to read */
ulint offset_high,/* in: most significant 32 bits of ulint offset_high,/* in: most significant 32 bits of
offset */ offset */
ulint n); /* in: number of bytes to read */ ulint n); /* in: number of bytes to read */
/*********************************************************************** /***********************************************************************
Rewind file to its start, read at most size - 1 bytes from it to str, and Rewind file to its start, read at most size - 1 bytes from it to str, and
NUL-terminate str. All errors are silently ignored. This function is NUL-terminate str. All errors are silently ignored. This function is
@ -457,7 +461,7 @@ os_file_read_no_error_handling(
offset where to read */ offset where to read */
ulint offset_high,/* in: most significant 32 bits of ulint offset_high,/* in: most significant 32 bits of
offset */ offset */
ulint n); /* in: number of bytes to read */ ulint n); /* in: number of bytes to read */
/*********************************************************************** /***********************************************************************
Requests a synchronous write operation. */ Requests a synchronous write operation. */
@ -475,7 +479,7 @@ os_file_write(
offset where to write */ offset where to write */
ulint offset_high,/* in: most significant 32 bits of ulint offset_high,/* in: most significant 32 bits of
offset */ offset */
ulint n); /* in: number of bytes to write */ ulint n); /* in: number of bytes to write */
/*********************************************************************** /***********************************************************************
Check the existence and type of the given file. */ Check the existence and type of the given file. */
@ -483,7 +487,7 @@ ibool
os_file_status( os_file_status(
/*===========*/ /*===========*/
/* out: TRUE if call succeeded */ /* out: TRUE if call succeeded */
const char* path, /* in: pathname of the file */ const char* path, /* in: pathname of the file */
ibool* exists, /* out: TRUE if file exists */ ibool* exists, /* out: TRUE if file exists */
os_file_type_t* type); /* out: type of the file (if it exists) */ os_file_type_t* type); /* out: type of the file (if it exists) */
/******************************************************************** /********************************************************************
@ -500,18 +504,18 @@ yields a complete pathname.
The return value is a copy of the directory component of the pathname. The return value is a copy of the directory component of the pathname.
The copy is allocated from heap. It is the caller responsibility The copy is allocated from heap. It is the caller responsibility
to free it after it is no longer needed. to free it after it is no longer needed.
The following list of examples (taken from SUSv2) shows the strings The following list of examples (taken from SUSv2) shows the strings
returned by dirname and basename for different paths: returned by dirname and basename for different paths:
path dirname basename path dirname basename
"/usr/lib" "/usr" "lib" "/usr/lib" "/usr" "lib"
"/usr/" "/" "usr" "/usr/" "/" "usr"
"usr" "." "usr" "usr" "." "usr"
"/" "/" "/" "/" "/" "/"
"." "." "." "." "." "."
".." "." ".." ".." "." ".."
*/ */
char* char*
@ -522,7 +526,7 @@ os_file_dirname(
const char* path); /* in: pathname */ const char* path); /* in: pathname */
/******************************************************************** /********************************************************************
Creates all missing subdirectories along the given path. */ Creates all missing subdirectories along the given path. */
ibool ibool
os_file_create_subdirs_if_needed( os_file_create_subdirs_if_needed(
/*=============================*/ /*=============================*/
@ -577,7 +581,7 @@ os_aio(
offset where to read or write */ offset where to read or write */
ulint offset_high, /* in: most significant 32 bits of ulint offset_high, /* in: most significant 32 bits of
offset */ offset */
ulint n, /* in: number of bytes to read or write */ ulint n, /* in: number of bytes to read or write */
fil_node_t* message1,/* in: messages for the aio handler (these fil_node_t* message1,/* in: messages for the aio handler (these
can be used to identify a completed aio can be used to identify a completed aio
operation); if mode is OS_AIO_SYNC, these operation); if mode is OS_AIO_SYNC, these
@ -635,7 +639,7 @@ os_aio_windows_handle(
sync aio is used, and this parameter is sync aio is used, and this parameter is
ignored */ ignored */
ulint pos, /* this parameter is used only in sync aio: ulint pos, /* this parameter is used only in sync aio:
wait for the aio slot at this position */ wait for the aio slot at this position */
fil_node_t**message1, /* out: the messages passed with the aio fil_node_t**message1, /* out: the messages passed with the aio
request; note that also in the case where request; note that also in the case where
the aio operation failed, these output the aio operation failed, these output
@ -720,7 +724,7 @@ ibool
os_file_get_status( os_file_get_status(
/*===============*/ /*===============*/
/* out: TRUE if stat information found */ /* out: TRUE if stat information found */
const char* path, /* in: pathname of the file */ const char* path, /* in: pathname of the file */
os_file_stat_t* stat_info); /* information of a file in a directory */ os_file_stat_t* stat_info); /* information of a file in a directory */
#endif #endif

View File

@ -116,20 +116,21 @@ Allocates large pages memory. */
void* void*
os_mem_alloc_large( os_mem_alloc_large(
/*=================*/ /*===============*/
/* out: allocated memory */ /* out: allocated memory */
ulint n, /* in: number of bytes */ ulint n, /* in: number of bytes */
ibool set_to_zero, /* in: TRUE if allocated memory should be set ibool set_to_zero, /* in: TRUE if allocated memory
to zero if UNIV_SET_MEM_TO_ZERO is defined */ should be set to zero if
ibool assert_on_error); /* in: if TRUE, we crash mysqld if the memory UNIV_SET_MEM_TO_ZERO is defined */
cannot be allocated */ ibool assert_on_error);/* in: if TRUE, we crash mysqld if
the memory cannot be allocated */
/******************************************************************** /********************************************************************
Frees large pages memory. */ Frees large pages memory. */
void void
os_mem_free_large( os_mem_free_large(
/*=================*/ /*==============*/
void *ptr); /* in: number of bytes */ void *ptr); /* in: number of bytes */
/******************************************************************** /********************************************************************
Sets the priority boost for threads released from waiting within the current Sets the priority boost for threads released from waiting within the current
process. */ process. */
@ -144,4 +145,4 @@ os_process_set_priority_boost(
#include "os0proc.ic" #include "os0proc.ic"
#endif #endif
#endif #endif

View File

@ -16,10 +16,10 @@ Created 9/6/1995 Heikki Tuuri
#define os_fast_mutex_t CRITICAL_SECTION #define os_fast_mutex_t CRITICAL_SECTION
typedef HANDLE os_native_event_t; typedef HANDLE os_native_event_t;
typedef struct os_event_struct os_event_struct_t; typedef struct os_event_struct os_event_struct_t;
typedef os_event_struct_t* os_event_t; typedef os_event_struct_t* os_event_t;
struct os_event_struct { struct os_event_struct {
os_native_event_t handle; os_native_event_t handle;
@ -30,8 +30,8 @@ struct os_event_struct {
#else #else
typedef pthread_mutex_t os_fast_mutex_t; typedef pthread_mutex_t os_fast_mutex_t;
typedef struct os_event_struct os_event_struct_t; typedef struct os_event_struct os_event_struct_t;
typedef os_event_struct_t* os_event_t; typedef os_event_struct_t* os_event_t;
struct os_event_struct { struct os_event_struct {
os_fast_mutex_t os_mutex; /* this mutex protects the next os_fast_mutex_t os_mutex; /* this mutex protects the next
@ -79,7 +79,7 @@ Frees created events and OS 'slow' mutexes. */
void void
os_sync_free(void); os_sync_free(void);
/*==============*/ /*==============*/
/************************************************************* /*************************************************************
Creates an event semaphore, i.e., a semaphore which may just have two states: Creates an event semaphore, i.e., a semaphore which may just have two states:
signaled and nonsignaled. The created event is manual reset: it must be reset signaled and nonsignaled. The created event is manual reset: it must be reset
explicitly by calling sync_os_reset_event. */ explicitly by calling sync_os_reset_event. */
@ -158,9 +158,9 @@ os_event_wait_multiple(
/*===================*/ /*===================*/
/* out: index of the event /* out: index of the event
which was signaled */ which was signaled */
ulint n, /* in: number of events in the ulint n, /* in: number of events in the
array */ array */
os_native_event_t* native_event_array); os_native_event_t* native_event_array);
/* in: pointer to an array of event /* in: pointer to an array of event
handles */ handles */
#endif #endif
@ -234,9 +234,9 @@ void
os_fast_mutex_free( os_fast_mutex_free(
/*===============*/ /*===============*/
os_fast_mutex_t* fast_mutex); /* in: mutex to free */ os_fast_mutex_t* fast_mutex); /* in: mutex to free */
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "os0sync.ic" #include "os0sync.ic"
#endif #endif
#endif #endif

View File

@ -22,7 +22,7 @@ os_fast_mutex_trylock(
thread */ thread */
os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */ os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */
{ {
#ifdef __WIN__ #ifdef __WIN__
EnterCriticalSection(fast_mutex); EnterCriticalSection(fast_mutex);
return(0); return(0);

View File

@ -30,8 +30,8 @@ typedef void* os_thread_t;
typedef ulint os_thread_id_t; /* In Windows the thread id typedef ulint os_thread_id_t; /* In Windows the thread id
is an unsigned long int */ is an unsigned long int */
#else #else
typedef pthread_t os_thread_t; typedef pthread_t os_thread_t;
typedef os_thread_t os_thread_id_t; /* In Unix we use the thread typedef os_thread_t os_thread_id_t; /* In Unix we use the thread
handle itself as the id of handle itself as the id of
the thread */ the thread */
#endif #endif
@ -69,7 +69,7 @@ os_thread_create(
/*=============*/ /*=============*/
/* out: handle to the thread */ /* out: handle to the thread */
#ifndef __WIN__ #ifndef __WIN__
os_posix_f_t start_f, os_posix_f_t start_f,
#else #else
ulint (*start_f)(void*), /* in: pointer to function ulint (*start_f)(void*), /* in: pointer to function
from which to start */ from which to start */
@ -80,7 +80,7 @@ os_thread_create(
thread */ thread */
int int
os_thread_join( os_thread_join(
/*=============*/ /*===========*/
os_thread_id_t thread_id); /* in: id of the thread to join */ os_thread_id_t thread_id); /* in: id of the thread to join */
/********************************************************************* /*********************************************************************
Exits the current thread. */ Exits the current thread. */
@ -142,4 +142,4 @@ os_thread_get_last_error(void);
#include "os0thread.ic" #include "os0thread.ic"
#endif #endif
#endif #endif

View File

@ -57,7 +57,7 @@ page_cur_get_rec(
/* out: record */ /* out: record */
page_cur_t* cur); /* in: page cursor */ page_cur_t* cur); /* in: page cursor */
/************************************************************* /*************************************************************
Sets the cursor object to point before the first user record Sets the cursor object to point before the first user record
on the page. */ on the page. */
UNIV_INLINE UNIV_INLINE
void void
@ -66,7 +66,7 @@ page_cur_set_before_first(
page_t* page, /* in: index page */ page_t* page, /* in: index page */
page_cur_t* cur); /* in: cursor */ page_cur_t* cur); /* in: cursor */
/************************************************************* /*************************************************************
Sets the cursor object to point after the last user record on Sets the cursor object to point after the last user record on
the page. */ the page. */
UNIV_INLINE UNIV_INLINE
void void
@ -178,13 +178,13 @@ page_copy_rec_list_end_to_created_page(
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
/*************************************************************** /***************************************************************
Deletes a record at the page cursor. The cursor is moved to the Deletes a record at the page cursor. The cursor is moved to the
next record after the deleted one. */ next record after the deleted one. */
void void
page_cur_delete_rec( page_cur_delete_rec(
/*================*/ /*================*/
page_cur_t* cursor, /* in: a page cursor */ page_cur_t* cursor, /* in: a page cursor */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */ const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
mtr_t* mtr); /* in: mini-transaction handle */ mtr_t* mtr); /* in: mini-transaction handle */
@ -224,7 +224,7 @@ page_cur_search_with_match(
ulint* ilow_matched_bytes, ulint* ilow_matched_bytes,
/* in/out: already matched bytes in a field /* in/out: already matched bytes in a field
not yet completely matched */ not yet completely matched */
page_cur_t* cursor); /* out: page cursor */ page_cur_t* cursor); /* out: page cursor */
/*************************************************************** /***************************************************************
Positions a page cursor on a randomly chosen user record on a page. If there Positions a page cursor on a randomly chosen user record on a page. If there
are no user records, sets the cursor on the infimum record. */ are no user records, sets the cursor on the infimum record. */
@ -282,4 +282,4 @@ struct page_cur_struct{
#include "page0cur.ic" #include "page0cur.ic"
#endif #endif
#endif #endif

View File

@ -38,7 +38,7 @@ page_cur_get_rec(
} }
/************************************************************* /*************************************************************
Sets the cursor object to point before the first user record Sets the cursor object to point before the first user record
on the page. */ on the page. */
UNIV_INLINE UNIV_INLINE
void void
@ -51,7 +51,7 @@ page_cur_set_before_first(
} }
/************************************************************* /*************************************************************
Sets the cursor object to point after the last user record on Sets the cursor object to point after the last user record on
the page. */ the page. */
UNIV_INLINE UNIV_INLINE
void void
@ -181,7 +181,7 @@ page_cur_tuple_insert(
/* out: pointer to record if succeed, NULL /* out: pointer to record if succeed, NULL
otherwise */ otherwise */
page_cur_t* cursor, /* in: a page cursor */ page_cur_t* cursor, /* in: a page cursor */
dtuple_t* tuple, /* in: pointer to a data tuple */ dtuple_t* tuple, /* in: pointer to a data tuple */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
mtr_t* mtr) /* in: mini-transaction handle */ mtr_t* mtr) /* in: mini-transaction handle */
{ {

View File

@ -115,7 +115,7 @@ typedef byte page_dir_slot_t;
typedef page_dir_slot_t page_dir_t; typedef page_dir_slot_t page_dir_t;
/* Offset of the directory start down from the page end. We call the /* Offset of the directory start down from the page end. We call the
slot with the highest file address directory start, as it points to slot with the highest file address directory start, as it points to
the first record in the list of records. */ the first record in the list of records. */
#define PAGE_DIR FIL_PAGE_DATA_END #define PAGE_DIR FIL_PAGE_DATA_END
@ -127,7 +127,7 @@ page end, when the page is empty */
#define PAGE_EMPTY_DIR_START (PAGE_DIR + 2 * PAGE_DIR_SLOT_SIZE) #define PAGE_EMPTY_DIR_START (PAGE_DIR + 2 * PAGE_DIR_SLOT_SIZE)
/* The maximum and minimum number of records owned by a directory slot. The /* The maximum and minimum number of records owned by a directory slot. The
number may drop below the minimum in the first and the last slot in the number may drop below the minimum in the first and the last slot in the
directory. */ directory. */
#define PAGE_DIR_SLOT_MAX_N_OWNED 8 #define PAGE_DIR_SLOT_MAX_N_OWNED 8
#define PAGE_DIR_SLOT_MIN_N_OWNED 4 #define PAGE_DIR_SLOT_MIN_N_OWNED 4
@ -234,20 +234,20 @@ the positive infinity in the alphabetical order. */
UNIV_INLINE UNIV_INLINE
int int
page_cmp_dtuple_rec_with_match( page_cmp_dtuple_rec_with_match(
/*===========================*/ /*===========================*/
/* out: 1, 0, -1, if dtuple is greater, equal, /* out: 1, 0, -1, if dtuple is greater, equal,
less than rec, respectively, when only the less than rec, respectively, when only the
common first fields are compared */ common first fields are compared */
dtuple_t* dtuple, /* in: data tuple */ dtuple_t* dtuple, /* in: data tuple */
rec_t* rec, /* in: physical record on a page; may also rec_t* rec, /* in: physical record on a page; may also
be page infimum or supremum, in which case be page infimum or supremum, in which case
matched-parameter values below are not matched-parameter values below are not
affected */ affected */
const ulint* offsets,/* in: array returned by rec_get_offsets() */ const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint* matched_fields, /* in/out: number of already completely ulint* matched_fields, /* in/out: number of already completely
matched fields; when function returns matched fields; when function returns
contains the value for current comparison */ contains the value for current comparison */
ulint* matched_bytes); /* in/out: number of already matched ulint* matched_bytes); /* in/out: number of already matched
bytes within the first field not completely bytes within the first field not completely
matched; when function returns contains the matched; when function returns contains the
value for current comparison */ value for current comparison */
@ -342,7 +342,7 @@ ulint
page_dir_slot_get_n_owned( page_dir_slot_get_n_owned(
/*======================*/ /*======================*/
/* out: number of records */ /* out: number of records */
page_dir_slot_t* slot); /* in: page directory slot */ page_dir_slot_t* slot); /* in: page directory slot */
/******************************************************************* /*******************************************************************
This is used to set the owned records field of a directory slot. */ This is used to set the owned records field of a directory slot. */
UNIV_INLINE UNIV_INLINE
@ -350,7 +350,7 @@ void
page_dir_slot_set_n_owned( page_dir_slot_set_n_owned(
/*======================*/ /*======================*/
page_dir_slot_t* slot, /* in: directory slot */ page_dir_slot_t* slot, /* in: directory slot */
ulint n); /* in: number of records owned ulint n); /* in: number of records owned
by the slot */ by the slot */
/**************************************************************** /****************************************************************
Calculates the space reserved for directory slots of a given Calculates the space reserved for directory slots of a given
@ -397,7 +397,7 @@ page_rec_get_next(
rec_t* rec); /* in: pointer to record, must not be page rec_t* rec); /* in: pointer to record, must not be page
supremum */ supremum */
/**************************************************************** /****************************************************************
Sets the pointer to the next record on the page. */ Sets the pointer to the next record on the page. */
UNIV_INLINE UNIV_INLINE
void void
page_rec_set_next( page_rec_set_next(
@ -436,7 +436,7 @@ TRUE if the record is the infimum record on a page. */
UNIV_INLINE UNIV_INLINE
ibool ibool
page_rec_is_infimum_low( page_rec_is_infimum_low(
/*=====================*/ /*====================*/
/* out: TRUE if the infimum record */ /* out: TRUE if the infimum record */
ulint offset);/* in: record offset on page */ ulint offset);/* in: record offset on page */
@ -548,7 +548,7 @@ page_mem_free(
/************************************************************** /**************************************************************
The index page creation function. */ The index page creation function. */
page_t* page_t*
page_create( page_create(
/*========*/ /*========*/
/* out: pointer to the page */ /* out: pointer to the page */
@ -651,19 +651,19 @@ Splits a directory slot which owns too many records. */
void void
page_dir_split_slot( page_dir_split_slot(
/*================*/ /*================*/
page_t* page, /* in: the index page in question */ page_t* page, /* in: the index page in question */
ulint slot_no); /* in: the directory slot */ ulint slot_no); /* in: the directory slot */
/***************************************************************** /*****************************************************************
Tries to balance the given directory slot with too few records Tries to balance the given directory slot with too few records
with the upper neighbor, so that there are at least the minimum number with the upper neighbor, so that there are at least the minimum number
of records owned by the slot; this may result in the merging of of records owned by the slot; this may result in the merging of
two slots. */ two slots. */
void void
page_dir_balance_slot( page_dir_balance_slot(
/*==================*/ /*==================*/
page_t* page, /* in: index page */ page_t* page, /* in: index page */
ulint slot_no); /* in: the directory slot */ ulint slot_no); /* in: the directory slot */
/************************************************************** /**************************************************************
Parses a log record of a record list end or start deletion. */ Parses a log record of a record list end or start deletion. */
@ -695,7 +695,7 @@ page_parse_create(
/**************************************************************** /****************************************************************
Prints record contents including the data relevant only in Prints record contents including the data relevant only in
the index page context. */ the index page context. */
void void
page_rec_print( page_rec_print(
/*===========*/ /*===========*/
@ -733,7 +733,7 @@ debugging purposes. */
void void
page_print( page_print(
/*======*/ /*=======*/
page_t* page, /* in: index page */ page_t* page, /* in: index page */
dict_index_t* index, /* in: dictionary index of the page */ dict_index_t* index, /* in: dictionary index of the page */
ulint dn, /* in: print dn first and last entries ulint dn, /* in: print dn first and last entries
@ -799,4 +799,4 @@ page_find_rec_with_heap_no(
#include "page0page.ic" #include "page0page.ic"
#endif #endif
#endif #endif

View File

@ -41,7 +41,7 @@ page_update_max_trx_id(
ut_ad(page); ut_ad(page);
if (ut_dulint_cmp(page_get_max_trx_id(page), trx_id) < 0) { if (ut_dulint_cmp(page_get_max_trx_id(page), trx_id) < 0) {
page_set_max_trx_id(page, trx_id); page_set_max_trx_id(page, trx_id);
} }
} }
@ -93,8 +93,8 @@ page_header_get_ptr(
ut_ad(page); ut_ad(page);
ut_ad((field == PAGE_FREE) ut_ad((field == PAGE_FREE)
|| (field == PAGE_LAST_INSERT) || (field == PAGE_LAST_INSERT)
|| (field == PAGE_HEAP_TOP)); || (field == PAGE_HEAP_TOP));
offs = page_header_get_field(page, field); offs = page_header_get_field(page, field);
@ -122,8 +122,8 @@ page_header_set_ptr(
ut_ad(page); ut_ad(page);
ut_ad((field == PAGE_FREE) ut_ad((field == PAGE_FREE)
|| (field == PAGE_LAST_INSERT) || (field == PAGE_LAST_INSERT)
|| (field == PAGE_HEAP_TOP)); || (field == PAGE_HEAP_TOP));
if (ptr == NULL) { if (ptr == NULL) {
offs = 0; offs = 0;
@ -177,13 +177,13 @@ page_rec_is_comp(
{ {
#ifdef UNIV_RELEASE_NOT_YET_STABLE #ifdef UNIV_RELEASE_NOT_YET_STABLE
if (UNIV_UNLIKELY((ulint)rec < (ulint)(buf_pool->frame_zero)) if (UNIV_UNLIKELY((ulint)rec < (ulint)(buf_pool->frame_zero))
|| UNIV_UNLIKELY((ulint)rec >= (ulint)(buf_pool->high_end))) { || UNIV_UNLIKELY((ulint)rec >= (ulint)(buf_pool->high_end))) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: trying to read a stray page rec %p\n" "InnoDB: Error: trying to read a stray page rec %p\n"
"InnoDB: buf pool start is at %p, end at %p\n", "InnoDB: buf pool start is at %p, end at %p\n",
rec, buf_pool->frame_zero, rec, buf_pool->frame_zero,
buf_pool->high_end); buf_pool->high_end);
ut_error; ut_error;
} }
@ -284,7 +284,7 @@ TRUE if the record is the infimum record on a page. */
UNIV_INLINE UNIV_INLINE
ibool ibool
page_rec_is_infimum_low( page_rec_is_infimum_low(
/*=====================*/ /*====================*/
/* out: TRUE if the infimum record */ /* out: TRUE if the infimum record */
ulint offset) /* in: record offset on page */ ulint offset) /* in: record offset on page */
{ {
@ -343,20 +343,20 @@ the positive infinity in the alphabetical order. */
UNIV_INLINE UNIV_INLINE
int int
page_cmp_dtuple_rec_with_match( page_cmp_dtuple_rec_with_match(
/*===========================*/ /*===========================*/
/* out: 1, 0, -1, if dtuple is greater, equal, /* out: 1, 0, -1, if dtuple is greater, equal,
less than rec, respectively, when only the less than rec, respectively, when only the
common first fields are compared */ common first fields are compared */
dtuple_t* dtuple, /* in: data tuple */ dtuple_t* dtuple, /* in: data tuple */
rec_t* rec, /* in: physical record on a page; may also rec_t* rec, /* in: physical record on a page; may also
be page infimum or supremum, in which case be page infimum or supremum, in which case
matched-parameter values below are not matched-parameter values below are not
affected */ affected */
const ulint* offsets,/* in: array returned by rec_get_offsets() */ const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint* matched_fields, /* in/out: number of already completely ulint* matched_fields, /* in/out: number of already completely
matched fields; when function returns matched fields; when function returns
contains the value for current comparison */ contains the value for current comparison */
ulint* matched_bytes) /* in/out: number of already matched ulint* matched_bytes) /* in/out: number of already matched
bytes within the first field not completely bytes within the first field not completely
matched; when function returns contains the matched; when function returns contains the
value for current comparison */ value for current comparison */
@ -461,7 +461,7 @@ page_dir_get_nth_slot(
return(page + UNIV_PAGE_SIZE - PAGE_DIR return(page + UNIV_PAGE_SIZE - PAGE_DIR
- (n + 1) * PAGE_DIR_SLOT_SIZE); - (n + 1) * PAGE_DIR_SLOT_SIZE);
} }
/****************************************************************** /******************************************************************
Used to check the consistency of a record on a page. */ Used to check the consistency of a record on a page. */
@ -474,7 +474,7 @@ page_rec_check(
{ {
page_t* page; page_t* page;
ut_a(rec); ut_a(rec);
page = buf_frame_align(rec); page = buf_frame_align(rec);
@ -517,7 +517,7 @@ ulint
page_dir_slot_get_n_owned( page_dir_slot_get_n_owned(
/*======================*/ /*======================*/
/* out: number of records */ /* out: number of records */
page_dir_slot_t* slot) /* in: page directory slot */ page_dir_slot_t* slot) /* in: page directory slot */
{ {
rec_t* rec = page_dir_slot_get_rec(slot); rec_t* rec = page_dir_slot_get_rec(slot);
return(rec_get_n_owned(rec, page_rec_is_comp(rec))); return(rec_get_n_owned(rec, page_rec_is_comp(rec)));
@ -530,7 +530,7 @@ void
page_dir_slot_set_n_owned( page_dir_slot_set_n_owned(
/*======================*/ /*======================*/
page_dir_slot_t* slot, /* in: directory slot */ page_dir_slot_t* slot, /* in: directory slot */
ulint n) /* in: number of records owned ulint n) /* in: number of records owned
by the slot */ by the slot */
{ {
rec_t* rec = page_dir_slot_get_rec(slot); rec_t* rec = page_dir_slot_get_rec(slot);
@ -549,7 +549,7 @@ page_dir_calc_reserved_space(
{ {
return((PAGE_DIR_SLOT_SIZE * n_recs + PAGE_DIR_SLOT_MIN_N_OWNED - 1) return((PAGE_DIR_SLOT_SIZE * n_recs + PAGE_DIR_SLOT_MIN_N_OWNED - 1)
/ PAGE_DIR_SLOT_MIN_N_OWNED); / PAGE_DIR_SLOT_MIN_N_OWNED);
} }
/**************************************************************** /****************************************************************
Gets the pointer to the next record on the page. */ Gets the pointer to the next record on the page. */
@ -563,7 +563,7 @@ page_rec_get_next(
ulint offs; ulint offs;
page_t* page; page_t* page;
ut_ad(page_rec_check(rec)); ut_ad(page_rec_check(rec));
page = ut_align_down(rec, UNIV_PAGE_SIZE); page = ut_align_down(rec, UNIV_PAGE_SIZE);
@ -584,7 +584,7 @@ page_rec_get_next(
} }
if (UNIV_UNLIKELY(offs == 0)) { if (UNIV_UNLIKELY(offs == 0)) {
return(NULL); return(NULL);
} }
@ -592,7 +592,7 @@ page_rec_get_next(
} }
/**************************************************************** /****************************************************************
Sets the pointer to the next record on the page. */ Sets the pointer to the next record on the page. */
UNIV_INLINE UNIV_INLINE
void void
page_rec_set_next( page_rec_set_next(
@ -604,7 +604,7 @@ page_rec_set_next(
page_t* page; page_t* page;
ulint offs; ulint offs;
ut_ad(page_rec_check(rec)); ut_ad(page_rec_check(rec));
ut_ad(!page_rec_is_supremum(rec)); ut_ad(!page_rec_is_supremum(rec));
page = ut_align_down(rec, UNIV_PAGE_SIZE); page = ut_align_down(rec, UNIV_PAGE_SIZE);
@ -635,7 +635,7 @@ page_rec_get_prev(
rec_t* prev_rec = NULL; rec_t* prev_rec = NULL;
page_t* page; page_t* page;
ut_ad(page_rec_check(rec)); ut_ad(page_rec_check(rec));
page = ut_align_down(rec, UNIV_PAGE_SIZE); page = ut_align_down(rec, UNIV_PAGE_SIZE);
@ -644,16 +644,16 @@ page_rec_get_prev(
slot_no = page_dir_find_owner_slot(rec); slot_no = page_dir_find_owner_slot(rec);
ut_a(slot_no != 0); ut_a(slot_no != 0);
slot = page_dir_get_nth_slot(page, slot_no - 1); slot = page_dir_get_nth_slot(page, slot_no - 1);
rec2 = page_dir_slot_get_rec(slot); rec2 = page_dir_slot_get_rec(slot);
while (rec != rec2) { while (rec != rec2) {
prev_rec = rec2; prev_rec = rec2;
rec2 = page_rec_get_next(rec2); rec2 = page_rec_get_next(rec2);
} }
ut_a(prev_rec); ut_a(prev_rec);
return(prev_rec); return(prev_rec);
@ -696,10 +696,10 @@ page_get_data_size(
ulint ret; ulint ret;
ret = (ulint)(page_header_get_field(page, PAGE_HEAP_TOP) ret = (ulint)(page_header_get_field(page, PAGE_HEAP_TOP)
- (page_is_comp(page) - (page_is_comp(page)
? PAGE_NEW_SUPREMUM_END ? PAGE_NEW_SUPREMUM_END
: PAGE_OLD_SUPREMUM_END) : PAGE_OLD_SUPREMUM_END)
- page_header_get_field(page, PAGE_GARBAGE)); - page_header_get_field(page, PAGE_GARBAGE));
ut_ad(ret < UNIV_PAGE_SIZE); ut_ad(ret < UNIV_PAGE_SIZE);

View File

@ -13,10 +13,10 @@ Created 2/2/1994 Heikki Tuuri
/* Type of the index page */ /* Type of the index page */
/* The following define eliminates a name collision on HP-UX */ /* The following define eliminates a name collision on HP-UX */
#define page_t ib_page_t #define page_t ib_page_t
typedef byte page_t; typedef byte page_t;
typedef struct page_search_struct page_search_t; typedef struct page_search_struct page_search_t;
typedef struct page_cur_struct page_cur_t; typedef struct page_cur_struct page_cur_t;
#endif #endif

View File

@ -1,90 +1,220 @@
#ifndef YYSTYPE /* A Bison parser, made by GNU Bison 1.875d. */
#define YYSTYPE int
#endif
#define PARS_INT_LIT 257
#define PARS_FLOAT_LIT 258
#define PARS_STR_LIT 259
#define PARS_NULL_LIT 260
#define PARS_ID_TOKEN 261
#define PARS_AND_TOKEN 262
#define PARS_OR_TOKEN 263
#define PARS_NOT_TOKEN 264
#define PARS_GE_TOKEN 265
#define PARS_LE_TOKEN 266
#define PARS_NE_TOKEN 267
#define PARS_PROCEDURE_TOKEN 268
#define PARS_IN_TOKEN 269
#define PARS_OUT_TOKEN 270
#define PARS_INT_TOKEN 271
#define PARS_INTEGER_TOKEN 272
#define PARS_FLOAT_TOKEN 273
#define PARS_CHAR_TOKEN 274
#define PARS_IS_TOKEN 275
#define PARS_BEGIN_TOKEN 276
#define PARS_END_TOKEN 277
#define PARS_IF_TOKEN 278
#define PARS_THEN_TOKEN 279
#define PARS_ELSE_TOKEN 280
#define PARS_ELSIF_TOKEN 281
#define PARS_LOOP_TOKEN 282
#define PARS_WHILE_TOKEN 283
#define PARS_RETURN_TOKEN 284
#define PARS_SELECT_TOKEN 285
#define PARS_SUM_TOKEN 286
#define PARS_COUNT_TOKEN 287
#define PARS_DISTINCT_TOKEN 288
#define PARS_FROM_TOKEN 289
#define PARS_WHERE_TOKEN 290
#define PARS_FOR_TOKEN 291
#define PARS_DDOT_TOKEN 292
#define PARS_CONSISTENT_TOKEN 293
#define PARS_READ_TOKEN 294
#define PARS_ORDER_TOKEN 295
#define PARS_BY_TOKEN 296
#define PARS_ASC_TOKEN 297
#define PARS_DESC_TOKEN 298
#define PARS_INSERT_TOKEN 299
#define PARS_INTO_TOKEN 300
#define PARS_VALUES_TOKEN 301
#define PARS_UPDATE_TOKEN 302
#define PARS_SET_TOKEN 303
#define PARS_DELETE_TOKEN 304
#define PARS_CURRENT_TOKEN 305
#define PARS_OF_TOKEN 306
#define PARS_CREATE_TOKEN 307
#define PARS_TABLE_TOKEN 308
#define PARS_INDEX_TOKEN 309
#define PARS_UNIQUE_TOKEN 310
#define PARS_CLUSTERED_TOKEN 311
#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 312
#define PARS_ON_TOKEN 313
#define PARS_ASSIGN_TOKEN 314
#define PARS_DECLARE_TOKEN 315
#define PARS_CURSOR_TOKEN 316
#define PARS_SQL_TOKEN 317
#define PARS_OPEN_TOKEN 318
#define PARS_FETCH_TOKEN 319
#define PARS_CLOSE_TOKEN 320
#define PARS_NOTFOUND_TOKEN 321
#define PARS_TO_CHAR_TOKEN 322
#define PARS_TO_NUMBER_TOKEN 323
#define PARS_TO_BINARY_TOKEN 324
#define PARS_BINARY_TO_NUMBER_TOKEN 325
#define PARS_SUBSTR_TOKEN 326
#define PARS_REPLSTR_TOKEN 327
#define PARS_CONCAT_TOKEN 328
#define PARS_INSTR_TOKEN 329
#define PARS_LENGTH_TOKEN 330
#define PARS_SYSDATE_TOKEN 331
#define PARS_PRINTF_TOKEN 332
#define PARS_ASSERT_TOKEN 333
#define PARS_RND_TOKEN 334
#define PARS_RND_STR_TOKEN 335
#define PARS_ROW_PRINTF_TOKEN 336
#define PARS_COMMIT_TOKEN 337
#define PARS_ROLLBACK_TOKEN 338
#define PARS_WORK_TOKEN 339
#define NEG 340
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
PARS_INT_LIT = 258,
PARS_FLOAT_LIT = 259,
PARS_STR_LIT = 260,
PARS_NULL_LIT = 261,
PARS_ID_TOKEN = 262,
PARS_AND_TOKEN = 263,
PARS_OR_TOKEN = 264,
PARS_NOT_TOKEN = 265,
PARS_GE_TOKEN = 266,
PARS_LE_TOKEN = 267,
PARS_NE_TOKEN = 268,
PARS_PROCEDURE_TOKEN = 269,
PARS_IN_TOKEN = 270,
PARS_OUT_TOKEN = 271,
PARS_BINARY_TOKEN = 272,
PARS_BLOB_TOKEN = 273,
PARS_INT_TOKEN = 274,
PARS_INTEGER_TOKEN = 275,
PARS_FLOAT_TOKEN = 276,
PARS_CHAR_TOKEN = 277,
PARS_IS_TOKEN = 278,
PARS_BEGIN_TOKEN = 279,
PARS_END_TOKEN = 280,
PARS_IF_TOKEN = 281,
PARS_THEN_TOKEN = 282,
PARS_ELSE_TOKEN = 283,
PARS_ELSIF_TOKEN = 284,
PARS_LOOP_TOKEN = 285,
PARS_WHILE_TOKEN = 286,
PARS_RETURN_TOKEN = 287,
PARS_SELECT_TOKEN = 288,
PARS_SUM_TOKEN = 289,
PARS_COUNT_TOKEN = 290,
PARS_DISTINCT_TOKEN = 291,
PARS_FROM_TOKEN = 292,
PARS_WHERE_TOKEN = 293,
PARS_FOR_TOKEN = 294,
PARS_DDOT_TOKEN = 295,
PARS_CONSISTENT_TOKEN = 296,
PARS_READ_TOKEN = 297,
PARS_ORDER_TOKEN = 298,
PARS_BY_TOKEN = 299,
PARS_ASC_TOKEN = 300,
PARS_DESC_TOKEN = 301,
PARS_INSERT_TOKEN = 302,
PARS_INTO_TOKEN = 303,
PARS_VALUES_TOKEN = 304,
PARS_UPDATE_TOKEN = 305,
PARS_SET_TOKEN = 306,
PARS_DELETE_TOKEN = 307,
PARS_CURRENT_TOKEN = 308,
PARS_OF_TOKEN = 309,
PARS_CREATE_TOKEN = 310,
PARS_TABLE_TOKEN = 311,
PARS_INDEX_TOKEN = 312,
PARS_UNIQUE_TOKEN = 313,
PARS_CLUSTERED_TOKEN = 314,
PARS_DOES_NOT_FIT_IN_MEM_TOKEN = 315,
PARS_ON_TOKEN = 316,
PARS_ASSIGN_TOKEN = 317,
PARS_DECLARE_TOKEN = 318,
PARS_CURSOR_TOKEN = 319,
PARS_SQL_TOKEN = 320,
PARS_OPEN_TOKEN = 321,
PARS_FETCH_TOKEN = 322,
PARS_CLOSE_TOKEN = 323,
PARS_NOTFOUND_TOKEN = 324,
PARS_TO_CHAR_TOKEN = 325,
PARS_TO_NUMBER_TOKEN = 326,
PARS_TO_BINARY_TOKEN = 327,
PARS_BINARY_TO_NUMBER_TOKEN = 328,
PARS_SUBSTR_TOKEN = 329,
PARS_REPLSTR_TOKEN = 330,
PARS_CONCAT_TOKEN = 331,
PARS_INSTR_TOKEN = 332,
PARS_LENGTH_TOKEN = 333,
PARS_SYSDATE_TOKEN = 334,
PARS_PRINTF_TOKEN = 335,
PARS_ASSERT_TOKEN = 336,
PARS_RND_TOKEN = 337,
PARS_RND_STR_TOKEN = 338,
PARS_ROW_PRINTF_TOKEN = 339,
PARS_COMMIT_TOKEN = 340,
PARS_ROLLBACK_TOKEN = 341,
PARS_WORK_TOKEN = 342,
NEG = 343
};
#endif
#define PARS_INT_LIT 258
#define PARS_FLOAT_LIT 259
#define PARS_STR_LIT 260
#define PARS_NULL_LIT 261
#define PARS_ID_TOKEN 262
#define PARS_AND_TOKEN 263
#define PARS_OR_TOKEN 264
#define PARS_NOT_TOKEN 265
#define PARS_GE_TOKEN 266
#define PARS_LE_TOKEN 267
#define PARS_NE_TOKEN 268
#define PARS_PROCEDURE_TOKEN 269
#define PARS_IN_TOKEN 270
#define PARS_OUT_TOKEN 271
#define PARS_BINARY_TOKEN 272
#define PARS_BLOB_TOKEN 273
#define PARS_INT_TOKEN 274
#define PARS_INTEGER_TOKEN 275
#define PARS_FLOAT_TOKEN 276
#define PARS_CHAR_TOKEN 277
#define PARS_IS_TOKEN 278
#define PARS_BEGIN_TOKEN 279
#define PARS_END_TOKEN 280
#define PARS_IF_TOKEN 281
#define PARS_THEN_TOKEN 282
#define PARS_ELSE_TOKEN 283
#define PARS_ELSIF_TOKEN 284
#define PARS_LOOP_TOKEN 285
#define PARS_WHILE_TOKEN 286
#define PARS_RETURN_TOKEN 287
#define PARS_SELECT_TOKEN 288
#define PARS_SUM_TOKEN 289
#define PARS_COUNT_TOKEN 290
#define PARS_DISTINCT_TOKEN 291
#define PARS_FROM_TOKEN 292
#define PARS_WHERE_TOKEN 293
#define PARS_FOR_TOKEN 294
#define PARS_DDOT_TOKEN 295
#define PARS_CONSISTENT_TOKEN 296
#define PARS_READ_TOKEN 297
#define PARS_ORDER_TOKEN 298
#define PARS_BY_TOKEN 299
#define PARS_ASC_TOKEN 300
#define PARS_DESC_TOKEN 301
#define PARS_INSERT_TOKEN 302
#define PARS_INTO_TOKEN 303
#define PARS_VALUES_TOKEN 304
#define PARS_UPDATE_TOKEN 305
#define PARS_SET_TOKEN 306
#define PARS_DELETE_TOKEN 307
#define PARS_CURRENT_TOKEN 308
#define PARS_OF_TOKEN 309
#define PARS_CREATE_TOKEN 310
#define PARS_TABLE_TOKEN 311
#define PARS_INDEX_TOKEN 312
#define PARS_UNIQUE_TOKEN 313
#define PARS_CLUSTERED_TOKEN 314
#define PARS_DOES_NOT_FIT_IN_MEM_TOKEN 315
#define PARS_ON_TOKEN 316
#define PARS_ASSIGN_TOKEN 317
#define PARS_DECLARE_TOKEN 318
#define PARS_CURSOR_TOKEN 319
#define PARS_SQL_TOKEN 320
#define PARS_OPEN_TOKEN 321
#define PARS_FETCH_TOKEN 322
#define PARS_CLOSE_TOKEN 323
#define PARS_NOTFOUND_TOKEN 324
#define PARS_TO_CHAR_TOKEN 325
#define PARS_TO_NUMBER_TOKEN 326
#define PARS_TO_BINARY_TOKEN 327
#define PARS_BINARY_TO_NUMBER_TOKEN 328
#define PARS_SUBSTR_TOKEN 329
#define PARS_REPLSTR_TOKEN 330
#define PARS_CONCAT_TOKEN 331
#define PARS_INSTR_TOKEN 332
#define PARS_LENGTH_TOKEN 333
#define PARS_SYSDATE_TOKEN 334
#define PARS_PRINTF_TOKEN 335
#define PARS_ASSERT_TOKEN 336
#define PARS_RND_TOKEN 337
#define PARS_RND_STR_TOKEN 338
#define PARS_ROW_PRINTF_TOKEN 339
#define PARS_COMMIT_TOKEN 340
#define PARS_ROLLBACK_TOKEN 341
#define PARS_WORK_TOKEN 342
#define NEG 343
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval; extern YYSTYPE yylval;

View File

@ -55,4 +55,4 @@ opt_print_query_plan(
#include "pars0opt.ic" #include "pars0opt.ic"
#endif #endif
#endif #endif

View File

@ -46,6 +46,8 @@ extern pars_res_word_t pars_rnd_str_token;
extern pars_res_word_t pars_count_token; extern pars_res_word_t pars_count_token;
extern pars_res_word_t pars_sum_token; extern pars_res_word_t pars_sum_token;
extern pars_res_word_t pars_distinct_token; extern pars_res_word_t pars_distinct_token;
extern pars_res_word_t pars_binary_token;
extern pars_res_word_t pars_blob_token;
extern pars_res_word_t pars_int_token; extern pars_res_word_t pars_int_token;
extern pars_res_word_t pars_char_token; extern pars_res_word_t pars_char_token;
extern pars_res_word_t pars_float_token; extern pars_res_word_t pars_float_token;
@ -59,7 +61,7 @@ extern pars_res_word_t pars_unique_token;
extern pars_res_word_t pars_clustered_token; extern pars_res_word_t pars_clustered_token;
extern ulint pars_star_denoter; extern ulint pars_star_denoter;
/* Procedure parameter types */ /* Procedure parameter types */
#define PARS_INPUT 0 #define PARS_INPUT 0
#define PARS_OUTPUT 1 #define PARS_OUTPUT 1
@ -111,7 +113,7 @@ func_node_t*
pars_func( pars_func(
/*======*/ /*======*/
/* out, own: function node in a query tree */ /* out, own: function node in a query tree */
que_node_t* res_word,/* in: function name reserved word */ que_node_t* res_word,/* in: function name reserved word */
que_node_t* arg); /* in: first argument in the argument list */ que_node_t* arg); /* in: first argument in the argument list */
/************************************************************************* /*************************************************************************
Parses an operator expression. */ Parses an operator expression. */
@ -190,7 +192,7 @@ pars_update_statement_start(
ibool is_delete, /* in: TRUE if delete */ ibool is_delete, /* in: TRUE if delete */
sym_node_t* table_sym, /* in: table name node */ sym_node_t* table_sym, /* in: table name node */
col_assign_node_t* col_assign_list);/* in: column assignment list, NULL col_assign_node_t* col_assign_list);/* in: column assignment list, NULL
if delete */ if delete */
/************************************************************************* /*************************************************************************
Parses an update or delete statement. */ Parses an update or delete statement. */
@ -212,7 +214,7 @@ pars_insert_statement(
/* out, own: update node in a query /* out, own: update node in a query
tree */ tree */
sym_node_t* table_sym, /* in: table name node */ sym_node_t* table_sym, /* in: table name node */
que_node_t* values_list, /* in: value expression list or NULL */ que_node_t* values_list, /* in: value expression list or NULL */
sel_node_t* select); /* in: select condition or NULL */ sel_node_t* select); /* in: select condition or NULL */
/************************************************************************* /*************************************************************************
Parses a procedure parameter declaration. */ Parses a procedure parameter declaration. */
@ -336,10 +338,15 @@ Parses a column definition at a table creation. */
sym_node_t* sym_node_t*
pars_column_def( pars_column_def(
/*============*/ /*============*/
/* out: column sym table node */ /* out: column sym table
sym_node_t* sym_node, /* in: column node in the symbol node */
table */ sym_node_t* sym_node, /* in: column node in the
pars_res_word_t* type); /* in: data type */ symbol table */
pars_res_word_t* type, /* in: data type */
sym_node_t* len, /* in: length of column, or
NULL */
void* is_not_null); /* in: if not NULL, column
is of type NOT NULL. */
/************************************************************************* /*************************************************************************
Parses a table creation operation. */ Parses a table creation operation. */
@ -464,7 +471,7 @@ struct if_node_struct{
que_node_t* cond; /* if condition */ que_node_t* cond; /* if condition */
que_node_t* stat_list; /* statement list */ que_node_t* stat_list; /* statement list */
que_node_t* else_part; /* else-part statement list */ que_node_t* else_part; /* else-part statement list */
elsif_node_t* elsif_list; /* elsif element list */ elsif_node_t* elsif_list; /* elsif element list */
}; };
/* while-statement node */ /* while-statement node */
@ -523,4 +530,4 @@ struct col_assign_node_struct{
#include "pars0pars.ic" #include "pars0pars.ic"
#endif #endif
#endif #endif

View File

@ -74,7 +74,7 @@ sym_tab_add_id(
#define SYM_CLUST_FIELD_NO 0 #define SYM_CLUST_FIELD_NO 0
#define SYM_SEC_FIELD_NO 1 #define SYM_SEC_FIELD_NO 1
struct sym_node_struct{ struct sym_node_struct{
que_common_t common; /* node type: que_common_t common; /* node type:
QUE_NODE_SYMBOL */ QUE_NODE_SYMBOL */
@ -185,4 +185,4 @@ struct sym_tab_struct{
#include "pars0sym.ic" #include "pars0sym.ic"
#endif #endif
#endif #endif

Some files were not shown because too many files have changed in this diff Show More