mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge XtraDB 9 into MariaDB.
This commit is contained in:
@ -85,6 +85,7 @@ TABLE_PRIVILEGES
|
||||
TRIGGERS
|
||||
USER_PRIVILEGES
|
||||
VIEWS
|
||||
XTRADB_ADMIN_COMMAND
|
||||
XTRADB_ENHANCEMENTS
|
||||
columns_priv
|
||||
db
|
||||
@ -865,8 +866,8 @@ TABLE_CONSTRAINTS TABLE_NAME select
|
||||
TABLE_PRIVILEGES TABLE_NAME select
|
||||
VIEWS TABLE_NAME select
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX table_name select
|
||||
INNODB_INDEX_STATS table_name select
|
||||
INNODB_TABLE_STATS table_name select
|
||||
INNODB_INDEX_STATS table_name select
|
||||
delete from mysql.user where user='mysqltest_4';
|
||||
delete from mysql.db where user='mysqltest_4';
|
||||
flush privileges;
|
||||
|
@ -35,7 +35,7 @@ INNODB_CMP
|
||||
INNODB_RSEG
|
||||
XTRADB_ENHANCEMENTS
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX
|
||||
INNODB_INDEX_STATS
|
||||
XTRADB_ADMIN_COMMAND
|
||||
INNODB_TRX
|
||||
INNODB_CMP_RESET
|
||||
INNODB_LOCK_WAITS
|
||||
@ -44,6 +44,7 @@ INNODB_LOCKS
|
||||
INNODB_CMPMEM
|
||||
INNODB_TABLE_STATS
|
||||
INNODB_BUFFER_POOL_PAGES_BLOB
|
||||
INNODB_INDEX_STATS
|
||||
SELECT t.table_name, c1.column_name
|
||||
FROM information_schema.tables t
|
||||
INNER JOIN
|
||||
@ -93,7 +94,7 @@ INNODB_CMP page_size
|
||||
INNODB_RSEG rseg_id
|
||||
XTRADB_ENHANCEMENTS name
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX schema_name
|
||||
INNODB_INDEX_STATS table_name
|
||||
XTRADB_ADMIN_COMMAND result_message
|
||||
INNODB_TRX trx_id
|
||||
INNODB_CMP_RESET page_size
|
||||
INNODB_LOCK_WAITS requesting_trx_id
|
||||
@ -102,6 +103,7 @@ INNODB_LOCKS lock_id
|
||||
INNODB_CMPMEM page_size
|
||||
INNODB_TABLE_STATS table_name
|
||||
INNODB_BUFFER_POOL_PAGES_BLOB space_id
|
||||
INNODB_INDEX_STATS table_name
|
||||
SELECT t.table_name, c1.column_name
|
||||
FROM information_schema.tables t
|
||||
INNER JOIN
|
||||
@ -151,7 +153,7 @@ INNODB_CMP page_size
|
||||
INNODB_RSEG rseg_id
|
||||
XTRADB_ENHANCEMENTS name
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX schema_name
|
||||
INNODB_INDEX_STATS table_name
|
||||
XTRADB_ADMIN_COMMAND result_message
|
||||
INNODB_TRX trx_id
|
||||
INNODB_CMP_RESET page_size
|
||||
INNODB_LOCK_WAITS requesting_trx_id
|
||||
@ -160,6 +162,7 @@ INNODB_LOCKS lock_id
|
||||
INNODB_CMPMEM page_size
|
||||
INNODB_TABLE_STATS table_name
|
||||
INNODB_BUFFER_POOL_PAGES_BLOB space_id
|
||||
INNODB_INDEX_STATS table_name
|
||||
select 1 as f1 from information_schema.tables where "CHARACTER_SETS"=
|
||||
(select cast(table_name as char) from information_schema.tables
|
||||
order by table_name limit 1) limit 1;
|
||||
@ -262,7 +265,7 @@ Database: information_schema
|
||||
| INNODB_RSEG |
|
||||
| XTRADB_ENHANCEMENTS |
|
||||
| INNODB_BUFFER_POOL_PAGES_INDEX |
|
||||
| INNODB_INDEX_STATS |
|
||||
| XTRADB_ADMIN_COMMAND |
|
||||
| INNODB_TRX |
|
||||
| INNODB_CMP_RESET |
|
||||
| INNODB_LOCK_WAITS |
|
||||
@ -271,6 +274,7 @@ Database: information_schema
|
||||
| INNODB_CMPMEM |
|
||||
| INNODB_TABLE_STATS |
|
||||
| INNODB_BUFFER_POOL_PAGES_BLOB |
|
||||
| INNODB_INDEX_STATS |
|
||||
+---------------------------------------+
|
||||
Database: INFORMATION_SCHEMA
|
||||
+---------------------------------------+
|
||||
@ -310,7 +314,7 @@ Database: INFORMATION_SCHEMA
|
||||
| INNODB_RSEG |
|
||||
| XTRADB_ENHANCEMENTS |
|
||||
| INNODB_BUFFER_POOL_PAGES_INDEX |
|
||||
| INNODB_INDEX_STATS |
|
||||
| XTRADB_ADMIN_COMMAND |
|
||||
| INNODB_TRX |
|
||||
| INNODB_CMP_RESET |
|
||||
| INNODB_LOCK_WAITS |
|
||||
@ -319,6 +323,7 @@ Database: INFORMATION_SCHEMA
|
||||
| INNODB_CMPMEM |
|
||||
| INNODB_TABLE_STATS |
|
||||
| INNODB_BUFFER_POOL_PAGES_BLOB |
|
||||
| INNODB_INDEX_STATS |
|
||||
+---------------------------------------+
|
||||
Wildcard: inf_rmation_schema
|
||||
+--------------------+
|
||||
@ -328,5 +333,5 @@ Wildcard: inf_rmation_schema
|
||||
+--------------------+
|
||||
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
|
||||
table_schema count(*)
|
||||
information_schema 43
|
||||
information_schema 44
|
||||
mysql 22
|
||||
|
@ -875,11 +875,11 @@ ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
|
||||
SELECT * FROM t1;
|
||||
d1
|
||||
1
|
||||
3
|
||||
2
|
||||
SELECT * FROM t1;
|
||||
d1
|
||||
1
|
||||
3
|
||||
2
|
||||
INSERT INTO t1 VALUES(null);
|
||||
Got one of the listed errors
|
||||
ALTER TABLE t1 AUTO_INCREMENT = 3;
|
||||
@ -888,13 +888,13 @@ Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`d1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`d1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
|
||||
INSERT INTO t1 VALUES(null);
|
||||
SELECT * FROM t1;
|
||||
d1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
|
35
mysql-test/r/innodb-consistent.result
Normal file
35
mysql-test/r/innodb-consistent.result
Normal file
@ -0,0 +1,35 @@
|
||||
drop table if exists t1;
|
||||
set session transaction isolation level read committed;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
create table t2 like t1;
|
||||
insert into t2 values (1),(2),(3),(4),(5),(6),(7);
|
||||
set autocommit=0;
|
||||
begin;
|
||||
replace into t1 select * from t2;
|
||||
set session transaction isolation level read committed;
|
||||
set autocommit=0;
|
||||
delete from t2 where a=5;
|
||||
commit;
|
||||
delete from t2;
|
||||
commit;
|
||||
commit;
|
||||
begin;
|
||||
insert into t1 select * from t2;
|
||||
set session transaction isolation level read committed;
|
||||
set autocommit=0;
|
||||
delete from t2 where a=5;
|
||||
commit;
|
||||
delete from t2;
|
||||
commit;
|
||||
commit;
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
drop table t1;
|
||||
drop table t2;
|
@ -1,4 +1,3 @@
|
||||
SET @save_innodb_file_format_check=@@global.innodb_file_format_check;
|
||||
create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb;
|
||||
insert into t1 values (5,5,'oo','oo'),(4,4,'tr','tr'),(3,4,'ad','ad'),(2,3,'ak','ak');
|
||||
commit;
|
||||
@ -629,7 +628,7 @@ drop table t1;
|
||||
create table t1(a int not null, b int, c char(10), d varchar(20), primary key (a)) engine = innodb;
|
||||
insert into t1 values (1,1,'ab','ab'),(2,2,'ac','ac'),(3,3,'ac','ac'),(4,4,'afe','afe'),(5,4,'affe','affe');
|
||||
alter table t1 add unique index (b), add unique index (c), add unique index (d);
|
||||
ERROR 23000: Duplicate entry '4' for key 'b'
|
||||
ERROR 23000: Duplicate entry 'ac' for key 'c'
|
||||
alter table t1 add unique index (c), add unique index (b), add index (d);
|
||||
ERROR 23000: Duplicate entry 'ac' for key 'c'
|
||||
show create table t1;
|
||||
@ -970,6 +969,7 @@ create index t1u on t1 (u(1));
|
||||
drop table t1;
|
||||
set global innodb_file_per_table=0;
|
||||
set global innodb_file_format=Antelope;
|
||||
set global innodb_file_format_check=Antelope;
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
CREATE TABLE t1(
|
||||
@ -1171,4 +1171,3 @@ a b
|
||||
3 a
|
||||
3 b
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL innodb_file_format_check=@save_innodb_file_format_check;
|
||||
|
@ -196,15 +196,15 @@ drop table t1;
|
||||
set innodb_strict_mode = on;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 0;
|
||||
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16]
|
||||
Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16]
|
||||
Error 1005 Can't create table 'test.t1' (errno: 1478)
|
||||
create table t2 (id int primary key) engine = innodb key_block_size = 9;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
|
||||
Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
|
||||
Error 1005 Can't create table 'test.t2' (errno: 1478)
|
||||
create table t3 (id int primary key) engine = innodb key_block_size = 1;
|
||||
create table t4 (id int primary key) engine = innodb key_block_size = 2;
|
||||
@ -233,30 +233,30 @@ key_block_size = 8 row_format = compressed;
|
||||
create table t2 (id int primary key) engine = innodb
|
||||
key_block_size = 8 row_format = redundant;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
|
||||
Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 1478)
|
||||
create table t3 (id int primary key) engine = innodb
|
||||
key_block_size = 8 row_format = compact;
|
||||
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
|
||||
Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
|
||||
Error 1005 Can't create table 'test.t3' (errno: 1478)
|
||||
create table t4 (id int primary key) engine = innodb
|
||||
key_block_size = 8 row_format = dynamic;
|
||||
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
|
||||
Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
|
||||
Error 1005 Can't create table 'test.t4' (errno: 1478)
|
||||
create table t5 (id int primary key) engine = innodb
|
||||
key_block_size = 8 row_format = default;
|
||||
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
|
||||
Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
|
||||
Error 1005 Can't create table 'test.t5' (errno: 1478)
|
||||
SELECT table_schema, table_name, row_format
|
||||
FROM information_schema.tables WHERE engine='innodb';
|
||||
@ -266,26 +266,26 @@ drop table t1;
|
||||
create table t1 (id int primary key) engine = innodb
|
||||
key_block_size = 9 row_format = redundant;
|
||||
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
|
||||
Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
|
||||
Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
|
||||
Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
|
||||
Error 1005 Can't create table 'test.t1' (errno: 1478)
|
||||
create table t2 (id int primary key) engine = innodb
|
||||
key_block_size = 9 row_format = compact;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
|
||||
Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
|
||||
Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
|
||||
Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 1478)
|
||||
create table t2 (id int primary key) engine = innodb
|
||||
key_block_size = 9 row_format = dynamic;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
|
||||
Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
|
||||
Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
|
||||
Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 1478)
|
||||
SELECT table_schema, table_name, row_format
|
||||
FROM information_schema.tables WHERE engine='innodb';
|
||||
@ -293,45 +293,45 @@ table_schema table_name row_format
|
||||
set global innodb_file_per_table = off;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 1;
|
||||
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Error 1005 Can't create table 'test.t1' (errno: 1478)
|
||||
create table t2 (id int primary key) engine = innodb key_block_size = 2;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 1478)
|
||||
create table t3 (id int primary key) engine = innodb key_block_size = 4;
|
||||
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Error 1005 Can't create table 'test.t3' (errno: 1478)
|
||||
create table t4 (id int primary key) engine = innodb key_block_size = 8;
|
||||
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Error 1005 Can't create table 'test.t4' (errno: 1478)
|
||||
create table t5 (id int primary key) engine = innodb key_block_size = 16;
|
||||
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Error 1005 Can't create table 'test.t5' (errno: 1478)
|
||||
create table t6 (id int primary key) engine = innodb row_format = compressed;
|
||||
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
|
||||
Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
|
||||
Error 1005 Can't create table 'test.t6' (errno: 1478)
|
||||
create table t7 (id int primary key) engine = innodb row_format = dynamic;
|
||||
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
|
||||
Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
|
||||
Error 1005 Can't create table 'test.t7' (errno: 1478)
|
||||
create table t8 (id int primary key) engine = innodb row_format = compact;
|
||||
create table t9 (id int primary key) engine = innodb row_format = redundant;
|
||||
@ -345,45 +345,45 @@ set global innodb_file_per_table = on;
|
||||
set global innodb_file_format = `0`;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 1;
|
||||
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Error 1005 Can't create table 'test.t1' (errno: 1478)
|
||||
create table t2 (id int primary key) engine = innodb key_block_size = 2;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 1478)
|
||||
create table t3 (id int primary key) engine = innodb key_block_size = 4;
|
||||
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Error 1005 Can't create table 'test.t3' (errno: 1478)
|
||||
create table t4 (id int primary key) engine = innodb key_block_size = 8;
|
||||
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Error 1005 Can't create table 'test.t4' (errno: 1478)
|
||||
create table t5 (id int primary key) engine = innodb key_block_size = 16;
|
||||
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
|
||||
Error 1005 Can't create table 'test.t5' (errno: 1478)
|
||||
create table t6 (id int primary key) engine = innodb row_format = compressed;
|
||||
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
|
||||
Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
|
||||
Error 1005 Can't create table 'test.t6' (errno: 1478)
|
||||
create table t7 (id int primary key) engine = innodb row_format = dynamic;
|
||||
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
|
||||
show errors;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
|
||||
Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
|
||||
Error 1005 Can't create table 'test.t7' (errno: 1478)
|
||||
create table t8 (id int primary key) engine = innodb row_format = compact;
|
||||
create table t9 (id int primary key) engine = innodb row_format = redundant;
|
||||
|
@ -3090,7 +3090,7 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
commit;
|
||||
drop table t1, t2, t3, t5, t6, t8, t9;
|
||||
CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.t1' (errno: -1)
|
||||
ERROR 42000: Incorrect column name 'DB_ROW_ID'
|
||||
CREATE TABLE t1 (
|
||||
a BIGINT(20) NOT NULL,
|
||||
PRIMARY KEY (a)
|
||||
|
@ -1,4 +1,2 @@
|
||||
set @old_innodb_file_format=@@innodb_file_format;
|
||||
set @old_innodb_file_per_table=@@innodb_file_per_table;
|
||||
SET GLOBAL innodb_file_format='Barracuda';
|
||||
SET GLOBAL innodb_file_per_table=ON;
|
||||
|
@ -1,14 +1,6 @@
|
||||
create table bug44369 (DB_ROW_ID int) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
|
||||
ERROR 42000: Incorrect column name 'DB_ROW_ID'
|
||||
create table bug44369 (db_row_id int) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 1005 Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
|
||||
Error 1005 Can't create table 'test.bug44369' (errno: -1)
|
||||
ERROR 42000: Incorrect column name 'db_row_id'
|
||||
create table bug44369 (db_TRX_Id int) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 1005 Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
|
||||
Error 1005 Can't create table 'test.bug44369' (errno: -1)
|
||||
ERROR 42000: Incorrect column name 'db_TRX_Id'
|
||||
|
7
mysql-test/r/innodb_bug44571.result
Normal file
7
mysql-test/r/innodb_bug44571.result
Normal file
@ -0,0 +1,7 @@
|
||||
CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
|
||||
ALTER TABLE bug44571 CHANGE foo bar INT;
|
||||
ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
|
||||
ERROR 42000: Key column 'foo' doesn't exist in table
|
||||
ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
|
||||
CREATE INDEX bug44571c ON bug44571 (bar);
|
||||
DROP TABLE bug44571;
|
9
mysql-test/r/innodb_bug46676.result
Normal file
9
mysql-test/r/innodb_bug46676.result
Normal file
@ -0,0 +1,9 @@
|
||||
SET foreign_key_checks=0;
|
||||
CREATE TABLE t1 (id int, foreign key (id) references t2(id)) ENGINE=INNODB;
|
||||
CREATE TABLE t2 (id int, foreign key (id) references t1(id)) ENGINE=INNODB;
|
||||
SET foreign_key_checks=1;
|
||||
SELECT COUNT(*) FROM information_schema.key_column_usage WHERE REFERENCED_TABLE_NAME in ('t1', 't2');
|
||||
COUNT(*)
|
||||
2
|
||||
SET foreign_key_checks=0;
|
||||
DROP TABLE t1, t2;
|
24
mysql-test/r/innodb_bug47167.result
Normal file
24
mysql-test/r/innodb_bug47167.result
Normal file
@ -0,0 +1,24 @@
|
||||
set @old_innodb_file_format_check=@@innodb_file_format_check;
|
||||
select @old_innodb_file_format_check;
|
||||
@old_innodb_file_format_check
|
||||
Antelope
|
||||
set global innodb_file_format_check = Barracuda;
|
||||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
set global innodb_file_format_check = DEFAULT;
|
||||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
set global innodb_file_format_check = @old_innodb_file_format_check;
|
||||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Antelope
|
||||
set global innodb_file_format_check = cheetah;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_format_check = Bear;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_format_check = on;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_format_check = off;
|
||||
ERROR HY000: Incorrect arguments to SET
|
@ -1,4 +1,3 @@
|
||||
set @old_innodb_file_format=@@innodb_file_format;
|
||||
call mtr.add_suppression("InnoDB: invalid innodb_file_format_check value");
|
||||
select @@innodb_file_format;
|
||||
@@innodb_file_format
|
||||
@ -32,8 +31,6 @@ select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
set global innodb_file_format_check=default;
|
||||
Warnings:
|
||||
Warning 1210 Ignoring SET innodb_file_format=on
|
||||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
@ -44,5 +41,4 @@ ERROR HY000: Incorrect arguments to SET
|
||||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
set global innodb_file_format=@old_innodb_file_format;
|
||||
set global innodb_file_format_check=Antelope;
|
||||
set global innodb_file_format_check=antelope;
|
||||
|
@ -1,6 +1,5 @@
|
||||
SET @old_innodb_file_format=@@innodb_file_format;
|
||||
SET @old_innodb_file_per_table=@@innodb_file_per_table;
|
||||
SET @old_innodb_file_format_check=@@innodb_file_format_check;
|
||||
SET GLOBAL innodb_file_format='Barracuda';
|
||||
SET GLOBAL innodb_file_per_table=ON;
|
||||
DROP TABLE IF EXISTS `test1`;
|
||||
@ -29,4 +28,4 @@ ALTER TABLE test1 ENGINE=MyISAM;
|
||||
DROP TABLE test1;
|
||||
SET GLOBAL innodb_file_format=@old_innodb_file_format;
|
||||
SET GLOBAL innodb_file_per_table=@old_innodb_file_per_table;
|
||||
SET GLOBAL innodb_file_format_check=@old_innodb_file_format_check;
|
||||
set global innodb_file_format_check=Antelope;
|
||||
|
@ -11,7 +11,7 @@
|
||||
-- disable_result_log
|
||||
-- enable_warnings
|
||||
|
||||
SET @old_innodb_stats_sample_pages=@@innodb_stats_sample_pages;
|
||||
let $sample_pages=`select @@innodb_stats_sample_pages`;
|
||||
SET GLOBAL innodb_stats_sample_pages=0;
|
||||
|
||||
# check that the value has been adjusted to 1
|
||||
@ -62,4 +62,4 @@ SET GLOBAL innodb_stats_sample_pages=16;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
DROP TABLE innodb_analyze;
|
||||
SET GLOBAL innodb_stats_sample_pages=@old_innodb_stats_sample_pages;
|
||||
EVAL SET GLOBAL innodb_stats_sample_pages=$sample_pages;
|
||||
|
1
mysql-test/t/innodb-consistent-master.opt
Normal file
1
mysql-test/t/innodb-consistent-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--loose-innodb_lock_wait_timeout=2
|
58
mysql-test/t/innodb-consistent.test
Normal file
58
mysql-test/t/innodb-consistent.test
Normal file
@ -0,0 +1,58 @@
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
# REPLACE INTO ... SELECT and INSERT INTO ... SELECT should do
|
||||
# a consistent read of the source table.
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
set session transaction isolation level read committed;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
create table t2 like t1;
|
||||
insert into t2 values (1),(2),(3),(4),(5),(6),(7);
|
||||
set autocommit=0;
|
||||
|
||||
# REPLACE INTO ... SELECT case
|
||||
begin;
|
||||
# this should not result in any locks on t2.
|
||||
replace into t1 select * from t2;
|
||||
|
||||
connection b;
|
||||
set session transaction isolation level read committed;
|
||||
set autocommit=0;
|
||||
# should not cuase a lock wait.
|
||||
delete from t2 where a=5;
|
||||
commit;
|
||||
delete from t2;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
|
||||
# INSERT INTO ... SELECT case
|
||||
begin;
|
||||
# this should not result in any locks on t2.
|
||||
insert into t1 select * from t2;
|
||||
|
||||
connection b;
|
||||
set session transaction isolation level read committed;
|
||||
set autocommit=0;
|
||||
# should not cuase a lock wait.
|
||||
delete from t2 where a=5;
|
||||
commit;
|
||||
delete from t2;
|
||||
commit;
|
||||
connection a;
|
||||
commit;
|
||||
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
||||
connection default;
|
||||
disconnect a;
|
||||
disconnect b;
|
@ -1,6 +1,6 @@
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
SET @save_innodb_file_format_check=@@global.innodb_file_format_check;
|
||||
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
|
||||
|
||||
create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb;
|
||||
insert into t1 values (5,5,'oo','oo'),(4,4,'tr','tr'),(3,4,'ad','ad'),(2,3,'ak','ak');
|
||||
@ -404,6 +404,7 @@ create index t1u on t1 (u(1));
|
||||
drop table t1;
|
||||
eval set global innodb_file_per_table=$per_table;
|
||||
eval set global innodb_file_format=$format;
|
||||
eval set global innodb_file_format_check=$format;
|
||||
|
||||
#
|
||||
# Test to check whether CREATE INDEX handles implicit foreign key
|
||||
@ -541,4 +542,9 @@ disconnect b;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
SET GLOBAL innodb_file_format_check=@save_innodb_file_format_check;
|
||||
#
|
||||
# restore environment to the state it was before this test execution
|
||||
#
|
||||
|
||||
-- disable_query_log
|
||||
eval SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig;
|
||||
|
@ -1 +1 @@
|
||||
--binlog_cache_size=32768 --innodb_lock_wait_timeout=1
|
||||
--binlog_cache_size=32768 --loose_innodb_lock_wait_timeout=1
|
||||
|
@ -1 +1 @@
|
||||
--innodb_lock_wait_timeout=2
|
||||
--loose-innodb_lock_wait_timeout=2
|
||||
|
@ -1,2 +1 @@
|
||||
--innodb-use-sys-malloc=true
|
||||
--innodb-use-sys-malloc=true
|
||||
--loose-innodb-use-sys-malloc=true
|
||||
|
@ -178,11 +178,11 @@ set innodb_strict_mode = on;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 0;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t2 (id int primary key) engine = innodb key_block_size = 9;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
|
||||
create table t3 (id int primary key) engine = innodb key_block_size = 1;
|
||||
@ -208,22 +208,22 @@ key_block_size = 8 row_format = compressed;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t2 (id int primary key) engine = innodb
|
||||
key_block_size = 8 row_format = redundant;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t3 (id int primary key) engine = innodb
|
||||
key_block_size = 8 row_format = compact;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t4 (id int primary key) engine = innodb
|
||||
key_block_size = 8 row_format = dynamic;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t5 (id int primary key) engine = innodb
|
||||
key_block_size = 8 row_format = default;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
SELECT table_schema, table_name, row_format
|
||||
FROM information_schema.tables WHERE engine='innodb';
|
||||
@ -233,17 +233,17 @@ drop table t1;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t1 (id int primary key) engine = innodb
|
||||
key_block_size = 9 row_format = redundant;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t2 (id int primary key) engine = innodb
|
||||
key_block_size = 9 row_format = compact;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t2 (id int primary key) engine = innodb
|
||||
key_block_size = 9 row_format = dynamic;
|
||||
show errors;
|
||||
show warnings;
|
||||
|
||||
SELECT table_schema, table_name, row_format
|
||||
FROM information_schema.tables WHERE engine='innodb';
|
||||
@ -253,25 +253,25 @@ set global innodb_file_per_table = off;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 1;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t2 (id int primary key) engine = innodb key_block_size = 2;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t3 (id int primary key) engine = innodb key_block_size = 4;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t4 (id int primary key) engine = innodb key_block_size = 8;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t5 (id int primary key) engine = innodb key_block_size = 16;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t6 (id int primary key) engine = innodb row_format = compressed;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t7 (id int primary key) engine = innodb row_format = dynamic;
|
||||
show errors;
|
||||
show warnings;
|
||||
create table t8 (id int primary key) engine = innodb row_format = compact;
|
||||
create table t9 (id int primary key) engine = innodb row_format = redundant;
|
||||
|
||||
@ -285,25 +285,25 @@ set global innodb_file_format = `0`;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 1;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t2 (id int primary key) engine = innodb key_block_size = 2;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t3 (id int primary key) engine = innodb key_block_size = 4;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t4 (id int primary key) engine = innodb key_block_size = 8;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t5 (id int primary key) engine = innodb key_block_size = 16;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t6 (id int primary key) engine = innodb row_format = compressed;
|
||||
show errors;
|
||||
show warnings;
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table t7 (id int primary key) engine = innodb row_format = dynamic;
|
||||
show errors;
|
||||
show warnings;
|
||||
create table t8 (id int primary key) engine = innodb row_format = compact;
|
||||
create table t9 (id int primary key) engine = innodb row_format = redundant;
|
||||
|
||||
|
@ -2270,7 +2270,7 @@ disconnect j;
|
||||
drop table t1, t2, t3, t5, t6, t8, t9;
|
||||
|
||||
# bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID"
|
||||
--error 1005
|
||||
--error ER_WRONG_COLUMN_NAME
|
||||
CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
|
||||
|
||||
#
|
||||
|
@ -9,7 +9,7 @@
|
||||
-- disable_result_log
|
||||
|
||||
# set packet size and reconnect
|
||||
SET @save_max_allowed_packet=@@global.max_allowed_packet;
|
||||
let $max_packet=`select @@global.max_allowed_packet`;
|
||||
SET @@global.max_allowed_packet=16777216;
|
||||
--connect (newconn, localhost, root,,)
|
||||
|
||||
@ -33,4 +33,4 @@ SELECT f4, f8 FROM bug34300;
|
||||
DROP TABLE bug34300;
|
||||
disconnect newconn;
|
||||
connection default;
|
||||
SET @@global.max_allowed_packet=@save_max_allowed_packet;
|
||||
EVAL SET @@global.max_allowed_packet=$max_packet;
|
||||
|
@ -4,9 +4,9 @@
|
||||
#
|
||||
|
||||
-- source include/have_innodb.inc
|
||||
set @old_innodb_file_format=@@innodb_file_format;
|
||||
set @old_innodb_file_per_table=@@innodb_file_per_table;
|
||||
|
||||
let $file_format=`select @@innodb_file_format`;
|
||||
let $file_per_table=`select @@innodb_file_per_table`;
|
||||
SET GLOBAL innodb_file_format='Barracuda';
|
||||
SET GLOBAL innodb_file_per_table=ON;
|
||||
|
||||
@ -1155,5 +1155,5 @@ DROP TABLE IF EXISTS table4;
|
||||
DROP TABLE IF EXISTS table5;
|
||||
DROP TABLE IF EXISTS table6;
|
||||
|
||||
set global innodb_file_format=@old_innodb_file_format;
|
||||
set global innodb_file_per_table=@old_innodb_file_per_table;
|
||||
EVAL SET GLOBAL innodb_file_format=$file_format;
|
||||
EVAL SET GLOBAL innodb_file_per_table=$file_per_table;
|
||||
|
@ -13,9 +13,10 @@ SET storage_engine=InnoDB;
|
||||
|
||||
-- disable_query_log
|
||||
-- disable_result_log
|
||||
set @old_innodb_file_per_table=@@innodb_file_per_table;
|
||||
set @old_innodb_file_format=@@innodb_file_format;
|
||||
|
||||
let $file_format=`select @@innodb_file_format`;
|
||||
let $file_format_check=`select @@innodb_file_format_check`;
|
||||
let $file_per_table=`select @@innodb_file_per_table`;
|
||||
SET GLOBAL innodb_file_format='Barracuda';
|
||||
SET GLOBAL innodb_file_per_table=on;
|
||||
|
||||
@ -27,6 +28,6 @@ INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.90
|
||||
CHECK TABLE table0 EXTENDED;
|
||||
|
||||
DROP TABLE table0;
|
||||
set global innodb_file_per_table=@old_innodb_file_per_table;
|
||||
set global innodb_file_format=@old_innodb_file_format;
|
||||
set global innodb_file_format_check=Antelope;
|
||||
EVAL SET GLOBAL innodb_file_format=$file_format;
|
||||
EVAL SET GLOBAL innodb_file_format_check=$file_format_check;
|
||||
EVAL SET GLOBAL innodb_file_per_table=$file_per_table;
|
||||
|
@ -1 +1 @@
|
||||
--innodb_commit_concurrency=1
|
||||
--loose_innodb_commit_concurrency=1
|
||||
|
@ -6,16 +6,12 @@
|
||||
--source include/have_innodb.inc
|
||||
|
||||
# This create table operation should fail.
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
--error ER_WRONG_COLUMN_NAME
|
||||
create table bug44369 (DB_ROW_ID int) engine=innodb;
|
||||
|
||||
# This create should fail as well
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
--error ER_WRONG_COLUMN_NAME
|
||||
create table bug44369 (db_row_id int) engine=innodb;
|
||||
|
||||
show warnings;
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
--error ER_WRONG_COLUMN_NAME
|
||||
create table bug44369 (db_TRX_Id int) engine=innodb;
|
||||
|
||||
show warnings;
|
||||
|
13
mysql-test/t/innodb_bug44571.test
Normal file
13
mysql-test/t/innodb_bug44571.test
Normal file
@ -0,0 +1,13 @@
|
||||
#
|
||||
# Bug#44571 InnoDB Plugin crashes on ADD INDEX
|
||||
# http://bugs.mysql.com/44571
|
||||
#
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
|
||||
ALTER TABLE bug44571 CHANGE foo bar INT;
|
||||
-- error ER_KEY_COLUMN_DOES_NOT_EXITS
|
||||
ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
|
||||
ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
|
||||
CREATE INDEX bug44571c ON bug44571 (bar);
|
||||
DROP TABLE bug44571;
|
16
mysql-test/t/innodb_bug46676.test
Normal file
16
mysql-test/t/innodb_bug46676.test
Normal file
@ -0,0 +1,16 @@
|
||||
# This is the test for bug 46676: mysqld got exception 0xc0000005
|
||||
# It is reproducible with InnoDB plugin 1.0.4 + MySQL 5.1.37.
|
||||
# But no longer reproducible after MySQL 5.1.38 (with plugin 1.0.5).
|
||||
|
||||
--source include/have_innodb.inc
|
||||
|
||||
SET foreign_key_checks=0;
|
||||
CREATE TABLE t1 (id int, foreign key (id) references t2(id)) ENGINE=INNODB;
|
||||
CREATE TABLE t2 (id int, foreign key (id) references t1(id)) ENGINE=INNODB;
|
||||
SET foreign_key_checks=1;
|
||||
|
||||
# Server crashes
|
||||
SELECT COUNT(*) FROM information_schema.key_column_usage WHERE REFERENCED_TABLE_NAME in ('t1', 't2');
|
||||
|
||||
SET foreign_key_checks=0;
|
||||
DROP TABLE t1, t2;
|
45
mysql-test/t/innodb_bug47167.test
Normal file
45
mysql-test/t/innodb_bug47167.test
Normal file
@ -0,0 +1,45 @@
|
||||
# This is the unit test for bug *47167.
|
||||
# It tests setting the global variable
|
||||
# "innodb_file_format_check" with a
|
||||
# user-Defined Variable.
|
||||
|
||||
--source include/have_innodb.inc
|
||||
|
||||
# Save the value (Antelope) in 'innodb_file_format_check' to
|
||||
# 'old_innodb_file_format_check'
|
||||
set @old_innodb_file_format_check=@@innodb_file_format_check;
|
||||
|
||||
# @old_innodb_file_format_check shall have the value of 'Antelope'
|
||||
select @old_innodb_file_format_check;
|
||||
|
||||
# Reset the value in 'innodb_file_format_check' to 'Barracuda'
|
||||
set global innodb_file_format_check = Barracuda;
|
||||
|
||||
select @@innodb_file_format_check;
|
||||
|
||||
# Set 'innodb_file_format_check' to its default value, which
|
||||
# is the latest file format supported in the current release.
|
||||
set global innodb_file_format_check = DEFAULT;
|
||||
|
||||
select @@innodb_file_format_check;
|
||||
|
||||
# Put the saved value back to 'innodb_file_format_check'
|
||||
set global innodb_file_format_check = @old_innodb_file_format_check;
|
||||
|
||||
# Check whether 'innodb_file_format_check' get its original value.
|
||||
select @@innodb_file_format_check;
|
||||
|
||||
# Following are negative tests, all should fail.
|
||||
--disable_warnings
|
||||
--error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check = cheetah;
|
||||
|
||||
--error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check = Bear;
|
||||
|
||||
--error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check = on;
|
||||
|
||||
--error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check = off;
|
||||
--enable_warnings
|
@ -1,5 +1,4 @@
|
||||
-- source include/have_innodb.inc
|
||||
set @old_innodb_file_format=@@innodb_file_format;
|
||||
|
||||
call mtr.add_suppression("InnoDB: invalid innodb_file_format_check value");
|
||||
|
||||
@ -29,6 +28,4 @@ set global innodb_file_format=on;
|
||||
--error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format=off;
|
||||
select @@innodb_file_format_check;
|
||||
|
||||
set global innodb_file_format=@old_innodb_file_format;
|
||||
set global innodb_file_format_check=Antelope;
|
||||
set global innodb_file_format_check=antelope;
|
||||
|
@ -109,19 +109,18 @@ SELECT * FROM ```t'\"_str` WHERE c1 = '3' FOR UPDATE;
|
||||
-- send
|
||||
SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE;
|
||||
|
||||
-- connection con_verify_innodb_locks
|
||||
|
||||
# Loop, giving time for the above 2 queries to execute before continuing.
|
||||
# Without this, it sometimes happens that the SELECT FROM innodb_locks
|
||||
# executes before some of them, resulting in less than expected number
|
||||
# of rows being selected from innodb_locks.
|
||||
SET @counter := 0;
|
||||
while (`SELECT (@counter := @counter + 1) <= 50 AND COUNT(*) != 14 FROM INFORMATION_SCHEMA.INNODB_LOCKS`)
|
||||
{
|
||||
sleep 0.1;
|
||||
}
|
||||
|
||||
-- enable_result_log
|
||||
-- connection con_verify_innodb_locks
|
||||
# Wait for the above queries to execute before continuing.
|
||||
# Without this, it sometimes happens that the SELECT from innodb_locks
|
||||
# executes before some of them, resulting in less than expected number
|
||||
# of rows being selected from innodb_locks. If there is a bug and there
|
||||
# are no 14 rows in innodb_locks then this test will fail with timeout.
|
||||
let $count = 14;
|
||||
let $table = INFORMATION_SCHEMA.INNODB_LOCKS;
|
||||
-- source include/wait_until_rows_count.inc
|
||||
# the above enables the query log, re-disable it
|
||||
-- disable_query_log
|
||||
SELECT lock_mode, lock_type, lock_table, lock_index, lock_rec, lock_data
|
||||
FROM INFORMATION_SCHEMA.INNODB_LOCKS ORDER BY lock_data;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
SET @old_innodb_file_format=@@innodb_file_format;
|
||||
SET @old_innodb_file_per_table=@@innodb_file_per_table;
|
||||
SET @old_innodb_file_format_check=@@innodb_file_format_check;
|
||||
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
|
||||
SET GLOBAL innodb_file_format='Barracuda';
|
||||
SET GLOBAL innodb_file_per_table=ON;
|
||||
|
||||
@ -45,4 +45,4 @@ ALTER TABLE test1 ENGINE=MyISAM;
|
||||
DROP TABLE test1;
|
||||
SET GLOBAL innodb_file_format=@old_innodb_file_format;
|
||||
SET GLOBAL innodb_file_per_table=@old_innodb_file_per_table;
|
||||
SET GLOBAL innodb_file_format_check=@old_innodb_file_format_check;
|
||||
eval set global innodb_file_format_check=$innodb_file_format_check_orig;
|
||||
|
@ -13,28 +13,33 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# This is the CMakeLists for InnoDB Plugin
|
||||
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
|
||||
|
||||
# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
|
||||
# CMakeLists.txt still needs to work with previous versions of MySQL.
|
||||
IF (MYSQL_VERSION_ID GREATER "50137")
|
||||
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
|
||||
ENDIF (MYSQL_VERSION_ID GREATER "50137")
|
||||
|
||||
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||
SET(WIN64 TRUE)
|
||||
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||
|
||||
# Check type sizes
|
||||
include(CheckTypeSize)
|
||||
|
||||
# Currently, the checked results are not used.
|
||||
CHECK_TYPE_SIZE(int SIZEOF_INT)
|
||||
CHECK_TYPE_SIZE(long SIZEOF_LONG)
|
||||
CHECK_TYPE_SIZE(void* SIZEOF_VOID_P)
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
|
||||
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
|
||||
ADD_DEFINITIONS(-D_WIN32 -D_LIB -DMYSQL_SERVER)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
|
||||
${CMAKE_SOURCE_DIR}/storage/xtradb/include
|
||||
${CMAKE_SOURCE_DIR}/storage/xtradb/handler
|
||||
# Include directories under innobase
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/xtradb/include
|
||||
${CMAKE_SOURCE_DIR}/storage/xtradb/handler)
|
||||
|
||||
# Include directories under mysql
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/sql
|
||||
${CMAKE_SOURCE_DIR}/regex
|
||||
${CMAKE_SOURCE_DIR}/zlib
|
||||
${CMAKE_SOURCE_DIR}/extra/yassl/include)
|
||||
|
||||
# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
|
||||
@ -77,5 +82,20 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
||||
usr/usr0sess.c
|
||||
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
|
||||
ut/ut0list.c ut/ut0wqueue.c)
|
||||
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
|
||||
|
||||
IF (MYSQL_VERSION_ID GREATER "50137")
|
||||
MYSQL_STORAGE_ENGINE(INNOBASE)
|
||||
# Use ha_innodb for plugin name, if plugin is built
|
||||
GET_TARGET_PROPERTY(LIB_LOCATION ha_innobase LOCATION)
|
||||
IF(LIB_LOCATION)
|
||||
SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb)
|
||||
ENDIF(LIB_LOCATION)
|
||||
ELSE (MYSQL_VERSION_ID GREATER "50137")
|
||||
IF (NOT SOURCE_SUBLIBS)
|
||||
ADD_DEFINITIONS(-D_WIN32 -DMYSQL_SERVER)
|
||||
ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES})
|
||||
# Require mysqld_error.h, which is built as part of the GenError
|
||||
ADD_DEPENDENCIES(innobase GenError)
|
||||
ENDIF (NOT SOURCE_SUBLIBS)
|
||||
ENDIF (MYSQL_VERSION_ID GREATER "50137")
|
||||
|
@ -1,3 +1,319 @@
|
||||
2009-11-20 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Add a workaround to prevent a crash due to Bug#45961 DDL on
|
||||
partitioned innodb tables leaves data dictionary in an inconsistent
|
||||
state
|
||||
|
||||
2009-11-19 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c:
|
||||
Fix Bug#48469 when innodb tablespace is configured too small, crash
|
||||
and corruption!
|
||||
|
||||
2009-11-19 The InnoDB Team
|
||||
|
||||
* data/data0type.c:
|
||||
Fix Bug#48526 Data type for float and double is incorrectly reported
|
||||
in InnoDB table monitor
|
||||
|
||||
2009-11-19 The InnoDB Team
|
||||
|
||||
* CMakeLists.txt:
|
||||
Fix Bug#48317 cannot build innodb as static library
|
||||
|
||||
2009-11-18 The InnoDB Team
|
||||
|
||||
* handler/handler0alter.cc:
|
||||
Fix Bug#48782 On lock wait timeout, CREATE INDEX (creating primary key)
|
||||
attempts DROP TABLE
|
||||
|
||||
2009-11-17 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb.result,
|
||||
mysql-test/innodb.test, mysql-test/innodb_bug44369.result,
|
||||
mysql-test/innodb_bug44369.test, mysql-test/patches/innodb-index.diff,
|
||||
row/row0mysql.c:
|
||||
Report duplicate table names to the client connection, not to the
|
||||
error log.
|
||||
|
||||
2009-11-12 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/db0err.h, row/row0merge.c,
|
||||
row/row0mysql.c:
|
||||
Allow CREATE INDEX to be interrupted.
|
||||
Also, when CHECK TABLE is interrupted, report ER_QUERY_INTERRUPTED.
|
||||
|
||||
2009-11-11 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb_bug47167.result,
|
||||
mysql-test/innodb_bug47167.test, mysql-test/innodb_file_format.result:
|
||||
Fix Bug#47167 "set global innodb_file_format_check" cannot set value
|
||||
by User-Defined Variable
|
||||
|
||||
2009-11-11 The InnoDB Team
|
||||
|
||||
* include/os0file.h, os/os0file.c:
|
||||
Fix Bug#3139 Mysql crashes: 'windows error 995' after several selects
|
||||
on a large DB
|
||||
|
||||
2009-11-04 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#32430 'show innodb status' causes errors
|
||||
Invalid (old?) table or database name in logs
|
||||
|
||||
2009-11-02 The InnoDB Team
|
||||
|
||||
* btr/btr0sea.c, buf/buf0buf.c, dict/dict0dict.c, fil/fil0fil.c,
|
||||
ibuf/ibuf0ibuf.c, include/btr0sea.h, include/dict0dict.h,
|
||||
include/fil0fil.h, include/ibuf0ibuf.h, include/lock0lock.h,
|
||||
include/log0log.h, include/log0recv.h, include/mem0mem.h,
|
||||
include/mem0pool.h, include/os0file.h, include/pars0pars.h,
|
||||
include/srv0srv.h, include/thr0loc.h, include/trx0i_s.h,
|
||||
include/trx0purge.h, include/trx0rseg.h, include/trx0sys.h,
|
||||
include/trx0undo.h, include/usr0sess.h, lock/lock0lock.c,
|
||||
log/log0log.c, log/log0recv.c, mem/mem0dbg.c, mem/mem0pool.c,
|
||||
os/os0file.c, os/os0sync.c, os/os0thread.c, pars/lexyy.c,
|
||||
pars/pars0lex.l, que/que0que.c, srv/srv0srv.c, srv/srv0start.c,
|
||||
sync/sync0arr.c, sync/sync0sync.c, thr/thr0loc.c, trx/trx0i_s.c,
|
||||
trx/trx0purge.c, trx/trx0rseg.c, trx/trx0sys.c, trx/trx0undo.c,
|
||||
usr/usr0sess.c, ut/ut0mem.c:
|
||||
Fix Bug #45992 innodb memory not freed after shutdown
|
||||
Fix Bug #46656 InnoDB plugin: memory leaks (Valgrind)
|
||||
|
||||
2009-10-29 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
|
||||
mysql-test/innodb-autoinc.test:
|
||||
Fix Bug#47125 auto_increment start value is ignored if an index is
|
||||
created and engine=innodb
|
||||
|
||||
2009-10-29 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb_bug47777.result,
|
||||
mysql-test/innodb_bug47777.test:
|
||||
Fix Bug#47777 innodb dies with spatial pk: Failing assertion: buf <=
|
||||
original_buf + buf_len
|
||||
|
||||
2009-10-29 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#38996 Race condition in ANALYZE TABLE
|
||||
|
||||
2009-10-29 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix bug#42383: Can't create table 'test.bug39438'
|
||||
|
||||
2009-10-29 The InnoDB Team
|
||||
|
||||
* os/os0proc.c:
|
||||
Fix Bug#48237 Error handling in os_mem_alloc_large appears to
|
||||
be incorrect
|
||||
|
||||
2009-10-29 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c, buf/buf0lru.c, include/buf0buf.h, include/buf0buf.ic:
|
||||
Fix corruption of the buf_pool->LRU_old list and improve debug
|
||||
assertions.
|
||||
|
||||
2009-10-28 The InnoDB Team
|
||||
|
||||
* srv/srv0start.c:
|
||||
Fix Bug#41490 After enlargement of InnoDB page size, the error message
|
||||
become inaccurate
|
||||
|
||||
2009-10-26 The InnoDB Team
|
||||
|
||||
* row/row0ins.c:
|
||||
When allocating a data tuple, zero out the system fields in order
|
||||
to avoid Valgrind warnings about uninitialized fields in
|
||||
dtuple_validate().
|
||||
|
||||
2009-10-22 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb-zip.result,
|
||||
mysql-test/innodb-zip.test, mysql-test/innodb_bug44369.result,
|
||||
mysql-test/innodb_bug44369.test:
|
||||
Fix Bug#47233 Innodb calls push_warning(MYSQL_ERROR::WARN_LEVEL_ERROR)
|
||||
|
||||
2009-10-19 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb_information_schema.test:
|
||||
Fix Bug#47808 innodb_information_schema.test fails when run under
|
||||
valgrind
|
||||
|
||||
2009-10-15 The InnoDB Team
|
||||
|
||||
* include/page0page.ic:
|
||||
Fix Bug#47058 Failure to compile innodb_plugin on solaris 10u7 + spro
|
||||
cc/CC 5.10
|
||||
|
||||
2009-10-13 The InnoDB Team
|
||||
|
||||
* buf/buf0flu.c:
|
||||
Call fsync() on datafiles after a batch of pages is written to disk
|
||||
even when skip_innodb_doublewrite is set.
|
||||
|
||||
2009-10-05 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c:
|
||||
Do not invalidate buffer pool while an LRU batch is active. Added code
|
||||
to buf_pool_invalidate() to wait for the running batches to finish.
|
||||
|
||||
2009-10-01 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#47763 typo in error message: Failed to open table %s after %lu
|
||||
attemtps.
|
||||
|
||||
2009-10-01 The InnoDB Team
|
||||
|
||||
* fsp/fsp0fsp.c, row/row0merge.c:
|
||||
Clean up after a crash during DROP INDEX. When InnoDB crashes
|
||||
while dropping an index, ensure that the index will be completely
|
||||
dropped during crash recovery. The MySQL .frm file may still
|
||||
contain the dropped index, but there is little that we can do
|
||||
about it.
|
||||
|
||||
2009-09-28 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
When a secondary index exists in the MySQL .frm file but not in
|
||||
the InnoDB data dictionary, return an error instead of letting an
|
||||
assertion fail in index_read.
|
||||
|
||||
2009-09-28 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, buf/buf0buf.c, include/page0page.h,
|
||||
include/page0zip.h, page/page0cur.c, page/page0page.c,
|
||||
page/page0zip.c:
|
||||
Do not write to PAGE_INDEX_ID when restoring an uncompressed page
|
||||
after a compression failure. The field should only be written
|
||||
when creating a B-tree page. This fix addresses a race condition
|
||||
in a debug assertion.
|
||||
|
||||
2009-09-28 The InnoDB Team
|
||||
|
||||
* fil/fil0fil.c:
|
||||
Try to prevent the reuse of tablespace identifiers after InnoDB
|
||||
has crashed during table creation. Also, refuse to start if files
|
||||
with duplicate tablespace identifiers are encountered.
|
||||
|
||||
2009-09-25 The InnoDB Team
|
||||
|
||||
* include/os0file.h, os/os0file.c:
|
||||
Fix Bug#47055 unconditional exit(1) on ERROR_WORKING_SET_QUOTA
|
||||
1453 (0x5AD) for InnoDB backend
|
||||
|
||||
2009-09-19 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb-consistent-master.opt,
|
||||
mysql-test/innodb-consistent.result,
|
||||
mysql-test/innodb-consistent.test:
|
||||
Fix Bug#37232 Innodb might get too many read locks for DML with
|
||||
repeatable-read
|
||||
|
||||
2009-09-19 The InnoDB Team
|
||||
|
||||
* fsp/fsp0fsp.c:
|
||||
Fix Bug#31183 Tablespace full problems not reported in error log,
|
||||
error message unclear
|
||||
|
||||
2009-09-17 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
|
||||
Make the test pass with zlib 1.2.3.3. Apparently, the definition
|
||||
of compressBound() has changed between zlib versions, and the
|
||||
maximum record size of a table with 1K compressed page size has
|
||||
been reduced by one byte. This is an arbitrary test. In practical
|
||||
applications, for good write performance, the compressed page size
|
||||
should be chosen to be bigger than the absolute minimum.
|
||||
|
||||
2009-09-16 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#46256 drop table with unknown collation crashes innodb
|
||||
|
||||
2009-09-16 The InnoDB Team
|
||||
|
||||
* dict/dict0dict.c, handler/ha_innodb.cc,
|
||||
mysql-test/innodb_bug44369.result, mysql-test/innodb_bug44369.test,
|
||||
row/row0mysql.c:
|
||||
Fix Bug#44369 InnoDB: Does not uniformly disallow disallowed column
|
||||
names
|
||||
|
||||
2009-09-16 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/db0err.h,
|
||||
mysql-test/innodb_bug46000.result, mysql-test/innodb_bug46000.test:
|
||||
Fix Bug#46000 using index called GEN_CLUST_INDEX crashes server
|
||||
|
||||
2009-09-02 The InnoDB Team
|
||||
|
||||
* include/lock0lock.h, include/row0mysql.h, lock/lock0lock.c,
|
||||
row/row0mysql.c:
|
||||
Fix a regression introduced by the fix for MySQL bug#26316. We check
|
||||
whether a transaction holds any AUTOINC locks before we acquire
|
||||
the kernel mutex and release those locks.
|
||||
|
||||
2009-08-27 The InnoDB Team
|
||||
|
||||
* dict/dict0dict.c, include/dict0dict.h,
|
||||
mysql-test/innodb_bug44571.result, mysql-test/innodb_bug44571.test:
|
||||
Fix Bug#44571 InnoDB Plugin crashes on ADD INDEX
|
||||
|
||||
2009-08-27 The InnoDB Team
|
||||
|
||||
* row/row0merge.c:
|
||||
Fix a bug in the merge sort that can corrupt indexes in fast index
|
||||
creation. Add some consistency checks. Check that the number of
|
||||
records remains constant in every merge sort pass.
|
||||
|
||||
2009-08-27 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c, buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
|
||||
include/buf0buf.h, include/buf0buf.ic, include/buf0lru.h,
|
||||
include/ut0ut.h, ut/ut0ut.c:
|
||||
Make it possible to tune the buffer pool LRU eviction policy to be
|
||||
more resistant against index scans. Introduce the settable global
|
||||
variables innodb_old_blocks_pct and innodb_old_blocks_time for
|
||||
controlling the buffer pool eviction policy. The parameter
|
||||
innodb_old_blocks_pct (5..95) controls the desired amount of "old"
|
||||
blocks in the LRU list. The default is 37, corresponding to the
|
||||
old fixed ratio of 3/8. Each time a block is accessed, it will be
|
||||
moved to the "new" blocks if its first access was at least
|
||||
innodb_old_blocks_time milliseconds ago (default 0, meaning every
|
||||
block). The idea is that in index scans, blocks will be accessed
|
||||
a few times within innodb_old_blocks_time, and they will remain in
|
||||
the "old" section of the LRU list. Thus, when innodb_old_blocks_time
|
||||
is nonzero, blocks retrieved for one-time index scans will be more
|
||||
likely candidates for eviction than blocks that are accessed in
|
||||
random patterns.
|
||||
|
||||
2009-08-26 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, os/os0file.c:
|
||||
Fix Bug#42885 buf_read_ahead_random, buf_read_ahead_linear counters,
|
||||
thread wakeups
|
||||
|
||||
2009-08-20 The InnoDB Team
|
||||
|
||||
* lock/lock0lock.c:
|
||||
Fix Bug#46650 Innodb assertion autoinc_lock == lock in
|
||||
lock_table_remove_low on INSERT SELECT
|
||||
|
||||
2009-08-13 The InnoDB Team
|
||||
|
||||
* handler/handler0alter.cc:
|
||||
Fix Bug#46657 InnoDB plugin: invalid read in index_merge_innodb test
|
||||
(Valgrind)
|
||||
|
||||
2009-08-11 The InnoDB Team
|
||||
|
||||
InnoDB Plugin 1.0.4 released
|
||||
|
||||
2009-07-20 The InnoDB Team
|
||||
|
||||
* buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
|
||||
|
@ -22,7 +22,7 @@ MYSQLLIBdir= $(pkglibdir)
|
||||
pkgplugindir= $(pkglibdir)/plugin
|
||||
INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/regex \
|
||||
-I$(top_srcdir)/storage/xtradb/include \
|
||||
-I$(srcdir)/include \
|
||||
-I$(top_srcdir)/sql \
|
||||
-I$(srcdir) @ZLIB_INCLUDES@
|
||||
|
||||
@ -31,7 +31,6 @@ DEFS= @DEFS@
|
||||
|
||||
noinst_HEADERS= \
|
||||
handler/ha_innodb.h \
|
||||
handler/handler0vars.h \
|
||||
handler/i_s.h \
|
||||
include/btr0btr.h \
|
||||
include/btr0btr.ic \
|
||||
|
@ -790,14 +790,21 @@ btr_create(
|
||||
} else {
|
||||
/* It is a non-ibuf tree: create a file segment for leaf
|
||||
pages */
|
||||
fseg_create(space, page_no,
|
||||
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr);
|
||||
if (!fseg_create(space, page_no,
|
||||
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
|
||||
/* Not enough space for new segment, free root
|
||||
segment before return. */
|
||||
btr_free_root(space, zip_size, page_no, mtr);
|
||||
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
/* The fseg create acquires a second latch on the page,
|
||||
therefore we must declare it: */
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
|
||||
}
|
||||
|
||||
/* Create a new index page on the the allocated segment page */
|
||||
/* Create a new index page on the allocated segment page */
|
||||
page_zip = buf_block_get_page_zip(block);
|
||||
|
||||
if (UNIV_LIKELY_NULL(page_zip)) {
|
||||
@ -1011,7 +1018,26 @@ btr_page_reorganize_low(
|
||||
(!page_zip_compress(page_zip, page, index, NULL))) {
|
||||
|
||||
/* Restore the old page and exit. */
|
||||
buf_frame_copy(page, temp_page);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
|
||||
/* Check that the bytes that we skip are identical. */
|
||||
ut_a(!memcmp(page, temp_page, PAGE_HEADER));
|
||||
ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
|
||||
PAGE_HEADER + PAGE_N_RECS + temp_page,
|
||||
PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
|
||||
ut_a(!memcmp(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page,
|
||||
UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + temp_page,
|
||||
FIL_PAGE_DATA_END));
|
||||
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
|
||||
|
||||
memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
|
||||
PAGE_N_RECS - PAGE_N_DIR_SLOTS);
|
||||
memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
|
||||
UNIV_PAGE_SIZE - PAGE_DATA - FIL_PAGE_DATA_END);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
|
||||
ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
|
||||
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
@ -1902,7 +1928,7 @@ func_start:
|
||||
n_uniq, &heap);
|
||||
|
||||
/* If the new record is less than the existing record
|
||||
the the split in the middle will copy the existing
|
||||
the split in the middle will copy the existing
|
||||
record to the new node. */
|
||||
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
|
||||
split_rec = page_get_middle_rec(page);
|
||||
|
@ -175,6 +175,21 @@ btr_search_sys_create(
|
||||
btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Frees the adaptive search system at a database shutdown. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_search_sys_free(void)
|
||||
/*=====================*/
|
||||
{
|
||||
mem_free(btr_search_latch_temp);
|
||||
btr_search_latch_temp = NULL;
|
||||
mem_heap_free(btr_search_sys->hash_index->heap);
|
||||
hash_table_free(btr_search_sys->hash_index);
|
||||
mem_free(btr_search_sys);
|
||||
btr_search_sys = NULL;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Disable the adaptive hash search system and empty the index. */
|
||||
UNIV_INTERN
|
||||
@ -957,7 +972,7 @@ btr_search_guess_on_hash(
|
||||
/* Increment the page get statistics though we did not really
|
||||
fix the page: for user info only */
|
||||
|
||||
buf_pool->n_page_gets++;
|
||||
buf_pool->stat.n_page_gets++;
|
||||
|
||||
return(TRUE);
|
||||
|
||||
|
@ -531,11 +531,10 @@ buf_buddy_relocate(
|
||||
UNIV_MEM_ASSERT_W(src, size);
|
||||
|
||||
mutex = buf_page_get_mutex_enter(bpage);
|
||||
ut_a(mutex);
|
||||
|
||||
mutex_enter(&zip_free_mutex);
|
||||
|
||||
if (buf_page_can_relocate(bpage)) {
|
||||
if (mutex && buf_page_can_relocate(bpage)) {
|
||||
/* Relocate the compressed page. */
|
||||
ut_a(bpage->zip.data == src);
|
||||
memcpy(dst, src, size);
|
||||
@ -563,7 +562,9 @@ success:
|
||||
rw_lock_x_unlock(&page_hash_latch);
|
||||
}
|
||||
|
||||
if (mutex) {
|
||||
mutex_exit(mutex);
|
||||
}
|
||||
} else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
|
||||
/* This must be a buf_page_t object. */
|
||||
UNIV_MEM_ASSERT_RW(src, size);
|
||||
|
@ -51,6 +51,40 @@ Created 11/5/1995 Heikki Tuuri
|
||||
#include "dict0dict.h"
|
||||
#include "log0recv.h"
|
||||
#include "page0zip.h"
|
||||
#include "trx0trx.h"
|
||||
|
||||
/* prototypes for new functions added to ha_innodb.cc */
|
||||
trx_t* innobase_get_trx();
|
||||
|
||||
inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
|
||||
{
|
||||
ulint block_hash;
|
||||
ulint block_hash_byte;
|
||||
byte block_hash_offset;
|
||||
|
||||
ut_ad(block);
|
||||
|
||||
if (!innobase_get_slow_log() || !trx || !trx->take_stats)
|
||||
return;
|
||||
|
||||
if (!trx->distinct_page_access_hash) {
|
||||
trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
|
||||
memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
|
||||
}
|
||||
|
||||
block_hash = ut_hash_ulint((block->page.space << 20) + block->page.space +
|
||||
block->page.offset, DPAH_SIZE << 3);
|
||||
block_hash_byte = block_hash >> 3;
|
||||
block_hash_offset = (byte) block_hash & 0x07;
|
||||
if (block_hash_byte < 0 || block_hash_byte >= DPAH_SIZE)
|
||||
fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", block_hash_byte, block_hash_offset);
|
||||
if (block_hash_offset < 0 || block_hash_offset > 7)
|
||||
fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", block_hash_byte, block_hash_offset);
|
||||
if ((trx->distinct_page_access_hash[block_hash_byte] & ((byte) 0x01 << block_hash_offset)) == 0)
|
||||
trx->distinct_page_access++;
|
||||
trx->distinct_page_access_hash[block_hash_byte] |= (byte) 0x01 << block_hash_offset;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
IMPLEMENTATION OF THE BUFFER POOL
|
||||
@ -845,16 +879,35 @@ buf_chunk_not_freed(
|
||||
block = chunk->blocks;
|
||||
|
||||
for (i = chunk->size; i--; block++) {
|
||||
ibool ready;
|
||||
|
||||
switch (buf_block_get_state(block)) {
|
||||
case BUF_BLOCK_ZIP_FREE:
|
||||
case BUF_BLOCK_ZIP_PAGE:
|
||||
case BUF_BLOCK_ZIP_DIRTY:
|
||||
/* The uncompressed buffer pool should never
|
||||
contain compressed block descriptors. */
|
||||
ut_error;
|
||||
break;
|
||||
case BUF_BLOCK_NOT_USED:
|
||||
case BUF_BLOCK_READY_FOR_USE:
|
||||
case BUF_BLOCK_MEMORY:
|
||||
case BUF_BLOCK_REMOVE_HASH:
|
||||
/* Skip blocks that are not being used for
|
||||
file pages. */
|
||||
break;
|
||||
case BUF_BLOCK_FILE_PAGE:
|
||||
mutex_enter(&block->mutex);
|
||||
|
||||
if (buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
|
||||
&& !buf_flush_ready_for_replace(&block->page)) {
|
||||
|
||||
ready = buf_flush_ready_for_replace(&block->page);
|
||||
mutex_exit(&block->mutex);
|
||||
|
||||
if (!ready) {
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
||||
mutex_exit(&block->mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
@ -985,8 +1038,6 @@ buf_pool_init(void)
|
||||
buf_pool->no_flush[i] = os_event_create(NULL);
|
||||
}
|
||||
|
||||
buf_pool->ulint_clock = 1;
|
||||
|
||||
/* 3. Initialize LRU fields
|
||||
--------------------------- */
|
||||
/* All fields are initialized by mem_zalloc(). */
|
||||
@ -1024,7 +1075,11 @@ buf_pool_free(void)
|
||||
os_mem_free_large(chunk->mem, chunk->mem_size);
|
||||
}
|
||||
|
||||
buf_pool->n_chunks = 0;
|
||||
mem_free(buf_pool->chunks);
|
||||
hash_table_free(buf_pool->page_hash);
|
||||
hash_table_free(buf_pool->zip_hash);
|
||||
mem_free(buf_pool);
|
||||
buf_pool = NULL;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
@ -1171,10 +1226,15 @@ buf_relocate(
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||
whose "old" flag is set. */
|
||||
ut_a(buf_pool->LRU_old->old);
|
||||
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|
||||
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
|
||||
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|
||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||
} else {
|
||||
/* Check that the "old" flag is consistent in
|
||||
the block and its neighbours. */
|
||||
buf_page_set_old(dpage, buf_page_is_old(dpage));
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
}
|
||||
|
||||
@ -1509,36 +1569,9 @@ buf_pool_resize(void)
|
||||
buf_pool_page_hash_rebuild();
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Moves the block to the start of the LRU list if there is a danger
|
||||
that the block would drift out of the buffer pool. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
buf_block_make_young(
|
||||
/*=================*/
|
||||
buf_page_t* bpage) /*!< in: block to make younger */
|
||||
{
|
||||
ut_ad(!buf_pool_mutex_own());
|
||||
|
||||
/* Note that we read freed_page_clock's without holding any mutex:
|
||||
this is allowed since the result is used only in heuristics */
|
||||
|
||||
if (buf_page_peek_if_too_old(bpage)) {
|
||||
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
/* There has been freeing activity in the LRU list:
|
||||
best to move to the head of the LRU list */
|
||||
|
||||
buf_LRU_make_block_young(bpage);
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Moves a page to the start of the buffer pool LRU list. This high-level
|
||||
function can be used to prevent an important page from from slipping out of
|
||||
function can be used to prevent an important page from slipping out of
|
||||
the buffer pool. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
@ -1557,6 +1590,42 @@ buf_page_make_young(
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Sets the time of the first access of a page and moves a page to the
|
||||
start of the buffer pool LRU list if it is too old. This high-level
|
||||
function can be used to prevent an important page from slipping
|
||||
out of the buffer pool. */
|
||||
static
|
||||
void
|
||||
buf_page_set_accessed_make_young(
|
||||
/*=============================*/
|
||||
buf_page_t* bpage, /*!< in/out: buffer block of a
|
||||
file page */
|
||||
unsigned access_time) /*!< in: bpage->access_time
|
||||
read under mutex protection,
|
||||
or 0 if unknown */
|
||||
{
|
||||
ut_ad(!buf_pool_mutex_own());
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
if (buf_page_peek_if_too_old(bpage)) {
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
buf_LRU_make_block_young(bpage);
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
} else if (!access_time) {
|
||||
ulint time_ms = ut_time_ms();
|
||||
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
|
||||
//buf_pool_mutex_enter();
|
||||
if (block_mutex) {
|
||||
buf_page_set_accessed(bpage, time_ms);
|
||||
mutex_exit(block_mutex);
|
||||
}
|
||||
//buf_pool_mutex_exit();
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Resets the check_index_page_at_flush field of a page if found in the buffer
|
||||
pool. */
|
||||
@ -1696,11 +1765,20 @@ buf_page_get_zip(
|
||||
buf_page_t* bpage;
|
||||
mutex_t* block_mutex;
|
||||
ibool must_read;
|
||||
unsigned access_time;
|
||||
trx_t* trx = NULL;
|
||||
ulint sec;
|
||||
ulint ms;
|
||||
ib_uint64_t start_time;
|
||||
ib_uint64_t finish_time;
|
||||
|
||||
#ifndef UNIV_LOG_DEBUG
|
||||
ut_ad(!ibuf_inside());
|
||||
#endif
|
||||
buf_pool->n_page_gets++;
|
||||
if (innobase_get_slow_log()) {
|
||||
trx = innobase_get_trx();
|
||||
}
|
||||
buf_pool->stat.n_page_gets++;
|
||||
|
||||
for (;;) {
|
||||
//buf_pool_mutex_enter();
|
||||
@ -1716,7 +1794,7 @@ lookup:
|
||||
//buf_pool_mutex_exit();
|
||||
rw_lock_s_unlock(&page_hash_latch);
|
||||
|
||||
buf_read_page(space, zip_size, offset);
|
||||
buf_read_page(space, zip_size, offset, trx);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(++buf_dbg_counter % 37 || buf_validate());
|
||||
@ -1770,14 +1848,13 @@ err_exit:
|
||||
|
||||
got_block:
|
||||
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
|
||||
access_time = buf_page_is_accessed(bpage);
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
|
||||
buf_page_set_accessed(bpage, TRUE);
|
||||
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
buf_block_make_young(bpage);
|
||||
buf_page_set_accessed_make_young(bpage, access_time);
|
||||
|
||||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
||||
ut_a(!bpage->file_page_was_freed);
|
||||
@ -1793,6 +1870,13 @@ got_block:
|
||||
/* Let us wait until the read operation
|
||||
completes */
|
||||
|
||||
if (innobase_get_slow_log() && trx && trx->take_stats)
|
||||
{
|
||||
ut_usectime(&sec, &ms);
|
||||
start_time = (ib_uint64_t)sec * 1000000 + ms;
|
||||
} else {
|
||||
start_time = 0;
|
||||
}
|
||||
for (;;) {
|
||||
enum buf_io_fix io_fix;
|
||||
|
||||
@ -1807,6 +1891,12 @@ got_block:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
|
||||
{
|
||||
ut_usectime(&sec, &ms);
|
||||
finish_time = (ib_uint64_t)sec * 1000000 + ms;
|
||||
trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||
@ -1870,7 +1960,7 @@ buf_zip_decompress(
|
||||
switch (fil_page_get_type(frame)) {
|
||||
case FIL_PAGE_INDEX:
|
||||
if (page_zip_decompress(&block->page.zip,
|
||||
block->frame)) {
|
||||
block->frame, TRUE)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
@ -2058,10 +2148,15 @@ buf_page_get_gen(
|
||||
mtr_t* mtr) /*!< in: mini-transaction */
|
||||
{
|
||||
buf_block_t* block;
|
||||
ibool accessed;
|
||||
unsigned access_time;
|
||||
ulint fix_type;
|
||||
ibool must_read;
|
||||
mutex_t* block_mutex;
|
||||
trx_t* trx = NULL;
|
||||
ulint sec;
|
||||
ulint ms;
|
||||
ib_uint64_t start_time;
|
||||
ib_uint64_t finish_time;
|
||||
|
||||
ut_ad(mtr);
|
||||
ut_ad((rw_latch == RW_S_LATCH)
|
||||
@ -2075,14 +2170,16 @@ buf_page_get_gen(
|
||||
#ifndef UNIV_LOG_DEBUG
|
||||
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
|
||||
#endif
|
||||
buf_pool->n_page_gets++;
|
||||
if (innobase_get_slow_log()) {
|
||||
trx = innobase_get_trx();
|
||||
}
|
||||
buf_pool->stat.n_page_gets++;
|
||||
loop:
|
||||
block = guess;
|
||||
//buf_pool_mutex_enter();
|
||||
|
||||
if (block) {
|
||||
block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
|
||||
ut_a(block_mutex);
|
||||
|
||||
/* If the guess is a compressed page descriptor that
|
||||
has been allocated by buf_buddy_alloc(), it may have
|
||||
@ -2092,7 +2189,9 @@ loop:
|
||||
the guess may be pointing to a buffer pool chunk that
|
||||
has been released when resizing the buffer pool. */
|
||||
|
||||
if (!buf_block_is_uncompressed(block)
|
||||
if (!block_mutex) {
|
||||
block = guess = NULL;
|
||||
} else if (!buf_block_is_uncompressed(block)
|
||||
|| offset != block->page.offset
|
||||
|| space != block->page.space
|
||||
|| buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
|
||||
@ -2127,7 +2226,7 @@ loop2:
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
buf_read_page(space, zip_size, offset);
|
||||
buf_read_page(space, zip_size, offset, trx);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(++buf_dbg_counter % 37 || buf_validate());
|
||||
@ -2351,17 +2450,17 @@ wait_until_unfixed:
|
||||
UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
|
||||
|
||||
buf_block_buf_fix_inc(block, file, line);
|
||||
//buf_pool_mutex_exit();
|
||||
|
||||
//mutex_exit(&block->mutex);
|
||||
|
||||
/* Check if this is the first access to the page */
|
||||
|
||||
accessed = buf_page_is_accessed(&block->page);
|
||||
|
||||
buf_page_set_accessed(&block->page, TRUE);
|
||||
access_time = buf_page_is_accessed(&block->page);
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
buf_block_make_young(&block->page);
|
||||
buf_page_set_accessed_make_young(&block->page, access_time);
|
||||
|
||||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
||||
ut_a(!block->page.file_page_was_freed);
|
||||
@ -2379,6 +2478,13 @@ wait_until_unfixed:
|
||||
/* Let us wait until the read operation
|
||||
completes */
|
||||
|
||||
if (innobase_get_slow_log() && trx && trx->take_stats)
|
||||
{
|
||||
ut_usectime(&sec, &ms);
|
||||
start_time = (ib_uint64_t)sec * 1000000 + ms;
|
||||
} else {
|
||||
start_time = 0;
|
||||
}
|
||||
for (;;) {
|
||||
enum buf_io_fix io_fix;
|
||||
|
||||
@ -2393,6 +2499,12 @@ wait_until_unfixed:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
|
||||
{
|
||||
ut_usectime(&sec, &ms);
|
||||
finish_time = (ib_uint64_t)sec * 1000000 + ms;
|
||||
trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
|
||||
}
|
||||
}
|
||||
|
||||
fix_type = MTR_MEMO_BUF_FIX;
|
||||
@ -2414,17 +2526,21 @@ wait_until_unfixed:
|
||||
|
||||
mtr_memo_push(mtr, block, fix_type);
|
||||
|
||||
if (!accessed) {
|
||||
if (!access_time) {
|
||||
/* In the case of a first access, try to apply linear
|
||||
read-ahead */
|
||||
|
||||
buf_read_ahead_linear(space, zip_size, offset);
|
||||
buf_read_ahead_linear(space, zip_size, offset, trx);
|
||||
}
|
||||
|
||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||
ut_a(ibuf_count_get(buf_block_get_space(block),
|
||||
buf_block_get_page_no(block)) == 0);
|
||||
#endif
|
||||
if (innobase_get_slow_log()) {
|
||||
_increment_page_get_statistics(block, trx);
|
||||
}
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
||||
@ -2444,9 +2560,10 @@ buf_page_optimistic_get_func(
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mini-transaction */
|
||||
{
|
||||
ibool accessed;
|
||||
unsigned access_time;
|
||||
ibool success;
|
||||
ulint fix_type;
|
||||
trx_t* trx = NULL;
|
||||
|
||||
ut_ad(mtr && block);
|
||||
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
|
||||
@ -2461,14 +2578,16 @@ buf_page_optimistic_get_func(
|
||||
}
|
||||
|
||||
buf_block_buf_fix_inc(block, file, line);
|
||||
accessed = buf_page_is_accessed(&block->page);
|
||||
buf_page_set_accessed(&block->page, TRUE);
|
||||
|
||||
mutex_exit(&block->mutex);
|
||||
|
||||
buf_block_make_young(&block->page);
|
||||
/* Check if this is the first access to the page.
|
||||
We do a dirty read on purpose, to avoid mutex contention.
|
||||
This field is only used for heuristic purposes; it does not
|
||||
affect correctness. */
|
||||
|
||||
/* Check if this is the first access to the page */
|
||||
access_time = buf_page_is_accessed(&block->page);
|
||||
buf_page_set_accessed_make_young(&block->page, access_time);
|
||||
|
||||
ut_ad(!ibuf_inside()
|
||||
|| ibuf_page(buf_block_get_space(block),
|
||||
@ -2520,21 +2639,28 @@ buf_page_optimistic_get_func(
|
||||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
||||
ut_a(block->page.file_page_was_freed == FALSE);
|
||||
#endif
|
||||
if (UNIV_UNLIKELY(!accessed)) {
|
||||
if (innobase_get_slow_log()) {
|
||||
trx = innobase_get_trx();
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(!access_time)) {
|
||||
/* In the case of a first access, try to apply linear
|
||||
read-ahead */
|
||||
|
||||
buf_read_ahead_linear(buf_block_get_space(block),
|
||||
buf_block_get_zip_size(block),
|
||||
buf_block_get_page_no(block));
|
||||
buf_block_get_page_no(block), trx);
|
||||
}
|
||||
|
||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||
ut_a(ibuf_count_get(buf_block_get_space(block),
|
||||
buf_block_get_page_no(block)) == 0);
|
||||
#endif
|
||||
buf_pool->n_page_gets++;
|
||||
buf_pool->stat.n_page_gets++;
|
||||
|
||||
if (innobase_get_slow_log()) {
|
||||
_increment_page_get_statistics(block, trx);
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
@ -2556,6 +2682,7 @@ buf_page_get_known_nowait(
|
||||
{
|
||||
ibool success;
|
||||
ulint fix_type;
|
||||
trx_t* trx = NULL;
|
||||
|
||||
ut_ad(mtr);
|
||||
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
|
||||
@ -2581,8 +2708,24 @@ buf_page_get_known_nowait(
|
||||
|
||||
mutex_exit(&block->mutex);
|
||||
|
||||
if (mode == BUF_MAKE_YOUNG) {
|
||||
buf_block_make_young(&block->page);
|
||||
if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
buf_LRU_make_block_young(&block->page);
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
} else if (!buf_page_is_accessed(&block->page)) {
|
||||
/* Above, we do a dirty read on purpose, to avoid
|
||||
mutex contention. The field buf_page_t::access_time
|
||||
is only used for heuristic purposes. Writes to the
|
||||
field must be protected by mutex, however. */
|
||||
ulint time_ms = ut_time_ms();
|
||||
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&block->mutex);
|
||||
buf_page_set_accessed(&block->page, time_ms);
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&block->mutex);
|
||||
}
|
||||
|
||||
ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
|
||||
@ -2621,7 +2764,12 @@ buf_page_get_known_nowait(
|
||||
|| (ibuf_count_get(buf_block_get_space(block),
|
||||
buf_block_get_page_no(block)) == 0));
|
||||
#endif
|
||||
buf_pool->n_page_gets++;
|
||||
buf_pool->stat.n_page_gets++;
|
||||
|
||||
if (innobase_get_slow_log()) {
|
||||
trx = innobase_get_trx();
|
||||
_increment_page_get_statistics(block, trx);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
@ -2700,7 +2848,7 @@ buf_page_try_get_func(
|
||||
#endif /* UNIV_DEBUG_FILE_ACCESSES */
|
||||
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
buf_pool->n_page_gets++;
|
||||
buf_pool->stat.n_page_gets++;
|
||||
|
||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||
ut_a(ibuf_count_get(buf_block_get_space(block),
|
||||
@ -2719,10 +2867,10 @@ buf_page_init_low(
|
||||
buf_page_t* bpage) /*!< in: block to init */
|
||||
{
|
||||
bpage->flush_type = BUF_FLUSH_LRU;
|
||||
bpage->accessed = FALSE;
|
||||
bpage->io_fix = BUF_IO_NONE;
|
||||
bpage->buf_fix_count = 0;
|
||||
bpage->freed_page_clock = 0;
|
||||
bpage->access_time = 0;
|
||||
bpage->newest_modification = 0;
|
||||
bpage->oldest_modification = 0;
|
||||
HASH_INVALIDATE(bpage, hash);
|
||||
@ -3044,6 +3192,7 @@ buf_page_create(
|
||||
buf_frame_t* frame;
|
||||
buf_block_t* block;
|
||||
buf_block_t* free_block = NULL;
|
||||
ulint time_ms = ut_time_ms();
|
||||
|
||||
ut_ad(mtr);
|
||||
ut_ad(space || !zip_size);
|
||||
@ -3095,7 +3244,7 @@ buf_page_create(
|
||||
buf_LRU_add_block(&block->page, FALSE);
|
||||
|
||||
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
|
||||
buf_pool->n_pages_created++;
|
||||
buf_pool->stat.n_pages_created++;
|
||||
|
||||
if (zip_size) {
|
||||
void* data;
|
||||
@ -3132,13 +3281,13 @@ buf_page_create(
|
||||
rw_lock_x_unlock(&block->lock);
|
||||
}
|
||||
|
||||
buf_page_set_accessed(&block->page, time_ms);
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
|
||||
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
|
||||
|
||||
buf_page_set_accessed(&block->page, TRUE);
|
||||
|
||||
mutex_exit(&block->mutex);
|
||||
|
||||
/* Delete possible entries for the page from the insert buffer:
|
||||
@ -3355,7 +3504,7 @@ corrupt:
|
||||
|
||||
ut_ad(buf_pool->n_pend_reads > 0);
|
||||
buf_pool->n_pend_reads--;
|
||||
buf_pool->n_pages_read++;
|
||||
buf_pool->stat.n_pages_read++;
|
||||
|
||||
if (uncompressed) {
|
||||
rw_lock_x_unlock_gen(&((buf_block_t*) bpage)->lock,
|
||||
@ -3380,7 +3529,7 @@ corrupt:
|
||||
BUF_IO_WRITE);
|
||||
}
|
||||
|
||||
buf_pool->n_pages_written++;
|
||||
buf_pool->stat.n_pages_written++;
|
||||
|
||||
break;
|
||||
|
||||
@ -3412,6 +3561,31 @@ buf_pool_invalidate(void)
|
||||
/*=====================*/
|
||||
{
|
||||
ibool freed;
|
||||
enum buf_flush i;
|
||||
|
||||
buf_pool_mutex_enter();
|
||||
|
||||
for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) {
|
||||
|
||||
/* As this function is called during startup and
|
||||
during redo application phase during recovery, InnoDB
|
||||
is single threaded (apart from IO helper threads) at
|
||||
this stage. No new write batch can be in intialization
|
||||
stage at this point. */
|
||||
ut_ad(buf_pool->init_flush[i] == FALSE);
|
||||
|
||||
/* However, it is possible that a write batch that has
|
||||
been posted earlier is still not complete. For buffer
|
||||
pool invalidation to proceed we must ensure there is NO
|
||||
write activity happening. */
|
||||
if (buf_pool->n_flush[i] > 0) {
|
||||
buf_pool_mutex_exit();
|
||||
buf_flush_wait_batch_end(i);
|
||||
buf_pool_mutex_enter();
|
||||
}
|
||||
}
|
||||
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
ut_ad(buf_all_freed());
|
||||
|
||||
@ -3427,6 +3601,14 @@ buf_pool_invalidate(void)
|
||||
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
|
||||
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
|
||||
|
||||
buf_pool->freed_page_clock = 0;
|
||||
buf_pool->LRU_old = NULL;
|
||||
buf_pool->LRU_old_len = 0;
|
||||
buf_pool->LRU_flush_ended = 0;
|
||||
|
||||
memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
|
||||
buf_refresh_io_stats();
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
}
|
||||
@ -3706,6 +3888,7 @@ buf_print(void)
|
||||
"n pending decompressions %lu\n"
|
||||
"n pending reads %lu\n"
|
||||
"n pending flush LRU %lu list %lu single page %lu\n"
|
||||
"pages made young %lu, not young %lu\n"
|
||||
"pages read %lu, created %lu, written %lu\n",
|
||||
(ulong) size,
|
||||
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
|
||||
@ -3716,8 +3899,11 @@ buf_print(void)
|
||||
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU],
|
||||
(ulong) buf_pool->n_flush[BUF_FLUSH_LIST],
|
||||
(ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE],
|
||||
(ulong) buf_pool->n_pages_read, buf_pool->n_pages_created,
|
||||
(ulong) buf_pool->n_pages_written);
|
||||
(ulong) buf_pool->stat.n_pages_made_young,
|
||||
(ulong) buf_pool->stat.n_pages_not_made_young,
|
||||
(ulong) buf_pool->stat.n_pages_read,
|
||||
(ulong) buf_pool->stat.n_pages_created,
|
||||
(ulong) buf_pool->stat.n_pages_written);
|
||||
|
||||
/* Count the number of blocks belonging to each index in the buffer */
|
||||
|
||||
@ -3927,10 +4113,9 @@ buf_print_io(
|
||||
{
|
||||
time_t current_time;
|
||||
double time_elapsed;
|
||||
ulint size;
|
||||
ulint n_gets_diff;
|
||||
|
||||
ut_ad(buf_pool);
|
||||
size = buf_pool->curr_size;
|
||||
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
@ -3943,13 +4128,15 @@ buf_print_io(
|
||||
"Buffer pool size, bytes %lu\n"
|
||||
"Free buffers %lu\n"
|
||||
"Database pages %lu\n"
|
||||
"Old database pages %lu\n"
|
||||
"Modified db pages %lu\n"
|
||||
"Pending reads %lu\n"
|
||||
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
|
||||
(ulong) size,
|
||||
(ulong) size * UNIV_PAGE_SIZE,
|
||||
(ulong) buf_pool->curr_size,
|
||||
(ulong) buf_pool->curr_size * UNIV_PAGE_SIZE,
|
||||
(ulong) UT_LIST_GET_LEN(buf_pool->free),
|
||||
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
|
||||
(ulong) buf_pool->LRU_old_len,
|
||||
(ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
|
||||
(ulong) buf_pool->n_pend_reads,
|
||||
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
|
||||
@ -3961,37 +4148,66 @@ buf_print_io(
|
||||
current_time = time(NULL);
|
||||
time_elapsed = 0.001 + difftime(current_time,
|
||||
buf_pool->last_printout_time);
|
||||
buf_pool->last_printout_time = current_time;
|
||||
|
||||
fprintf(file,
|
||||
"Pages made young %lu, not young %lu\n"
|
||||
"%.2f youngs/s, %.2f non-youngs/s\n"
|
||||
"Pages read %lu, created %lu, written %lu\n"
|
||||
"%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
|
||||
(ulong) buf_pool->n_pages_read,
|
||||
(ulong) buf_pool->n_pages_created,
|
||||
(ulong) buf_pool->n_pages_written,
|
||||
(buf_pool->n_pages_read - buf_pool->n_pages_read_old)
|
||||
(ulong) buf_pool->stat.n_pages_made_young,
|
||||
(ulong) buf_pool->stat.n_pages_not_made_young,
|
||||
(buf_pool->stat.n_pages_made_young
|
||||
- buf_pool->old_stat.n_pages_made_young)
|
||||
/ time_elapsed,
|
||||
(buf_pool->n_pages_created - buf_pool->n_pages_created_old)
|
||||
(buf_pool->stat.n_pages_not_made_young
|
||||
- buf_pool->old_stat.n_pages_not_made_young)
|
||||
/ time_elapsed,
|
||||
(buf_pool->n_pages_written - buf_pool->n_pages_written_old)
|
||||
(ulong) buf_pool->stat.n_pages_read,
|
||||
(ulong) buf_pool->stat.n_pages_created,
|
||||
(ulong) buf_pool->stat.n_pages_written,
|
||||
(buf_pool->stat.n_pages_read
|
||||
- buf_pool->old_stat.n_pages_read)
|
||||
/ time_elapsed,
|
||||
(buf_pool->stat.n_pages_created
|
||||
- buf_pool->old_stat.n_pages_created)
|
||||
/ time_elapsed,
|
||||
(buf_pool->stat.n_pages_written
|
||||
- buf_pool->old_stat.n_pages_written)
|
||||
/ time_elapsed);
|
||||
|
||||
if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
|
||||
fprintf(file, "Buffer pool hit rate %lu / 1000\n",
|
||||
n_gets_diff = buf_pool->stat.n_page_gets - buf_pool->old_stat.n_page_gets;
|
||||
|
||||
if (n_gets_diff) {
|
||||
fprintf(file,
|
||||
"Buffer pool hit rate %lu / 1000,"
|
||||
" young-making rate %lu / 1000 not %lu / 1000\n",
|
||||
(ulong)
|
||||
(1000 - ((1000 * (buf_pool->n_pages_read
|
||||
- buf_pool->n_pages_read_old))
|
||||
/ (buf_pool->n_page_gets
|
||||
- buf_pool->n_page_gets_old))));
|
||||
(1000 - ((1000 * (buf_pool->stat.n_pages_read
|
||||
- buf_pool->old_stat.n_pages_read))
|
||||
/ (buf_pool->stat.n_page_gets
|
||||
- buf_pool->old_stat.n_page_gets))),
|
||||
(ulong)
|
||||
(1000 * (buf_pool->stat.n_pages_made_young
|
||||
- buf_pool->old_stat.n_pages_made_young)
|
||||
/ n_gets_diff),
|
||||
(ulong)
|
||||
(1000 * (buf_pool->stat.n_pages_not_made_young
|
||||
- buf_pool->old_stat.n_pages_not_made_young)
|
||||
/ n_gets_diff));
|
||||
} else {
|
||||
fputs("No buffer pool page gets since the last printout\n",
|
||||
file);
|
||||
}
|
||||
|
||||
buf_pool->n_page_gets_old = buf_pool->n_page_gets;
|
||||
buf_pool->n_pages_read_old = buf_pool->n_pages_read;
|
||||
buf_pool->n_pages_created_old = buf_pool->n_pages_created;
|
||||
buf_pool->n_pages_written_old = buf_pool->n_pages_written;
|
||||
/* Statistics about read ahead algorithm */
|
||||
fprintf(file, "Pages read ahead %.2f/s,"
|
||||
" evicted without access %.2f/s\n",
|
||||
(buf_pool->stat.n_ra_pages_read
|
||||
- buf_pool->old_stat.n_ra_pages_read)
|
||||
/ time_elapsed,
|
||||
(buf_pool->stat.n_ra_pages_evicted
|
||||
- buf_pool->old_stat.n_ra_pages_evicted)
|
||||
/ time_elapsed);
|
||||
|
||||
/* Print some values to help us with visualizing what is
|
||||
happening with LRU eviction. */
|
||||
@ -4003,6 +4219,7 @@ buf_print_io(
|
||||
buf_LRU_stat_sum.io, buf_LRU_stat_cur.io,
|
||||
buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
|
||||
|
||||
buf_refresh_io_stats();
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
mutex_exit(&free_list_mutex);
|
||||
@ -4018,10 +4235,7 @@ buf_refresh_io_stats(void)
|
||||
/*======================*/
|
||||
{
|
||||
buf_pool->last_printout_time = time(NULL);
|
||||
buf_pool->n_page_gets_old = buf_pool->n_page_gets;
|
||||
buf_pool->n_pages_read_old = buf_pool->n_pages_read;
|
||||
buf_pool->n_pages_created_old = buf_pool->n_pages_created;
|
||||
buf_pool->n_pages_written_old = buf_pool->n_pages_written;
|
||||
buf_pool->old_stat = buf_pool->stat;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -330,6 +330,28 @@ buf_flush_write_complete(
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Flush a batch of writes to the datafiles that have already been
|
||||
written by the OS. */
|
||||
static
|
||||
void
|
||||
buf_flush_sync_datafiles(void)
|
||||
/*==========================*/
|
||||
{
|
||||
/* Wake possible simulated aio thread to actually post the
|
||||
writes to the operating system */
|
||||
os_aio_simulated_wake_handler_threads();
|
||||
|
||||
/* Wait that all async writes to tablespaces have been posted to
|
||||
the OS */
|
||||
os_aio_wait_until_no_pending_writes();
|
||||
|
||||
/* Now we flush the data to disk (for example, with fsync) */
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Flushes possible buffered writes from the doublewrite memory buffer to disk,
|
||||
and also wakes up the aio thread if simulated aio is used. It is very
|
||||
@ -347,8 +369,8 @@ buf_flush_buffered_writes(void)
|
||||
ulint i;
|
||||
|
||||
if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
|
||||
os_aio_simulated_wake_handler_threads();
|
||||
|
||||
/* Sync the writes to the disk. */
|
||||
buf_flush_sync_datafiles();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -556,22 +578,10 @@ flush:
|
||||
buf_LRU_stat_inc_io();
|
||||
}
|
||||
|
||||
/* Wake possible simulated aio thread to actually post the
|
||||
writes to the operating system */
|
||||
|
||||
os_aio_simulated_wake_handler_threads();
|
||||
|
||||
/* Wait that all async writes to tablespaces have been posted to
|
||||
the OS */
|
||||
|
||||
os_aio_wait_until_no_pending_writes();
|
||||
|
||||
/* Now we flush the data to disk (for example, with fsync) */
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
/* Sync the writes to the disk. */
|
||||
buf_flush_sync_datafiles();
|
||||
|
||||
/* We can now reuse the doublewrite memory buffer: */
|
||||
|
||||
trx_doublewrite->first_free = 0;
|
||||
|
||||
mutex_exit(&(trx_doublewrite->mutex));
|
||||
@ -994,9 +1004,7 @@ buf_flush_try_neighbors(
|
||||
|| buf_page_is_old(bpage)) {
|
||||
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
|
||||
|
||||
ut_a(block_mutex);
|
||||
|
||||
if (buf_flush_ready_for_flush(bpage, flush_type)
|
||||
if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)
|
||||
&& (i == offset || !bpage->buf_fix_count)) {
|
||||
/* We only try to flush those
|
||||
neighbors != offset where the buf fix count is
|
||||
@ -1012,7 +1020,7 @@ buf_flush_try_neighbors(
|
||||
|
||||
//buf_pool_mutex_enter();
|
||||
rw_lock_s_lock(&page_hash_latch);
|
||||
} else {
|
||||
} else if (block_mutex) {
|
||||
mutex_exit(block_mutex);
|
||||
}
|
||||
}
|
||||
@ -1050,6 +1058,7 @@ buf_flush_batch(
|
||||
min_n), otherwise ignored */
|
||||
{
|
||||
buf_page_t* bpage;
|
||||
buf_page_t* prev_bpage = NULL;
|
||||
ulint page_count = 0;
|
||||
ulint old_page_count;
|
||||
ulint space;
|
||||
@ -1103,6 +1112,9 @@ flush_next:
|
||||
mutex_enter(&flush_list_mutex);
|
||||
remaining = UT_LIST_GET_LEN(buf_pool->flush_list);
|
||||
bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
|
||||
if (bpage) {
|
||||
prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
|
||||
}
|
||||
mutex_exit(&flush_list_mutex);
|
||||
if (!bpage
|
||||
|| bpage->oldest_modification >= lsn_limit) {
|
||||
@ -1123,11 +1135,14 @@ flush_next:
|
||||
mutex_t*block_mutex = buf_page_get_mutex_enter(bpage);
|
||||
ibool ready;
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
//ut_a(buf_page_in_file(bpage));
|
||||
|
||||
ut_a(block_mutex);
|
||||
if (block_mutex) {
|
||||
ready = buf_flush_ready_for_flush(bpage, flush_type);
|
||||
mutex_exit(block_mutex);
|
||||
} else {
|
||||
ready = FALSE;
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
space = buf_page_get_space(bpage);
|
||||
@ -1162,6 +1177,13 @@ flush_next:
|
||||
mutex_enter(&flush_list_mutex);
|
||||
bpage = UT_LIST_GET_PREV(flush_list, bpage);
|
||||
//ut_ad(!bpage || bpage->in_flush_list); /* optimistic */
|
||||
if (bpage != prev_bpage) {
|
||||
/* the search may warp.. retrying */
|
||||
bpage = NULL;
|
||||
}
|
||||
if (bpage) {
|
||||
prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
|
||||
}
|
||||
mutex_exit(&flush_list_mutex);
|
||||
remaining--;
|
||||
}
|
||||
@ -1271,13 +1293,13 @@ buf_flush_LRU_recommendation(void)
|
||||
}
|
||||
block_mutex = buf_page_get_mutex_enter(bpage);
|
||||
|
||||
ut_a(block_mutex);
|
||||
|
||||
if (buf_flush_ready_for_replace(bpage)) {
|
||||
if (block_mutex && buf_flush_ready_for_replace(bpage)) {
|
||||
n_replaceable++;
|
||||
}
|
||||
|
||||
if (block_mutex) {
|
||||
mutex_exit(block_mutex);
|
||||
}
|
||||
|
||||
distance++;
|
||||
|
||||
|
@ -49,18 +49,22 @@ Created 11/5/1995 Heikki Tuuri
|
||||
#include "log0recv.h"
|
||||
#include "srv0srv.h"
|
||||
|
||||
/** The number of blocks from the LRU_old pointer onward, including the block
|
||||
pointed to, must be 3/8 of the whole LRU list length, except that the
|
||||
tolerance defined below is allowed. Note that the tolerance must be small
|
||||
enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the
|
||||
LRU_old pointer is not allowed to point to either end of the LRU list. */
|
||||
/** The number of blocks from the LRU_old pointer onward, including
|
||||
the block pointed to, must be buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
|
||||
of the whole LRU list length, except that the tolerance defined below
|
||||
is allowed. Note that the tolerance must be small enough such that for
|
||||
even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not
|
||||
allowed to point to either end of the LRU list. */
|
||||
|
||||
#define BUF_LRU_OLD_TOLERANCE 20
|
||||
|
||||
/** The whole LRU list length is divided by this number to determine an
|
||||
initial segment in buf_LRU_get_recent_limit */
|
||||
|
||||
#define BUF_LRU_INITIAL_RATIO 8
|
||||
/** The minimum amount of non-old blocks when the LRU_old list exists
|
||||
(that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).
|
||||
@see buf_LRU_old_adjust_len */
|
||||
#define BUF_LRU_NON_OLD_MIN_LEN 5
|
||||
#if BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN
|
||||
# error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN"
|
||||
#endif
|
||||
|
||||
/** When dropping the search hash index entries before deleting an ibd
|
||||
file, we build a local array of pages belonging to that tablespace
|
||||
@ -107,6 +111,15 @@ UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_sum;
|
||||
|
||||
/* @} */
|
||||
|
||||
/** @name Heuristics for detecting index scan @{ */
|
||||
/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
|
||||
"old" blocks. Protected by buf_pool_mutex. */
|
||||
UNIV_INTERN uint buf_LRU_old_ratio;
|
||||
/** Move blocks to "new" LRU list only if the first access was at
|
||||
least this many milliseconds ago. Not protected by any mutex or latch. */
|
||||
UNIV_INTERN uint buf_LRU_old_threshold_ms;
|
||||
/* @} */
|
||||
|
||||
/******************************************************************//**
|
||||
Takes a block out of the LRU list and page hash table.
|
||||
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
|
||||
@ -255,9 +268,12 @@ scan_again:
|
||||
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
|
||||
buf_page_t* prev_bpage;
|
||||
|
||||
ut_a(block_mutex);
|
||||
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
|
||||
if (!block_mutex) {
|
||||
goto next_page;
|
||||
}
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
|
||||
@ -360,9 +376,13 @@ scan_again:
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
ut_a(block_mutex);
|
||||
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
|
||||
if (!block_mutex) {
|
||||
bpage = prev_bpage;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf_page_get_space(bpage) == id) {
|
||||
if (bpage->buf_fix_count > 0
|
||||
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
|
||||
@ -450,45 +470,6 @@ next_page:
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Gets the minimum LRU_position field for the blocks in an initial segment
|
||||
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
|
||||
guaranteed to be precise, because the ulint_clock may wrap around.
|
||||
@return the limit; zero if could not determine it */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
buf_LRU_get_recent_limit(void)
|
||||
/*==========================*/
|
||||
{
|
||||
const buf_page_t* bpage;
|
||||
ulint len;
|
||||
ulint limit;
|
||||
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
|
||||
len = UT_LIST_GET_LEN(buf_pool->LRU);
|
||||
|
||||
if (len < BUF_LRU_OLD_MIN_LEN) {
|
||||
/* The LRU list is too short to do read-ahead */
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
|
||||
|
||||
limit = buf_page_get_LRU_position(bpage);
|
||||
len /= BUF_LRU_INITIAL_RATIO;
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
|
||||
return(limit > len ? (limit - len) : 0);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
|
||||
UNIV_INTERN
|
||||
@ -631,10 +612,13 @@ restart:
|
||||
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
|
||||
|
||||
enum buf_lru_free_block_status freed;
|
||||
unsigned accessed;
|
||||
mutex_t* block_mutex
|
||||
= buf_page_get_mutex_enter(bpage);
|
||||
|
||||
ut_a(block_mutex);
|
||||
if (!block_mutex) {
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (!bpage->in_LRU_list
|
||||
|| !buf_page_in_file(bpage)) {
|
||||
@ -645,11 +629,18 @@ restart:
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
ut_ad(bpage->in_LRU_list);
|
||||
|
||||
accessed = buf_page_is_accessed(bpage);
|
||||
freed = buf_LRU_free_block(bpage, TRUE, NULL, have_LRU_mutex);
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
switch (freed) {
|
||||
case BUF_LRU_FREED:
|
||||
/* Keep track of pages that are evicted without
|
||||
ever being accessed. This gives us a measure of
|
||||
the effectiveness of readahead */
|
||||
if (!accessed) {
|
||||
++buf_pool->stat.n_ra_pages_evicted;
|
||||
}
|
||||
return(TRUE);
|
||||
|
||||
case BUF_LRU_NOT_FREED:
|
||||
@ -1027,8 +1018,10 @@ buf_LRU_old_adjust_len(void)
|
||||
ut_a(buf_pool->LRU_old);
|
||||
//ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(mutex_own(&LRU_list_mutex));
|
||||
#if 3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5
|
||||
# error "3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5"
|
||||
ut_ad(buf_LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
|
||||
ut_ad(buf_LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
|
||||
#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
|
||||
# error "BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)"
|
||||
#endif
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||
@ -1040,34 +1033,39 @@ buf_LRU_old_adjust_len(void)
|
||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
for (;;) {
|
||||
old_len = buf_pool->LRU_old_len;
|
||||
new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
|
||||
new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
|
||||
* buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
|
||||
UT_LIST_GET_LEN(buf_pool->LRU)
|
||||
- (BUF_LRU_OLD_TOLERANCE
|
||||
+ BUF_LRU_NON_OLD_MIN_LEN));
|
||||
|
||||
ut_ad(buf_pool->LRU_old->in_LRU_list);
|
||||
ut_a(buf_pool->LRU_old);
|
||||
for (;;) {
|
||||
buf_page_t* LRU_old = buf_pool->LRU_old;
|
||||
|
||||
ut_a(LRU_old);
|
||||
ut_ad(LRU_old->in_LRU_list);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(buf_pool->LRU_old->old);
|
||||
ut_a(LRU_old->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
/* Update the LRU_old pointer if necessary */
|
||||
|
||||
if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
|
||||
if (old_len + BUF_LRU_OLD_TOLERANCE < new_len) {
|
||||
|
||||
buf_pool->LRU_old = UT_LIST_GET_PREV(
|
||||
LRU, buf_pool->LRU_old);
|
||||
buf_pool->LRU_old = LRU_old = UT_LIST_GET_PREV(
|
||||
LRU, LRU_old);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(!buf_pool->LRU_old->old);
|
||||
ut_a(!LRU_old->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
buf_page_set_old(buf_pool->LRU_old, TRUE);
|
||||
buf_pool->LRU_old_len++;
|
||||
old_len = ++buf_pool->LRU_old_len;
|
||||
buf_page_set_old(LRU_old, TRUE);
|
||||
|
||||
} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
|
||||
|
||||
buf_page_set_old(buf_pool->LRU_old, FALSE);
|
||||
buf_pool->LRU_old = UT_LIST_GET_NEXT(
|
||||
LRU, buf_pool->LRU_old);
|
||||
buf_pool->LRU_old_len--;
|
||||
buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old);
|
||||
old_len = --buf_pool->LRU_old_len;
|
||||
buf_page_set_old(LRU_old, FALSE);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -1092,12 +1090,13 @@ buf_LRU_old_init(void)
|
||||
the adjust function to move the LRU_old pointer to the right
|
||||
position */
|
||||
|
||||
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
|
||||
|
||||
while (bpage != NULL) {
|
||||
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage != NULL;
|
||||
bpage = UT_LIST_GET_PREV(LRU, bpage)) {
|
||||
ut_ad(bpage->in_LRU_list);
|
||||
buf_page_set_old(bpage, TRUE);
|
||||
bpage = UT_LIST_GET_NEXT(LRU, bpage);
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
/* This loop temporarily violates the
|
||||
assertions of buf_page_set_old(). */
|
||||
bpage->old = TRUE;
|
||||
}
|
||||
|
||||
buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU);
|
||||
@ -1152,16 +1151,19 @@ buf_LRU_remove_block(
|
||||
|
||||
if (UNIV_UNLIKELY(bpage == buf_pool->LRU_old)) {
|
||||
|
||||
/* Below: the previous block is guaranteed to exist, because
|
||||
the LRU_old pointer is only allowed to differ by the
|
||||
tolerance value from strict 3/8 of the LRU list length. */
|
||||
/* Below: the previous block is guaranteed to exist,
|
||||
because the LRU_old pointer is only allowed to differ
|
||||
by BUF_LRU_OLD_TOLERANCE from strict
|
||||
buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the LRU
|
||||
list length. */
|
||||
buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
|
||||
buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, bpage);
|
||||
ut_a(buf_pool->LRU_old);
|
||||
ut_a(prev_bpage);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(!buf_pool->LRU_old->old);
|
||||
ut_a(!prev_bpage->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
buf_page_set_old(buf_pool->LRU_old, TRUE);
|
||||
buf_pool->LRU_old = prev_bpage;
|
||||
buf_page_set_old(prev_bpage, TRUE);
|
||||
|
||||
buf_pool->LRU_old_len++;
|
||||
}
|
||||
@ -1172,10 +1174,19 @@ buf_LRU_remove_block(
|
||||
|
||||
buf_unzip_LRU_remove_block_if_needed(bpage);
|
||||
|
||||
/* If the LRU list is so short that LRU_old not defined, return */
|
||||
/* If the LRU list is so short that LRU_old is not defined,
|
||||
clear the "old" flags and return */
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU); bpage != NULL;
|
||||
bpage = UT_LIST_GET_NEXT(LRU, bpage)) {
|
||||
/* This loop temporarily violates the
|
||||
assertions of buf_page_set_old(). */
|
||||
bpage->old = FALSE;
|
||||
}
|
||||
|
||||
buf_pool->LRU_old = NULL;
|
||||
buf_pool->LRU_old_len = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1227,8 +1238,6 @@ buf_LRU_add_block_to_end_low(
|
||||
/*=========================*/
|
||||
buf_page_t* bpage) /*!< in: control block */
|
||||
{
|
||||
buf_page_t* last_bpage;
|
||||
|
||||
ut_ad(buf_pool);
|
||||
ut_ad(bpage);
|
||||
//ut_ad(buf_pool_mutex_own());
|
||||
@ -1236,31 +1245,18 @@ buf_LRU_add_block_to_end_low(
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
last_bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||
|
||||
if (last_bpage) {
|
||||
bpage->LRU_position = last_bpage->LRU_position;
|
||||
} else {
|
||||
bpage->LRU_position = buf_pool_clock_tic();
|
||||
}
|
||||
|
||||
ut_ad(!bpage->in_LRU_list);
|
||||
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
|
||||
bpage->in_LRU_list = TRUE;
|
||||
|
||||
buf_page_set_old(bpage, TRUE);
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
buf_pool->LRU_old_len++;
|
||||
}
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
ut_ad(buf_pool->LRU_old);
|
||||
|
||||
/* Adjust the length of the old block list if necessary */
|
||||
|
||||
buf_page_set_old(bpage, TRUE);
|
||||
buf_pool->LRU_old_len++;
|
||||
buf_LRU_old_adjust_len();
|
||||
|
||||
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
|
||||
@ -1269,6 +1265,8 @@ buf_LRU_add_block_to_end_low(
|
||||
defined: init it */
|
||||
|
||||
buf_LRU_old_init();
|
||||
} else {
|
||||
buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
|
||||
}
|
||||
|
||||
/* If this is a zipped block with decompressed frame as well
|
||||
@ -1302,7 +1300,6 @@ buf_LRU_add_block_low(
|
||||
|
||||
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
|
||||
|
||||
bpage->LRU_position = buf_pool_clock_tic();
|
||||
bpage->freed_page_clock = buf_pool->freed_page_clock;
|
||||
} else {
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
@ -1317,23 +1314,17 @@ buf_LRU_add_block_low(
|
||||
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
|
||||
bpage);
|
||||
buf_pool->LRU_old_len++;
|
||||
|
||||
/* We copy the LRU position field of the previous block
|
||||
to the new block */
|
||||
|
||||
bpage->LRU_position = (buf_pool->LRU_old)->LRU_position;
|
||||
}
|
||||
|
||||
bpage->in_LRU_list = TRUE;
|
||||
|
||||
buf_page_set_old(bpage, old);
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
ut_ad(buf_pool->LRU_old);
|
||||
|
||||
/* Adjust the length of the old block list if necessary */
|
||||
|
||||
buf_page_set_old(bpage, old);
|
||||
buf_LRU_old_adjust_len();
|
||||
|
||||
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
|
||||
@ -1342,6 +1333,8 @@ buf_LRU_add_block_low(
|
||||
defined: init it */
|
||||
|
||||
buf_LRU_old_init();
|
||||
} else {
|
||||
buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
|
||||
}
|
||||
|
||||
/* If this is a zipped block with decompressed frame as well
|
||||
@ -1375,6 +1368,13 @@ buf_LRU_make_block_young(
|
||||
/*=====================*/
|
||||
buf_page_t* bpage) /*!< in: control block */
|
||||
{
|
||||
//ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(mutex_own(&LRU_list_mutex));
|
||||
|
||||
if (bpage->old) {
|
||||
buf_pool->stat.n_pages_made_young++;
|
||||
}
|
||||
|
||||
buf_LRU_remove_block(bpage);
|
||||
buf_LRU_add_block_low(bpage, FALSE);
|
||||
}
|
||||
@ -1571,15 +1571,6 @@ not_freed:
|
||||
|
||||
buf_pool->LRU_old = b;
|
||||
}
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(prev_b->old
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)
|
||||
|| UT_LIST_GET_NEXT(LRU, b)->old);
|
||||
} else {
|
||||
ut_a(!prev_b->old
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
}
|
||||
|
||||
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
|
||||
@ -1595,6 +1586,11 @@ not_freed:
|
||||
defined: init it */
|
||||
buf_LRU_old_init();
|
||||
}
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* Check that the "old" flag is consistent
|
||||
in the block and its neighbours. */
|
||||
buf_page_set_old(b, buf_page_is_old(b));
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
} else {
|
||||
b->in_LRU_list = FALSE;
|
||||
buf_LRU_add_block_low(b, buf_page_is_old(b));
|
||||
@ -1985,6 +1981,52 @@ buf_LRU_block_free_hashed_page(
|
||||
buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Updates buf_LRU_old_ratio.
|
||||
@return updated old_pct */
|
||||
UNIV_INTERN
|
||||
uint
|
||||
buf_LRU_old_ratio_update(
|
||||
/*=====================*/
|
||||
uint old_pct,/*!< in: Reserve this percentage of
|
||||
the buffer pool for "old" blocks. */
|
||||
ibool adjust) /*!< in: TRUE=adjust the LRU list;
|
||||
FALSE=just assign buf_LRU_old_ratio
|
||||
during the initialization of InnoDB */
|
||||
{
|
||||
uint ratio;
|
||||
|
||||
ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100;
|
||||
if (ratio < BUF_LRU_OLD_RATIO_MIN) {
|
||||
ratio = BUF_LRU_OLD_RATIO_MIN;
|
||||
} else if (ratio > BUF_LRU_OLD_RATIO_MAX) {
|
||||
ratio = BUF_LRU_OLD_RATIO_MAX;
|
||||
}
|
||||
|
||||
if (adjust) {
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
|
||||
if (ratio != buf_LRU_old_ratio) {
|
||||
buf_LRU_old_ratio = ratio;
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU)
|
||||
>= BUF_LRU_OLD_MIN_LEN) {
|
||||
buf_LRU_old_adjust_len();
|
||||
}
|
||||
}
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
} else {
|
||||
buf_LRU_old_ratio = ratio;
|
||||
}
|
||||
|
||||
/* the reverse of
|
||||
ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100 */
|
||||
return((uint) (ratio * 100 / (double) BUF_LRU_OLD_RATIO_DIV + 0.5));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Update the historical stats that we are collecting for LRU eviction
|
||||
policy at the end of each interval. */
|
||||
@ -2023,6 +2065,218 @@ func_exit:
|
||||
memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Dump the LRU page list to the specific file. */
|
||||
#define LRU_DUMP_FILE "ib_lru_dump"
|
||||
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
buf_LRU_file_dump(void)
|
||||
/*===================*/
|
||||
{
|
||||
os_file_t dump_file = -1;
|
||||
ibool success;
|
||||
byte* buffer_base = NULL;
|
||||
byte* buffer = NULL;
|
||||
buf_page_t* bpage;
|
||||
ulint buffers;
|
||||
ulint offset;
|
||||
ibool ret = FALSE;
|
||||
ulint i;
|
||||
|
||||
for (i = 0; i < srv_n_data_files; i++) {
|
||||
if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
|
||||
fprintf(stderr,
|
||||
" InnoDB: The name '%s' seems to be used for"
|
||||
" innodb_data_file_path. Dumping LRU list is not"
|
||||
" done for safeness.\n", LRU_DUMP_FILE);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
|
||||
buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
|
||||
if (!buffer) {
|
||||
fprintf(stderr,
|
||||
" InnoDB: cannot allocate buffer.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
dump_file = os_file_create(LRU_DUMP_FILE, OS_FILE_OVERWRITE,
|
||||
OS_FILE_NORMAL, OS_DATA_FILE, &success);
|
||||
if (!success) {
|
||||
os_file_get_last_error(TRUE);
|
||||
fprintf(stderr,
|
||||
" InnoDB: cannot open %s\n", LRU_DUMP_FILE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||
|
||||
buffers = offset = 0;
|
||||
while (bpage != NULL) {
|
||||
if (offset == 0) {
|
||||
memset(buffer, 0, UNIV_PAGE_SIZE);
|
||||
}
|
||||
|
||||
mach_write_to_4(buffer + offset * 4, bpage->space);
|
||||
offset++;
|
||||
mach_write_to_4(buffer + offset * 4, bpage->offset);
|
||||
offset++;
|
||||
|
||||
if (offset == UNIV_PAGE_SIZE/4) {
|
||||
success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
|
||||
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
|
||||
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
|
||||
UNIV_PAGE_SIZE);
|
||||
if (!success) {
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
fprintf(stderr,
|
||||
" InnoDB: cannot write page %lu of %s\n",
|
||||
buffers, LRU_DUMP_FILE);
|
||||
goto end;
|
||||
}
|
||||
buffers++;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
}
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
|
||||
if (offset == 0) {
|
||||
memset(buffer, 0, UNIV_PAGE_SIZE);
|
||||
}
|
||||
|
||||
mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
|
||||
offset++;
|
||||
mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
|
||||
offset++;
|
||||
|
||||
success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
|
||||
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
|
||||
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
|
||||
UNIV_PAGE_SIZE);
|
||||
if (!success) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
end:
|
||||
if (dump_file != -1)
|
||||
os_file_close(dump_file);
|
||||
if (buffer_base)
|
||||
ut_free(buffer_base);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
/********************************************************************//**
|
||||
Read the pages based on the specific file.*/
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
buf_LRU_file_restore(void)
|
||||
/*======================*/
|
||||
{
|
||||
os_file_t dump_file = -1;
|
||||
ibool success;
|
||||
byte* buffer_base = NULL;
|
||||
byte* buffer = NULL;
|
||||
ulint buffers;
|
||||
ulint offset;
|
||||
ulint reads = 0;
|
||||
ulint req = 0;
|
||||
ibool terminated = FALSE;
|
||||
ibool ret = FALSE;
|
||||
|
||||
buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
|
||||
buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
|
||||
if (!buffer) {
|
||||
fprintf(stderr,
|
||||
" InnoDB: cannot allocate buffer.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
dump_file = os_file_create_simple_no_error_handling(
|
||||
LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
|
||||
if (!success) {
|
||||
os_file_get_last_error(TRUE);
|
||||
fprintf(stderr,
|
||||
" InnoDB: cannot open %s\n", LRU_DUMP_FILE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
buffers = 0;
|
||||
while (!terminated) {
|
||||
success = os_file_read(dump_file, buffer,
|
||||
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
|
||||
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
|
||||
UNIV_PAGE_SIZE);
|
||||
if (!success) {
|
||||
fprintf(stderr,
|
||||
" InnoDB: cannot read page %lu of %s,"
|
||||
" or meet unexpected terminal.",
|
||||
buffers, LRU_DUMP_FILE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
|
||||
ulint space_id, zip_size, page_no;
|
||||
ulint err;
|
||||
ib_int64_t tablespace_version;
|
||||
|
||||
space_id = mach_read_from_4(buffer + offset * 4);
|
||||
page_no = mach_read_from_4(buffer + (offset + 1) * 4);
|
||||
if (space_id == 0xFFFFFFFFUL
|
||||
|| page_no == 0xFFFFFFFFUL) {
|
||||
terminated = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (offset % 16 == 15) {
|
||||
os_aio_simulated_wake_handler_threads();
|
||||
buf_flush_free_margin(FALSE);
|
||||
}
|
||||
|
||||
zip_size = fil_space_get_zip_size(space_id);
|
||||
if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fil_area_is_exist(space_id, zip_size, page_no, 0,
|
||||
zip_size ? zip_size : UNIV_PAGE_SIZE)) {
|
||||
|
||||
tablespace_version = fil_space_get_version(space_id);
|
||||
|
||||
req++;
|
||||
reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
|
||||
| OS_AIO_SIMULATED_WAKE_LATER,
|
||||
space_id, zip_size, TRUE,
|
||||
tablespace_version, page_no, NULL);
|
||||
buf_LRU_stat_inc_io();
|
||||
}
|
||||
}
|
||||
|
||||
buffers++;
|
||||
}
|
||||
|
||||
os_aio_simulated_wake_handler_threads();
|
||||
buf_flush_free_margin(FALSE);
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: reading pages based on the dumped LRU list was done."
|
||||
" (requested: %lu, read: %lu)\n", req, reads);
|
||||
ret = TRUE;
|
||||
end:
|
||||
if (dump_file != -1)
|
||||
os_file_close(dump_file);
|
||||
if (buffer_base)
|
||||
ut_free(buffer_base);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
/**********************************************************************//**
|
||||
Validates the LRU list.
|
||||
@ -2036,7 +2290,6 @@ buf_LRU_validate(void)
|
||||
buf_block_t* block;
|
||||
ulint old_len;
|
||||
ulint new_len;
|
||||
ulint LRU_pos;
|
||||
|
||||
ut_ad(buf_pool);
|
||||
//buf_pool_mutex_enter();
|
||||
@ -2046,7 +2299,11 @@ buf_LRU_validate(void)
|
||||
|
||||
ut_a(buf_pool->LRU_old);
|
||||
old_len = buf_pool->LRU_old_len;
|
||||
new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
|
||||
new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
|
||||
* buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
|
||||
UT_LIST_GET_LEN(buf_pool->LRU)
|
||||
- (BUF_LRU_OLD_TOLERANCE
|
||||
+ BUF_LRU_NON_OLD_MIN_LEN));
|
||||
ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
|
||||
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
|
||||
}
|
||||
@ -2077,28 +2334,24 @@ buf_LRU_validate(void)
|
||||
}
|
||||
|
||||
if (buf_page_is_old(bpage)) {
|
||||
old_len++;
|
||||
}
|
||||
const buf_page_t* prev
|
||||
= UT_LIST_GET_PREV(LRU, bpage);
|
||||
const buf_page_t* next
|
||||
= UT_LIST_GET_NEXT(LRU, bpage);
|
||||
|
||||
if (buf_pool->LRU_old && (old_len == 1)) {
|
||||
if (!old_len++) {
|
||||
ut_a(buf_pool->LRU_old == bpage);
|
||||
} else {
|
||||
ut_a(!prev || buf_page_is_old(prev));
|
||||
}
|
||||
|
||||
LRU_pos = buf_page_get_LRU_position(bpage);
|
||||
ut_a(!next || buf_page_is_old(next));
|
||||
}
|
||||
|
||||
bpage = UT_LIST_GET_NEXT(LRU, bpage);
|
||||
|
||||
if (bpage) {
|
||||
/* If the following assert fails, it may
|
||||
not be an error: just the buf_pool clock
|
||||
has wrapped around */
|
||||
ut_a(LRU_pos >= buf_page_get_LRU_position(bpage));
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_pool->LRU_old) {
|
||||
ut_a(buf_pool->LRU_old_len == old_len);
|
||||
}
|
||||
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
mutex_enter(&free_list_mutex);
|
||||
@ -2149,9 +2402,6 @@ buf_LRU_print(void)
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
|
||||
fprintf(stderr, "Pool ulint clock %lu\n",
|
||||
(ulong) buf_pool->ulint_clock);
|
||||
|
||||
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
|
||||
|
||||
while (bpage != NULL) {
|
||||
@ -2182,18 +2432,16 @@ buf_LRU_print(void)
|
||||
const byte* frame;
|
||||
case BUF_BLOCK_FILE_PAGE:
|
||||
frame = buf_block_get_frame((buf_block_t*) bpage);
|
||||
fprintf(stderr, "\nLRU pos %lu type %lu"
|
||||
fprintf(stderr, "\ntype %lu"
|
||||
" index id %lu\n",
|
||||
(ulong) buf_page_get_LRU_position(bpage),
|
||||
(ulong) fil_page_get_type(frame),
|
||||
(ulong) ut_dulint_get_low(
|
||||
btr_page_get_index_id(frame)));
|
||||
break;
|
||||
case BUF_BLOCK_ZIP_PAGE:
|
||||
frame = bpage->zip.data;
|
||||
fprintf(stderr, "\nLRU pos %lu type %lu size %lu"
|
||||
fprintf(stderr, "\ntype %lu size %lu"
|
||||
" index id %lu\n",
|
||||
(ulong) buf_page_get_LRU_position(bpage),
|
||||
(ulong) fil_page_get_type(frame),
|
||||
(ulong) buf_page_get_zip_size(bpage),
|
||||
(ulong) ut_dulint_get_low(
|
||||
@ -2201,8 +2449,7 @@ buf_LRU_print(void)
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "\nLRU pos %lu !state %lu!\n",
|
||||
(ulong) buf_page_get_LRU_position(bpage),
|
||||
fprintf(stderr, "\n!state %lu!\n",
|
||||
(ulong) buf_page_get_state(bpage));
|
||||
break;
|
||||
}
|
||||
|
@ -38,14 +38,6 @@ Created 11/5/1995 Heikki Tuuri
|
||||
#include "srv0start.h"
|
||||
#include "srv0srv.h"
|
||||
|
||||
/** The size in blocks of the area where the random read-ahead algorithm counts
|
||||
the accessed pages when deciding whether to read-ahead */
|
||||
#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA
|
||||
|
||||
/** There must be at least this many pages in buf_pool in the area to start
|
||||
a random read-ahead */
|
||||
#define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
|
||||
|
||||
/** The linear read-ahead area size */
|
||||
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
|
||||
|
||||
@ -62,8 +54,9 @@ flag is cleared and the x-lock released by an i/o-handler thread.
|
||||
@return 1 if a read request was queued, 0 if the page already resided
|
||||
in buf_pool, or if the page is in the doublewrite buffer blocks in
|
||||
which case it is never read into the pool, or if the tablespace does
|
||||
not exist or is being dropped */
|
||||
static
|
||||
not exist or is being dropped
|
||||
@return 1 if read request is issued. 0 if it is not */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
buf_read_page_low(
|
||||
/*==============*/
|
||||
@ -82,7 +75,8 @@ buf_read_page_low(
|
||||
treat the tablespace as dropped; this is a timestamp we
|
||||
use to stop dangling page reads from a tablespace
|
||||
which we have DISCARDed + IMPORTed back */
|
||||
ulint offset) /*!< in: page number */
|
||||
ulint offset, /*!< in: page number */
|
||||
trx_t* trx)
|
||||
{
|
||||
buf_page_t* bpage;
|
||||
ulint wake_later;
|
||||
@ -183,15 +177,15 @@ not_to_recover:
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
|
||||
if (zip_size) {
|
||||
*err = fil_io(OS_FILE_READ | wake_later,
|
||||
*err = _fil_io(OS_FILE_READ | wake_later,
|
||||
sync, space, zip_size, offset, 0, zip_size,
|
||||
bpage->zip.data, bpage);
|
||||
bpage->zip.data, bpage, trx);
|
||||
} else {
|
||||
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
|
||||
|
||||
*err = fil_io(OS_FILE_READ | wake_later,
|
||||
*err = _fil_io(OS_FILE_READ | wake_later,
|
||||
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
|
||||
((buf_block_t*) bpage)->frame, bpage);
|
||||
((buf_block_t*) bpage)->frame, bpage, trx);
|
||||
}
|
||||
ut_a(*err == DB_SUCCESS);
|
||||
|
||||
@ -204,207 +198,34 @@ not_to_recover:
|
||||
return(1);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Applies a random read-ahead in buf_pool if there are at least a threshold
|
||||
value of accessed pages from the random read-ahead area. Does not read any
|
||||
page, not even the one at the position (space, offset), if the read-ahead
|
||||
mechanism is not activated. NOTE 1: the calling thread may own latches on
|
||||
pages: to avoid deadlocks this function must be written such that it cannot
|
||||
end up waiting for these latches! NOTE 2: the calling thread must want
|
||||
access to the page given: this rule is set to prevent unintended read-aheads
|
||||
performed by ibuf routines, a situation which could result in a deadlock if
|
||||
the OS does not support asynchronous i/o.
|
||||
@return number of page read requests issued; NOTE that if we read ibuf
|
||||
pages, it may happen that the page at the given page number does not
|
||||
get read even if we return a positive value! */
|
||||
static
|
||||
ulint
|
||||
buf_read_ahead_random(
|
||||
/*==================*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset) /*!< in: page number of a page which the current thread
|
||||
wants to access */
|
||||
{
|
||||
ib_int64_t tablespace_version;
|
||||
ulint recent_blocks = 0;
|
||||
ulint count;
|
||||
ulint LRU_recent_limit;
|
||||
ulint ibuf_mode;
|
||||
ulint low, high;
|
||||
ulint err;
|
||||
ulint i;
|
||||
ulint buf_read_ahead_random_area;
|
||||
|
||||
// /* We have currently disabled random readahead */
|
||||
// return(0);
|
||||
|
||||
if (!(srv_read_ahead & 1)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (srv_startup_is_before_trx_rollback_phase) {
|
||||
/* No read-ahead to avoid thread deadlocks */
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (ibuf_bitmap_page(zip_size, offset)
|
||||
|| trx_sys_hdr_page(space, offset)) {
|
||||
|
||||
/* If it is an ibuf bitmap page or trx sys hdr, we do
|
||||
no read-ahead, as that could break the ibuf page access
|
||||
order */
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Remember the tablespace version before we ask te tablespace size
|
||||
below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
|
||||
do not try to read outside the bounds of the tablespace! */
|
||||
|
||||
tablespace_version = fil_space_get_version(space);
|
||||
|
||||
buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA;
|
||||
|
||||
low = (offset / buf_read_ahead_random_area)
|
||||
* buf_read_ahead_random_area;
|
||||
high = (offset / buf_read_ahead_random_area + 1)
|
||||
* buf_read_ahead_random_area;
|
||||
if (high > fil_space_get_size(space)) {
|
||||
|
||||
high = fil_space_get_size(space);
|
||||
}
|
||||
|
||||
/* Get the minimum LRU_position field value for an initial segment
|
||||
of the LRU list, to determine which blocks have recently been added
|
||||
to the start of the list. */
|
||||
|
||||
LRU_recent_limit = buf_LRU_get_recent_limit();
|
||||
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&buf_pool_mutex);
|
||||
|
||||
if (buf_pool->n_pend_reads
|
||||
> buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&buf_pool_mutex);
|
||||
|
||||
return(0);
|
||||
}
|
||||
mutex_exit(&buf_pool_mutex);
|
||||
|
||||
/* Count how many blocks in the area have been recently accessed,
|
||||
that is, reside near the start of the LRU list. */
|
||||
|
||||
rw_lock_s_lock(&page_hash_latch);
|
||||
for (i = low; i < high; i++) {
|
||||
const buf_page_t* bpage = buf_page_hash_get(space, i);
|
||||
|
||||
if (bpage
|
||||
&& buf_page_is_accessed(bpage)
|
||||
&& (buf_page_get_LRU_position(bpage) > LRU_recent_limit)) {
|
||||
|
||||
recent_blocks++;
|
||||
|
||||
if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
rw_lock_s_unlock(&page_hash_latch);
|
||||
goto read_ahead;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
rw_lock_s_unlock(&page_hash_latch);
|
||||
/* Do nothing */
|
||||
return(0);
|
||||
|
||||
read_ahead:
|
||||
/* Read all the suitable blocks within the area */
|
||||
|
||||
if (ibuf_inside()) {
|
||||
ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
|
||||
} else {
|
||||
ibuf_mode = BUF_READ_ANY_PAGE;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = low; i < high; i++) {
|
||||
/* It is only sensible to do read-ahead in the non-sync aio
|
||||
mode: hence FALSE as the first parameter */
|
||||
|
||||
if (!ibuf_bitmap_page(zip_size, i)) {
|
||||
count += buf_read_page_low(
|
||||
&err, FALSE,
|
||||
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
|
||||
space, zip_size, FALSE,
|
||||
tablespace_version, i);
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Warning: in random"
|
||||
" readahead trying to access\n"
|
||||
"InnoDB: tablespace %lu page %lu,\n"
|
||||
"InnoDB: but the tablespace does not"
|
||||
" exist or is just being dropped.\n",
|
||||
(ulong) space, (ulong) i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In simulated aio we wake the aio handler threads only after
|
||||
queuing all aio requests, in native aio the following call does
|
||||
nothing: */
|
||||
|
||||
os_aio_simulated_wake_handler_threads();
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (buf_debug_prints && (count > 0)) {
|
||||
fprintf(stderr,
|
||||
"Random read-ahead space %lu offset %lu pages %lu\n",
|
||||
(ulong) space, (ulong) offset,
|
||||
(ulong) count);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
++srv_read_ahead_rnd;
|
||||
return(count);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
High-level function which reads a page asynchronously from a file to the
|
||||
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
|
||||
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
|
||||
released by the i/o-handler thread. Does a random read-ahead if it seems
|
||||
sensible.
|
||||
@return number of page read requests issued: this can be greater than
|
||||
1 if read-ahead occurred */
|
||||
released by the i/o-handler thread.
|
||||
@return TRUE if page has been read in, FALSE in case of failure */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
ibool
|
||||
buf_read_page(
|
||||
/*==========*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset) /*!< in: page number */
|
||||
ulint offset, /*!< in: page number */
|
||||
trx_t* trx)
|
||||
{
|
||||
ib_int64_t tablespace_version;
|
||||
ulint count;
|
||||
ulint count2;
|
||||
ulint err;
|
||||
|
||||
tablespace_version = fil_space_get_version(space);
|
||||
|
||||
count = buf_read_ahead_random(space, zip_size, offset);
|
||||
|
||||
/* We do the i/o in the synchronous aio mode to save thread
|
||||
switches: hence TRUE */
|
||||
|
||||
count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
|
||||
count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
|
||||
zip_size, FALSE,
|
||||
tablespace_version, offset);
|
||||
srv_buf_pool_reads+= count2;
|
||||
tablespace_version, offset, trx);
|
||||
srv_buf_pool_reads += count;
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
@ -421,14 +242,14 @@ buf_read_page(
|
||||
/* Increment number of I/O operations used for LRU policy. */
|
||||
buf_LRU_stat_inc_io();
|
||||
|
||||
return(count + count2);
|
||||
return(count > 0);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Applies linear read-ahead if in the buf_pool the page is a border page of
|
||||
a linear read-ahead area and all the pages in the area have been accessed.
|
||||
Does not read any page if the read-ahead mechanism is not activated. Note
|
||||
that the the algorithm looks at the 'natural' adjacent successor and
|
||||
that the algorithm looks at the 'natural' adjacent successor and
|
||||
predecessor of the page, which on the leaf level of a B-tree are the next
|
||||
and previous page in the chain of leaves. To know these, the page specified
|
||||
in (space, offset) must already be present in the buf_pool. Thus, the
|
||||
@ -454,8 +275,9 @@ buf_read_ahead_linear(
|
||||
/*==================*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset) /*!< in: page number of a page; NOTE: the current thread
|
||||
ulint offset, /*!< in: page number of a page; NOTE: the current thread
|
||||
must want access to this page (see NOTE 3 above) */
|
||||
trx_t* trx)
|
||||
{
|
||||
ib_int64_t tablespace_version;
|
||||
buf_page_t* bpage;
|
||||
@ -557,9 +379,17 @@ buf_read_ahead_linear(
|
||||
fail_count++;
|
||||
|
||||
} else if (pred_bpage) {
|
||||
int res = (ut_ulint_cmp(
|
||||
buf_page_get_LRU_position(bpage),
|
||||
buf_page_get_LRU_position(pred_bpage)));
|
||||
/* Note that buf_page_is_accessed() returns
|
||||
the time of the first access. If some blocks
|
||||
of the extent existed in the buffer pool at
|
||||
the time of a linear access pattern, the first
|
||||
access times may be nonmonotonic, even though
|
||||
the latest access times were linear. The
|
||||
threshold (srv_read_ahead_factor) should help
|
||||
a little against this. */
|
||||
int res = ut_ulint_cmp(
|
||||
buf_page_is_accessed(bpage),
|
||||
buf_page_is_accessed(pred_bpage));
|
||||
/* Accesses not in the right order */
|
||||
if (res != 0 && res != asc_or_desc) {
|
||||
fail_count++;
|
||||
@ -670,7 +500,7 @@ buf_read_ahead_linear(
|
||||
count += buf_read_page_low(
|
||||
&err, FALSE,
|
||||
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
|
||||
space, zip_size, FALSE, tablespace_version, i);
|
||||
space, zip_size, FALSE, tablespace_version, i, trx);
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
@ -705,7 +535,7 @@ buf_read_ahead_linear(
|
||||
LRU policy decision. */
|
||||
buf_LRU_stat_inc_io();
|
||||
|
||||
++srv_read_ahead_seq;
|
||||
buf_pool->stat.n_ra_pages_read += count;
|
||||
return(count);
|
||||
}
|
||||
|
||||
@ -760,7 +590,7 @@ buf_read_ibuf_merge_pages(
|
||||
buf_read_page_low(&err, sync && (i + 1 == n_stored),
|
||||
BUF_READ_ANY_PAGE, space_ids[i],
|
||||
zip_size, TRUE, space_versions[i],
|
||||
page_nos[i]);
|
||||
page_nos[i], NULL);
|
||||
|
||||
if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
|
||||
tablespace_deleted:
|
||||
@ -857,12 +687,12 @@ buf_read_recv_pages(
|
||||
if ((i + 1 == n_stored) && sync) {
|
||||
buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
|
||||
zip_size, TRUE, tablespace_version,
|
||||
page_nos[i]);
|
||||
page_nos[i], NULL);
|
||||
} else {
|
||||
buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
|
||||
| OS_AIO_SIMULATED_WAKE_LATER,
|
||||
space, zip_size, TRUE,
|
||||
tablespace_version, page_nos[i]);
|
||||
tablespace_version, page_nos[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,6 +237,22 @@ dtype_print(
|
||||
fputs("DATA_SYS", stderr);
|
||||
break;
|
||||
|
||||
case DATA_FLOAT:
|
||||
fputs("DATA_FLOAT", stderr);
|
||||
break;
|
||||
|
||||
case DATA_DOUBLE:
|
||||
fputs("DATA_DOUBLE", stderr);
|
||||
break;
|
||||
|
||||
case DATA_DECIMAL:
|
||||
fputs("DATA_DECIMAL", stderr);
|
||||
break;
|
||||
|
||||
case DATA_VARMYSQL:
|
||||
fputs("DATA_VARMYSQL", stderr);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "type %lu", (ulong) mtype);
|
||||
break;
|
||||
|
@ -1387,7 +1387,7 @@ dict_create_add_foreign_field_to_dictionary(
|
||||
Add a single foreign key definition to the data dictionary tables in the
|
||||
database. We also generate names to constraints that were not named by the
|
||||
user. A generated constraint has a name of the format
|
||||
databasename/tablename_ibfk_<number>, where the numbers start from 1, and
|
||||
databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and
|
||||
are given locally for this table, that is, the number is not global, as in
|
||||
the old format constraints < 4.0.18 it used to be.
|
||||
@return error code or DB_SUCCESS */
|
||||
|
@ -82,9 +82,10 @@ static char dict_ibfk[] = "_ibfk_";
|
||||
|
||||
/*******************************************************************//**
|
||||
Tries to find column names for the index and sets the col field of the
|
||||
index. */
|
||||
index.
|
||||
@return TRUE if the column names were found */
|
||||
static
|
||||
void
|
||||
ibool
|
||||
dict_index_find_cols(
|
||||
/*=================*/
|
||||
dict_table_t* table, /*!< in: table */
|
||||
@ -1261,7 +1262,7 @@ dict_index_too_big_for_undo(
|
||||
= TRX_UNDO_PAGE_HDR - TRX_UNDO_PAGE_HDR_SIZE
|
||||
+ 2 /* next record pointer */
|
||||
+ 1 /* type_cmpl */
|
||||
+ 11 /* trx->undo_no */ - 11 /* table->id */
|
||||
+ 11 /* trx->undo_no */ + 11 /* table->id */
|
||||
+ 1 /* rec_get_info_bits() */
|
||||
+ 11 /* DB_TRX_ID */
|
||||
+ 11 /* DB_ROLL_PTR */
|
||||
@ -1440,7 +1441,11 @@ dict_index_too_big_for_tree(
|
||||
goto add_field_size;
|
||||
}
|
||||
|
||||
if (srv_relax_table_creation) {
|
||||
field_max_size = dict_col_get_min_size(col);
|
||||
} else {
|
||||
field_max_size = dict_col_get_max_size(col);
|
||||
}
|
||||
field_ext_max_size = field_max_size < 256 ? 1 : 2;
|
||||
|
||||
if (field->prefix_len) {
|
||||
@ -1493,7 +1498,7 @@ add_field_size:
|
||||
|
||||
/**********************************************************************//**
|
||||
Adds an index to the dictionary cache.
|
||||
@return DB_SUCCESS or DB_TOO_BIG_RECORD */
|
||||
@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
dict_index_add_to_cache(
|
||||
@ -1519,7 +1524,10 @@ dict_index_add_to_cache(
|
||||
ut_a(!dict_index_is_clust(index)
|
||||
|| UT_LIST_GET_LEN(table->indexes) == 0);
|
||||
|
||||
dict_index_find_cols(table, index);
|
||||
if (!dict_index_find_cols(table, index)) {
|
||||
|
||||
return(DB_CORRUPTION);
|
||||
}
|
||||
|
||||
/* Build the cache internal representation of the index,
|
||||
containing also the added system fields */
|
||||
@ -1732,9 +1740,10 @@ dict_index_remove_from_cache(
|
||||
|
||||
/*******************************************************************//**
|
||||
Tries to find column names for the index and sets the col field of the
|
||||
index. */
|
||||
index.
|
||||
@return TRUE if the column names were found */
|
||||
static
|
||||
void
|
||||
ibool
|
||||
dict_index_find_cols(
|
||||
/*=================*/
|
||||
dict_table_t* table, /*!< in: table */
|
||||
@ -1759,17 +1768,21 @@ dict_index_find_cols(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* It is an error not to find a matching column. */
|
||||
fputs("InnoDB: Error: no matching column for ", stderr);
|
||||
ut_print_name(stderr, NULL, FALSE, field->name);
|
||||
fputs(" in ", stderr);
|
||||
dict_index_name_print(stderr, NULL, index);
|
||||
fputs("!\n", stderr);
|
||||
ut_error;
|
||||
#endif /* UNIV_DEBUG */
|
||||
return(FALSE);
|
||||
|
||||
found:
|
||||
;
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
@ -4711,6 +4724,26 @@ dict_ind_init(void)
|
||||
dict_ind_redundant->cached = dict_ind_compact->cached = TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Frees dict_ind_redundant and dict_ind_compact. */
|
||||
static
|
||||
void
|
||||
dict_ind_free(void)
|
||||
/*===============*/
|
||||
{
|
||||
dict_table_t* table;
|
||||
|
||||
table = dict_ind_compact->table;
|
||||
dict_mem_index_free(dict_ind_compact);
|
||||
dict_ind_compact = NULL;
|
||||
dict_mem_table_free(table);
|
||||
|
||||
table = dict_ind_redundant->table;
|
||||
dict_mem_index_free(dict_ind_redundant);
|
||||
dict_ind_redundant = NULL;
|
||||
dict_mem_table_free(table);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**********************************************************************//**
|
||||
Get index by name
|
||||
@ -4836,4 +4869,55 @@ dict_table_check_for_dup_indexes(
|
||||
}
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/**************************************************************************
|
||||
Closes the data dictionary module. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_close(void)
|
||||
/*============*/
|
||||
{
|
||||
ulint i;
|
||||
|
||||
/* Free the hash elements. We don't remove them from the table
|
||||
because we are going to destroy the table anyway. */
|
||||
for (i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) {
|
||||
dict_table_t* table;
|
||||
|
||||
table = HASH_GET_FIRST(dict_sys->table_hash, i);
|
||||
|
||||
while (table) {
|
||||
dict_table_t* prev_table = table;
|
||||
|
||||
table = HASH_GET_NEXT(name_hash, prev_table);
|
||||
#ifdef UNIV_DEBUG
|
||||
ut_a(prev_table->magic_n == DICT_TABLE_MAGIC_N);
|
||||
#endif
|
||||
/* Acquire only because it's a pre-condition. */
|
||||
mutex_enter(&dict_sys->mutex);
|
||||
|
||||
dict_table_remove_from_cache(prev_table);
|
||||
|
||||
mutex_exit(&dict_sys->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
hash_table_free(dict_sys->table_hash);
|
||||
|
||||
/* The elements are the same instance as in dict_sys->table_hash,
|
||||
therefore we don't delete the individual elements. */
|
||||
hash_table_free(dict_sys->table_id_hash);
|
||||
|
||||
dict_ind_free();
|
||||
|
||||
mutex_free(&dict_sys->mutex);
|
||||
|
||||
rw_lock_free(&dict_operation_lock);
|
||||
memset(&dict_operation_lock, 0x0, sizeof(dict_operation_lock));
|
||||
|
||||
mutex_free(&dict_foreign_err_mutex);
|
||||
|
||||
mem_free(dict_sys);
|
||||
dict_sys = NULL;
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
@ -327,6 +327,17 @@ fil_get_space_id_for_table(
|
||||
/*=======================*/
|
||||
const char* name); /*!< in: table name in the standard
|
||||
'databasename/tablename' format */
|
||||
/*******************************************************************//**
|
||||
Frees a space object from the tablespace memory cache. Closes the files in
|
||||
the chain but does not delete them. There must not be any pending i/o's or
|
||||
flushes on the files. */
|
||||
static
|
||||
ibool
|
||||
fil_space_free(
|
||||
/*===========*/
|
||||
/* out: TRUE if success */
|
||||
ulint id, /* in: space id */
|
||||
ibool own_mutex);/* in: TRUE if own system->mutex */
|
||||
/********************************************************************//**
|
||||
Reads data from a space to a buffer. Remember that the possible incomplete
|
||||
blocks at the end of file are ignored: they are not taken into account when
|
||||
@ -600,6 +611,11 @@ fil_node_create(
|
||||
|
||||
UT_LIST_ADD_LAST(chain, space->chain, node);
|
||||
|
||||
if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
|
||||
|
||||
fil_system->max_assigned_id = id;
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
|
||||
@ -619,12 +635,10 @@ fil_node_open_file(
|
||||
ulint size_high;
|
||||
ibool ret;
|
||||
ibool success;
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
byte* buf2;
|
||||
byte* page;
|
||||
ulint space_id;
|
||||
ulint flags;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
ut_ad(mutex_own(&(system->mutex)));
|
||||
ut_a(node->n_pending == 0);
|
||||
@ -660,9 +674,12 @@ fil_node_open_file(
|
||||
size_bytes = (((ib_int64_t)size_high) << 32)
|
||||
+ (ib_int64_t)size_low;
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
if (space->id == 0) {
|
||||
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
|
||||
/* TODO: adjust to zip_size, like below? */
|
||||
#else
|
||||
os_file_close(node->handle);
|
||||
goto add_size;
|
||||
}
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
ut_a(space->purpose != FIL_LOG);
|
||||
ut_a(space->id != 0);
|
||||
|
||||
@ -741,7 +758,10 @@ fil_node_open_file(
|
||||
(size_bytes
|
||||
/ dict_table_flags_to_zip_size(flags));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
add_size:
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
space->size += node->size;
|
||||
}
|
||||
|
||||
@ -961,7 +981,7 @@ close_more:
|
||||
" while the maximum\n"
|
||||
"InnoDB: allowed value would be %lu.\n"
|
||||
"InnoDB: You may need to raise the value of"
|
||||
" innodb_max_files_open in\n"
|
||||
" innodb_open_files in\n"
|
||||
"InnoDB: my.cnf.\n",
|
||||
(ulong) fil_system->n_open,
|
||||
(ulong) fil_system->max_n_open);
|
||||
@ -1141,7 +1161,7 @@ try_again:
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
fil_space_free(namesake_id);
|
||||
fil_space_free(namesake_id, FALSE);
|
||||
|
||||
goto try_again;
|
||||
}
|
||||
@ -1266,17 +1286,21 @@ Frees a space object from the tablespace memory cache. Closes the files in
|
||||
the chain but does not delete them. There must not be any pending i/o's or
|
||||
flushes on the files.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
static
|
||||
ibool
|
||||
fil_space_free(
|
||||
/*===========*/
|
||||
ulint id) /*!< in: space id */
|
||||
/* out: TRUE if success */
|
||||
ulint id, /* in: space id */
|
||||
ibool own_mutex) /* in: TRUE if own system->mutex */
|
||||
{
|
||||
fil_space_t* space;
|
||||
fil_space_t* namespace;
|
||||
fil_node_t* fil_node;
|
||||
|
||||
if (!own_mutex) {
|
||||
mutex_enter(&fil_system->mutex);
|
||||
}
|
||||
|
||||
space = fil_space_get_by_id(id);
|
||||
|
||||
@ -1323,7 +1347,9 @@ fil_space_free(
|
||||
|
||||
ut_a(0 == UT_LIST_GET_LEN(space->chain));
|
||||
|
||||
if (!own_mutex) {
|
||||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
|
||||
rw_lock_free(&(space->latch));
|
||||
|
||||
@ -1541,7 +1567,7 @@ fil_open_log_and_system_tablespace_files(void)
|
||||
fprintf(stderr,
|
||||
"InnoDB: Warning: you must"
|
||||
" raise the value of"
|
||||
" innodb_max_open_files in\n"
|
||||
" innodb_open_files in\n"
|
||||
"InnoDB: my.cnf! Remember that"
|
||||
" InnoDB keeps all log files"
|
||||
" and all system\n"
|
||||
@ -1583,6 +1609,8 @@ fil_close_all_files(void)
|
||||
space = UT_LIST_GET_FIRST(fil_system->space_list);
|
||||
|
||||
while (space != NULL) {
|
||||
fil_space_t* prev_space = space;
|
||||
|
||||
node = UT_LIST_GET_FIRST(space->chain);
|
||||
|
||||
while (node != NULL) {
|
||||
@ -1592,6 +1620,7 @@ fil_close_all_files(void)
|
||||
node = UT_LIST_GET_NEXT(chain, node);
|
||||
}
|
||||
space = UT_LIST_GET_NEXT(space_list, space);
|
||||
fil_space_free(prev_space->id, TRUE);
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
@ -2223,7 +2252,7 @@ try_again:
|
||||
#endif
|
||||
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
|
||||
|
||||
success = fil_space_free(id);
|
||||
success = fil_space_free(id, FALSE);
|
||||
|
||||
if (success) {
|
||||
success = os_file_delete(path);
|
||||
@ -2929,7 +2958,6 @@ fil_open_single_table_tablespace(
|
||||
byte* page;
|
||||
ulint space_id;
|
||||
ulint space_flags;
|
||||
ibool ret = TRUE;
|
||||
|
||||
filepath = fil_make_ibd_name(name, FALSE);
|
||||
|
||||
@ -3330,7 +3358,7 @@ skip_write:
|
||||
(ulong) space_id, (ulong) space_flags,
|
||||
(ulong) id, (ulong) flags);
|
||||
|
||||
ret = FALSE;
|
||||
success = FALSE;
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
@ -3350,7 +3378,7 @@ func_exit:
|
||||
os_file_close(file);
|
||||
mem_free(filepath);
|
||||
|
||||
return(ret);
|
||||
return(success);
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
@ -3566,7 +3594,7 @@ fil_load_single_table_tablespace(
|
||||
fprintf(stderr,
|
||||
"InnoDB: Renaming tablespace %s of id %lu,\n"
|
||||
"InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
|
||||
"InnoDB: because its size %lld is too small"
|
||||
"InnoDB: because its size %" PRId64 " is too small"
|
||||
" (< 4 pages 16 kB each),\n"
|
||||
"InnoDB: or the space id in the file header"
|
||||
" is not sensible.\n"
|
||||
@ -3628,9 +3656,19 @@ fil_load_single_table_tablespace(
|
||||
|
||||
if (!success) {
|
||||
|
||||
if (srv_force_recovery > 0) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: innodb_force_recovery"
|
||||
" was set to %lu. Continuing crash recovery\n"
|
||||
"InnoDB: even though the tablespace creation"
|
||||
" of this table failed.\n",
|
||||
srv_force_recovery);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* We do not use the size information we have about the file, because
|
||||
the rounding formula for extents and pages is somewhat complex; we
|
||||
let fil_node_open() do that task. */
|
||||
@ -4163,7 +4201,7 @@ fil_extend_space_to_desired_size(
|
||||
node->name, node->handle, buf,
|
||||
offset_low, offset_high,
|
||||
page_size * n_pages,
|
||||
NULL, NULL);
|
||||
NULL, NULL, NULL);
|
||||
#endif
|
||||
if (success) {
|
||||
node->size += n_pages;
|
||||
@ -4490,7 +4528,7 @@ Reads or writes data. This operation is asynchronous (aio).
|
||||
i/o on a tablespace which does not exist */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
fil_io(
|
||||
_fil_io(
|
||||
/*===*/
|
||||
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
|
||||
ORed to OS_FILE_LOG, if a log i/o
|
||||
@ -4515,8 +4553,9 @@ fil_io(
|
||||
void* buf, /*!< in/out: buffer where to store read data
|
||||
or from where to write; in aio this must be
|
||||
appropriately aligned */
|
||||
void* message) /*!< in: message for aio handler if non-sync
|
||||
void* message, /*!< in: message for aio handler if non-sync
|
||||
aio used, else ignored */
|
||||
trx_t* trx)
|
||||
{
|
||||
ulint mode;
|
||||
fil_space_t* space;
|
||||
@ -4686,7 +4725,7 @@ fil_io(
|
||||
#else
|
||||
/* Queue the aio request */
|
||||
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
|
||||
offset_low, offset_high, len, node, message);
|
||||
offset_low, offset_high, len, node, message, trx);
|
||||
#endif
|
||||
ut_a(ret);
|
||||
|
||||
@ -4706,6 +4745,78 @@ fil_io(
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Confirm whether the parameters are valid or not */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
fil_area_is_exist(
|
||||
/*==============*/
|
||||
ulint space_id, /*!< in: space id */
|
||||
ulint zip_size, /*!< in: compressed page size in bytes;
|
||||
0 for uncompressed pages */
|
||||
ulint block_offset, /*!< in: offset in number of blocks */
|
||||
ulint byte_offset, /*!< in: remainder of offset in bytes; in
|
||||
aio this must be divisible by the OS block
|
||||
size */
|
||||
ulint len) /*!< in: how many bytes to read or write; this
|
||||
must not cross a file boundary; in aio this
|
||||
must be a block size multiple */
|
||||
{
|
||||
fil_space_t* space;
|
||||
fil_node_t* node;
|
||||
|
||||
/* Reserve the fil_system mutex and make sure that we can open at
|
||||
least one file while holding it, if the file is not already open */
|
||||
|
||||
fil_mutex_enter_and_prepare_for_io(space_id);
|
||||
|
||||
space = fil_space_get_by_id(space_id);
|
||||
|
||||
if (!space) {
|
||||
mutex_exit(&fil_system->mutex);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
node = UT_LIST_GET_FIRST(space->chain);
|
||||
|
||||
for (;;) {
|
||||
if (UNIV_UNLIKELY(node == NULL)) {
|
||||
mutex_exit(&fil_system->mutex);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (space->id != 0 && node->size == 0) {
|
||||
/* We do not know the size of a single-table tablespace
|
||||
before we open the file */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (node->size > block_offset) {
|
||||
/* Found! */
|
||||
break;
|
||||
} else {
|
||||
block_offset -= node->size;
|
||||
node = UT_LIST_GET_NEXT(chain, node);
|
||||
}
|
||||
}
|
||||
|
||||
/* Open file if closed */
|
||||
fil_node_prepare_for_io(node, fil_system, space);
|
||||
fil_node_complete_io(node, fil_system, OS_FILE_READ);
|
||||
|
||||
/* Check that at least the start offset is within the bounds of a
|
||||
single-table tablespace */
|
||||
if (UNIV_UNLIKELY(node->size <= block_offset)
|
||||
&& space->id != 0 && space->purpose == FIL_TABLESPACE) {
|
||||
mutex_exit(&fil_system->mutex);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**********************************************************************//**
|
||||
Waits for an aio operation to complete. This function is used to write the
|
||||
@ -5065,6 +5176,29 @@ fil_page_get_type(
|
||||
return(mach_read_from_2(page + FIL_PAGE_TYPE));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Initializes the tablespace memory cache. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_close(void)
|
||||
/*===========*/
|
||||
{
|
||||
/* The mutex should already have been freed. */
|
||||
ut_ad(fil_system->mutex.magic_n == 0);
|
||||
|
||||
hash_table_free(fil_system->spaces);
|
||||
|
||||
hash_table_free(fil_system->name_hash);
|
||||
|
||||
ut_a(UT_LIST_GET_LEN(fil_system->LRU) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(fil_system->unflushed_spaces) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(fil_system->space_list) == 0);
|
||||
|
||||
mem_free(fil_system);
|
||||
|
||||
fil_system = NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Return local hash table informations. */
|
||||
|
||||
|
@ -232,6 +232,9 @@ the extent are free and which contain old tuple version to clean. */
|
||||
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/* Flag to indicate if we have printed the tablespace full error. */
|
||||
static ibool fsp_tbs_full_error_printed = FALSE;
|
||||
|
||||
/**********************************************************************//**
|
||||
Returns an extent to the free list of a space. */
|
||||
static
|
||||
@ -1099,7 +1102,7 @@ fsp_header_inc_size(
|
||||
|
||||
/**********************************************************************//**
|
||||
Gets the current free limit of the system tablespace. The free limit
|
||||
means the place of the first page which has never been put to the the
|
||||
means the place of the first page which has never been put to the
|
||||
free list for allocation. The space above that address is initialized
|
||||
to zero. Sets also the global variable log_fsp_current_free_limit.
|
||||
@return free limit in megabytes */
|
||||
@ -1218,6 +1221,19 @@ fsp_try_extend_data_file(
|
||||
|
||||
if (space == 0 && !srv_auto_extend_last_data_file) {
|
||||
|
||||
/* We print the error message only once to avoid
|
||||
spamming the error log. Note that we don't need
|
||||
to reset the flag to FALSE as dealing with this
|
||||
error requires server restart. */
|
||||
if (fsp_tbs_full_error_printed == FALSE) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: Data file(s) ran"
|
||||
" out of space.\n"
|
||||
"Please add another data file or"
|
||||
" use \'autoextend\' for the last"
|
||||
" data file.\n");
|
||||
fsp_tbs_full_error_printed = TRUE;
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
@ -1832,6 +1848,8 @@ fsp_seg_inode_page_find_used(
|
||||
if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
|
||||
/* This is used */
|
||||
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
|
||||
== FSEG_MAGIC_N_VALUE);
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
@ -1863,6 +1881,9 @@ fsp_seg_inode_page_find_free(
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
|
||||
== FSEG_MAGIC_N_VALUE);
|
||||
}
|
||||
|
||||
return(ULINT_UNDEFINED);
|
||||
@ -1981,6 +2002,8 @@ fsp_alloc_seg_inode(
|
||||
page + FSEG_INODE_PAGE_NODE, mtr);
|
||||
}
|
||||
|
||||
ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))
|
||||
|| mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||
return(inode);
|
||||
}
|
||||
|
||||
@ -2018,7 +2041,7 @@ fsp_free_seg_inode(
|
||||
}
|
||||
|
||||
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
|
||||
mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
|
||||
mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr);
|
||||
|
||||
if (ULINT_UNDEFINED
|
||||
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
|
||||
@ -2034,11 +2057,11 @@ fsp_free_seg_inode(
|
||||
|
||||
/**********************************************************************//**
|
||||
Returns the file segment inode, page x-latched.
|
||||
@return segment inode, page x-latched */
|
||||
@return segment inode, page x-latched; NULL if the inode is free */
|
||||
static
|
||||
fseg_inode_t*
|
||||
fseg_inode_get(
|
||||
/*===========*/
|
||||
fseg_inode_try_get(
|
||||
/*===============*/
|
||||
fseg_header_t* header, /*!< in: segment header */
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes
|
||||
@ -2054,8 +2077,34 @@ fseg_inode_get(
|
||||
|
||||
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
|
||||
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||
if (UNIV_UNLIKELY
|
||||
(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
|
||||
|
||||
inode = NULL;
|
||||
} else {
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
|
||||
== FSEG_MAGIC_N_VALUE);
|
||||
}
|
||||
|
||||
return(inode);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Returns the file segment inode, page x-latched.
|
||||
@return segment inode, page x-latched */
|
||||
static
|
||||
fseg_inode_t*
|
||||
fseg_inode_get(
|
||||
/*===========*/
|
||||
fseg_header_t* header, /*!< in: segment header */
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes
|
||||
or 0 for uncompressed pages */
|
||||
mtr_t* mtr) /*!< in: mtr handle */
|
||||
{
|
||||
fseg_inode_t* inode
|
||||
= fseg_inode_try_get(header, space, zip_size, mtr);
|
||||
ut_a(inode);
|
||||
return(inode);
|
||||
}
|
||||
|
||||
@ -2073,6 +2122,7 @@ fseg_get_nth_frag_page_no(
|
||||
ut_ad(inode && mtr);
|
||||
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
|
||||
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||
return(mach_read_from_4(inode + FSEG_FRAG_ARR
|
||||
+ n * FSEG_FRAG_SLOT_SIZE));
|
||||
}
|
||||
@ -2091,6 +2141,7 @@ fseg_set_nth_frag_page_no(
|
||||
ut_ad(inode && mtr);
|
||||
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
|
||||
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||
|
||||
mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
|
||||
page_no, MLOG_4BYTES, mtr);
|
||||
@ -2451,6 +2502,8 @@ fseg_fill_free_list(
|
||||
xdes_set_state(descr, XDES_FSEG, mtr);
|
||||
|
||||
seg_id = mtr_read_dulint(inode + FSEG_ID, mtr);
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
|
||||
== FSEG_MAGIC_N_VALUE);
|
||||
mlog_write_dulint(descr + XDES_ID, seg_id, mtr);
|
||||
|
||||
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
|
||||
@ -2479,6 +2532,7 @@ fseg_alloc_free_extent(
|
||||
fil_addr_t first;
|
||||
|
||||
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||
|
||||
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
|
||||
/* Segment free list is not empty, allocate from it */
|
||||
@ -3136,6 +3190,8 @@ fseg_mark_page_used(
|
||||
|
||||
ut_ad(seg_inode && mtr);
|
||||
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
|
||||
== FSEG_MAGIC_N_VALUE);
|
||||
|
||||
descr = xdes_get_descriptor(space, zip_size, page, mtr);
|
||||
|
||||
@ -3373,6 +3429,8 @@ fseg_free_extent(
|
||||
ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
|
||||
ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
|
||||
mtr_read_dulint(seg_inode + FSEG_ID, mtr)));
|
||||
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
|
||||
== FSEG_MAGIC_N_VALUE);
|
||||
|
||||
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
|
||||
|
||||
@ -3463,7 +3521,13 @@ fseg_free_step(
|
||||
ut_a(descr);
|
||||
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
|
||||
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
|
||||
inode = fseg_inode_get(header, space, zip_size, mtr);
|
||||
inode = fseg_inode_try_get(header, space, zip_size, mtr);
|
||||
|
||||
if (UNIV_UNLIKELY(inode == NULL)) {
|
||||
fprintf(stderr, "double free of inode from %u:%u\n",
|
||||
(unsigned) space, (unsigned) header_page);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
|
||||
|
||||
@ -3587,6 +3651,7 @@ fseg_get_first_extent(
|
||||
ut_ad(inode && mtr);
|
||||
|
||||
ut_ad(space == page_get_space_id(page_align(inode)));
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||
|
||||
first = fil_addr_null;
|
||||
|
||||
@ -3801,6 +3866,7 @@ fseg_print_low(
|
||||
(ulong) reserved, (ulong) used, (ulong) n_full,
|
||||
(ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
|
||||
(ulong) n_used);
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||
}
|
||||
|
||||
#ifdef UNIV_BTR_PRINT
|
||||
|
@ -79,6 +79,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
/* Include necessary InnoDB headers */
|
||||
extern "C" {
|
||||
#include "univ.i"
|
||||
#include "buf0lru.h"
|
||||
#include "btr0sea.h"
|
||||
#include "os0file.h"
|
||||
#include "os0thread.h"
|
||||
@ -111,7 +112,6 @@ extern "C" {
|
||||
|
||||
#include "ha_innodb.h"
|
||||
#include "i_s.h"
|
||||
#include "handler0vars.h"
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
// Defined in trx0sys.c
|
||||
@ -122,9 +122,12 @@ extern ib_int64_t trx_sys_mysql_relay_log_pos;
|
||||
#endif /* MYSQL_SERVER */
|
||||
|
||||
#ifndef MYSQL_SERVER
|
||||
# ifndef MYSQL_PLUGIN_IMPORT
|
||||
# define MYSQL_PLUGIN_IMPORT /* nothing */
|
||||
# endif /* MYSQL_PLUGIN_IMPORT */
|
||||
/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
|
||||
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
|
||||
extern pthread_mutex_t LOCK_thread_count;
|
||||
extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
|
||||
|
||||
#if MYSQL_VERSION_ID < 50124
|
||||
/* this is defined in mysql_priv.h inside #ifdef MYSQL_SERVER
|
||||
@ -148,13 +151,9 @@ static bool innodb_inited = 0;
|
||||
|
||||
/* In the Windows plugin, the return value of current_thd is
|
||||
undefined. Map it to NULL. */
|
||||
#if defined MYSQL_DYNAMIC_PLUGIN && defined __WIN__
|
||||
# undef current_thd
|
||||
# define current_thd NULL
|
||||
# define EQ_CURRENT_THD(thd) TRUE
|
||||
#else /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
|
||||
|
||||
#define EQ_CURRENT_THD(thd) ((thd) == current_thd)
|
||||
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
|
||||
|
||||
|
||||
static struct handlerton* innodb_hton_ptr;
|
||||
|
||||
@ -174,6 +173,10 @@ static ulong innobase_write_io_threads;
|
||||
static my_bool innobase_thread_concurrency_timer_based;
|
||||
static long long innobase_buffer_pool_size, innobase_log_file_size;
|
||||
|
||||
/** Percentage of the buffer pool to reserve for 'old' blocks.
|
||||
Connected to buf_LRU_old_ratio. */
|
||||
static uint innobase_old_blocks_pct;
|
||||
|
||||
/* The default values for the following char* start-up parameters
|
||||
are determined in innobase_init below: */
|
||||
|
||||
@ -188,9 +191,7 @@ file formats in the configuration file, but can only be set to any
|
||||
of the supported file formats during runtime. */
|
||||
static char* innobase_file_format_check = NULL;
|
||||
|
||||
/* The following has a misleading name: starting from 4.0.5, this also
|
||||
affects Windows: */
|
||||
static char* innobase_unix_file_flush_method = NULL;
|
||||
static char* innobase_file_flush_method = NULL;
|
||||
|
||||
/* Below we have boolean-valued start-up parameters, and their default
|
||||
values */
|
||||
@ -204,7 +205,7 @@ static my_bool innobase_use_doublewrite = TRUE;
|
||||
static my_bool innobase_use_checksums = TRUE;
|
||||
static my_bool innobase_extra_undoslots = FALSE;
|
||||
static my_bool innobase_fast_recovery = FALSE;
|
||||
static my_bool innobase_use_purge_thread = FALSE;
|
||||
static my_bool innobase_recovery_stats = TRUE;
|
||||
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
|
||||
static my_bool innobase_overwrite_relay_log_info = FALSE;
|
||||
static my_bool innobase_rollback_on_timeout = FALSE;
|
||||
@ -287,10 +288,10 @@ innobase_file_format_check_on_off(
|
||||
/************************************************************//**
|
||||
Validate the file format check config parameters, as a side effect it
|
||||
sets the srv_check_file_format_at_startup variable.
|
||||
@return true if valid config value */
|
||||
@return the format_id if valid config value, otherwise, return -1 */
|
||||
static
|
||||
bool
|
||||
innobase_file_format_check_validate(
|
||||
int
|
||||
innobase_file_format_validate_and_set(
|
||||
/*================================*/
|
||||
const char* format_check); /*!< in: parameter value */
|
||||
/****************************************************************//**
|
||||
@ -521,10 +522,10 @@ static SHOW_VAR innodb_status_variables[]= {
|
||||
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
|
||||
{"buffer_pool_pages_total",
|
||||
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
|
||||
{"buffer_pool_read_ahead_rnd",
|
||||
(char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
|
||||
{"buffer_pool_read_ahead_seq",
|
||||
(char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
|
||||
{"buffer_pool_read_ahead",
|
||||
(char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG},
|
||||
{"buffer_pool_read_ahead_evicted",
|
||||
(char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
|
||||
{"buffer_pool_read_requests",
|
||||
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
|
||||
{"buffer_pool_reads",
|
||||
@ -805,11 +806,20 @@ convert_error_code_to_mysql(
|
||||
case DB_SUCCESS:
|
||||
return(0);
|
||||
|
||||
case DB_INTERRUPTED:
|
||||
my_error(ER_QUERY_INTERRUPTED, MYF(0));
|
||||
/* fall through */
|
||||
case DB_ERROR:
|
||||
default:
|
||||
return(-1); /* unspecified error */
|
||||
|
||||
case DB_DUPLICATE_KEY:
|
||||
/* Be cautious with returning this error, since
|
||||
mysql could re-enter the storage layer to get
|
||||
duplicated key info, the operation requires a
|
||||
valid table handle and/or transaction information,
|
||||
which might not always be available in the error
|
||||
handling stage. */
|
||||
return(HA_ERR_FOUND_DUPP_KEY);
|
||||
|
||||
case DB_FOREIGN_DUPLICATE_KEY:
|
||||
@ -896,17 +906,14 @@ convert_error_code_to_mysql(
|
||||
return(ER_PRIMARY_CANT_HAVE_NULL);
|
||||
|
||||
case DB_TOO_MANY_CONCURRENT_TRXS:
|
||||
/* Once MySQL add the appropriate code to errmsg.txt then
|
||||
we can get rid of this #ifdef. NOTE: The code checked by
|
||||
the #ifdef is the suggested name for the error condition
|
||||
and the actual error code name could very well be different.
|
||||
This will require some monitoring, ie. the status
|
||||
of this request on our part.*/
|
||||
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
|
||||
return(ER_TOO_MANY_CONCURRENT_TRXS);
|
||||
#else
|
||||
/* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
|
||||
available in 5.1.38 and later, but the plugin should still
|
||||
work with previous versions of MySQL. */
|
||||
#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
|
||||
return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
|
||||
#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
|
||||
return(HA_ERR_RECORD_FILE_FULL);
|
||||
#endif
|
||||
#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
|
||||
case DB_UNSUPPORTED:
|
||||
return(HA_ERR_UNSUPPORTED);
|
||||
}
|
||||
@ -980,7 +987,23 @@ innobase_get_cset_width(
|
||||
*mbminlen = cs->mbminlen;
|
||||
*mbmaxlen = cs->mbmaxlen;
|
||||
} else {
|
||||
THD* thd = current_thd;
|
||||
|
||||
if (thd && thd_sql_command(thd) == SQLCOM_DROP_TABLE) {
|
||||
|
||||
/* Fix bug#46256: allow tables to be dropped if the
|
||||
collation is not found, but issue a warning. */
|
||||
if ((global_system_variables.log_warnings)
|
||||
&& (cset != 0)){
|
||||
|
||||
sql_print_warning(
|
||||
"Unknown collation #%lu.", cset);
|
||||
}
|
||||
} else {
|
||||
|
||||
ut_a(cset == 0);
|
||||
}
|
||||
|
||||
*mbminlen = *mbmaxlen = 0;
|
||||
}
|
||||
}
|
||||
@ -1054,6 +1077,7 @@ innobase_get_charset(
|
||||
}
|
||||
|
||||
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
|
||||
extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
|
||||
/*******************************************************************//**
|
||||
Map an OS error to an errno value. The OS error number is stored in
|
||||
_doserrno and the mapped value is stored in errno) */
|
||||
@ -1341,6 +1365,16 @@ innobase_trx_init(
|
||||
trx->check_unique_secondary = !thd_test_options(
|
||||
thd, OPTION_RELAXED_UNIQUE_CHECKS);
|
||||
|
||||
#ifdef EXTENDED_SLOWLOG
|
||||
if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) {
|
||||
trx->take_stats = TRUE;
|
||||
} else {
|
||||
trx->take_stats = FALSE;
|
||||
}
|
||||
#else
|
||||
trx->take_stats = FALSE;
|
||||
#endif
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -1397,6 +1431,32 @@ check_trx_exists(
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Gets current trx. */
|
||||
extern "C"
|
||||
trx_t*
|
||||
innobase_get_trx()
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
if (likely(thd != 0)) {
|
||||
trx_t*& trx = thd_to_trx(thd);
|
||||
return(trx);
|
||||
} else {
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
ibool
|
||||
innobase_get_slow_log()
|
||||
{
|
||||
#ifdef EXTENDED_SLOWLOG
|
||||
return((ibool) thd_opt_slow_log());
|
||||
#else
|
||||
return(FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Construct ha_innobase handler. */
|
||||
UNIV_INTERN
|
||||
@ -1713,15 +1773,19 @@ innobase_convert_identifier(
|
||||
FALSE=id is an UTF-8 string */
|
||||
{
|
||||
char nz[NAME_LEN + 1];
|
||||
#if MYSQL_VERSION_ID >= 50141
|
||||
char nz2[NAME_LEN + 1 + EXPLAIN_FILENAME_MAX_EXTRA_LENGTH];
|
||||
#else /* MYSQL_VERSION_ID >= 50141 */
|
||||
char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
|
||||
#endif /* MYSQL_VERSION_ID >= 50141 */
|
||||
|
||||
const char* s = id;
|
||||
int q;
|
||||
|
||||
if (file_id) {
|
||||
/* Decode the table name. The filename_to_tablename()
|
||||
function expects a NUL-terminated string. The input and
|
||||
output strings buffers must not be shared. */
|
||||
/* Decode the table name. The MySQL function expects
|
||||
a NUL-terminated string. The input and output strings
|
||||
buffers must not be shared. */
|
||||
|
||||
if (UNIV_UNLIKELY(idlen > (sizeof nz) - 1)) {
|
||||
idlen = (sizeof nz) - 1;
|
||||
@ -1731,7 +1795,13 @@ innobase_convert_identifier(
|
||||
nz[idlen] = 0;
|
||||
|
||||
s = nz2;
|
||||
#if MYSQL_VERSION_ID >= 50141
|
||||
idlen = explain_filename((THD*) thd, nz, nz2, sizeof nz2,
|
||||
EXPLAIN_PARTITIONS_AS_COMMENT);
|
||||
goto no_quote;
|
||||
#else /* MYSQL_VERSION_ID >= 50141 */
|
||||
idlen = filename_to_tablename(nz, nz2, sizeof nz2);
|
||||
#endif /* MYSQL_VERSION_ID >= 50141 */
|
||||
}
|
||||
|
||||
/* See if the identifier needs to be quoted. */
|
||||
@ -1742,6 +1812,9 @@ innobase_convert_identifier(
|
||||
}
|
||||
|
||||
if (q == EOF) {
|
||||
#if MYSQL_VERSION_ID >= 50141
|
||||
no_quote:
|
||||
#endif /* MYSQL_VERSION_ID >= 50141 */
|
||||
if (UNIV_UNLIKELY(idlen > buflen)) {
|
||||
idlen = buflen;
|
||||
}
|
||||
@ -2224,8 +2297,8 @@ mem_free_and_error:
|
||||
/* Did the user specify a format name that we support ?
|
||||
As a side effect it will update the variable
|
||||
srv_check_file_format_at_startup */
|
||||
if (!innobase_file_format_check_validate(
|
||||
innobase_file_format_check)) {
|
||||
if (innobase_file_format_validate_and_set(
|
||||
innobase_file_format_check) < 0) {
|
||||
|
||||
sql_print_error("InnoDB: invalid "
|
||||
"innodb_file_format_check value: "
|
||||
@ -2266,7 +2339,7 @@ innobase_change_buffering_inited_ok:
|
||||
|
||||
/* --------------------------------------------------*/
|
||||
|
||||
srv_file_flush_method_str = innobase_unix_file_flush_method;
|
||||
srv_file_flush_method_str = innobase_file_flush_method;
|
||||
|
||||
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
|
||||
srv_n_log_files = (ulint) innobase_log_files_in_group;
|
||||
@ -2294,8 +2367,7 @@ innobase_change_buffering_inited_ok:
|
||||
srv_force_recovery = (ulint) innobase_force_recovery;
|
||||
|
||||
srv_fast_recovery = (ibool) innobase_fast_recovery;
|
||||
|
||||
srv_use_purge_thread = (ibool) innobase_use_purge_thread;
|
||||
srv_recovery_stats = (ibool) innobase_recovery_stats;
|
||||
|
||||
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
|
||||
srv_use_checksums = (ibool) innobase_use_checksums;
|
||||
@ -2331,6 +2403,9 @@ innobase_change_buffering_inited_ok:
|
||||
ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
|
||||
srv_latin1_ordering = my_charset_latin1.sort_order;
|
||||
|
||||
innobase_old_blocks_pct = buf_LRU_old_ratio_update(
|
||||
innobase_old_blocks_pct, FALSE);
|
||||
|
||||
innobase_commit_concurrency_init_default();
|
||||
|
||||
/* Since we in this module access directly the fields of a trx
|
||||
@ -2512,7 +2587,10 @@ innobase_alter_table_flags(
|
||||
{
|
||||
return(HA_ONLINE_ADD_INDEX_NO_WRITES
|
||||
| HA_ONLINE_DROP_INDEX_NO_WRITES
|
||||
| HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES
|
||||
/* Current InnoDB doesn't sort unique indexes along mysqld's order
|
||||
It is dangerous to use index. So it is disabled until
|
||||
the bug http://bugs.mysql.com/47622 */
|
||||
/* | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES */
|
||||
| HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES
|
||||
| HA_ONLINE_ADD_PK_INDEX_NO_WRITES);
|
||||
}
|
||||
@ -2678,6 +2756,19 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
/* The following calls to read the MySQL binary log
|
||||
file name and the position return consistent results:
|
||||
1) Other InnoDB transactions cannot intervene between
|
||||
these calls as we are holding prepare_commit_mutex.
|
||||
2) Binary logging of other engines is not relevant
|
||||
to InnoDB as all InnoDB requires is that committing
|
||||
InnoDB transactions appear in the same order in the
|
||||
MySQL binary log as they appear in InnoDB logs.
|
||||
3) A MySQL log file rotation cannot happen because
|
||||
MySQL protects against this by having a counter of
|
||||
transactions in prepared state and it only allows
|
||||
a rotation when the counter drops to zero. See
|
||||
LOCK_prep_xids and COND_prep_xids in log.cc. */
|
||||
trx->mysql_log_file_name = mysql_bin_log_file_name();
|
||||
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
|
||||
|
||||
@ -2763,6 +2854,8 @@ innobase_rollback(
|
||||
|
||||
innobase_release_stat_resources(trx);
|
||||
|
||||
trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
|
||||
|
||||
/* If we had reserved the auto-inc lock for some table (if
|
||||
we come here to roll back the latest SQL statement) we
|
||||
release it now before a possibly lengthy rollback */
|
||||
@ -3324,7 +3417,7 @@ retry:
|
||||
|
||||
if (is_part) {
|
||||
sql_print_error("Failed to open table %s after "
|
||||
"%lu attemtps.\n", norm_name,
|
||||
"%lu attempts.\n", norm_name,
|
||||
retries);
|
||||
}
|
||||
|
||||
@ -3928,7 +4021,6 @@ ha_innobase::store_key_val_for_row(
|
||||
as BLOB data in innodb. */
|
||||
|| mysql_type == MYSQL_TYPE_GEOMETRY) {
|
||||
|
||||
|
||||
CHARSET_INFO* cs;
|
||||
ulint key_len;
|
||||
ulint true_len;
|
||||
@ -5229,6 +5321,11 @@ ha_innobase::index_read(
|
||||
|
||||
index = prebuilt->index;
|
||||
|
||||
if (UNIV_UNLIKELY(index == NULL)) {
|
||||
prebuilt->index_usable = FALSE;
|
||||
DBUG_RETURN(HA_ERR_CRASHED);
|
||||
}
|
||||
|
||||
/* Note that if the index for which the search template is built is not
|
||||
necessarily prebuilt->index, but can also be the clustered index */
|
||||
|
||||
@ -5388,6 +5485,7 @@ ha_innobase::change_active_index(
|
||||
if (UNIV_UNLIKELY(!prebuilt->index)) {
|
||||
sql_print_warning("InnoDB: change_active_index(%u) failed",
|
||||
keynr);
|
||||
prebuilt->index_usable = FALSE;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
@ -5395,7 +5493,9 @@ ha_innobase::change_active_index(
|
||||
prebuilt->index);
|
||||
|
||||
if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
|
||||
sql_print_warning("InnoDB: insufficient history for index %u",
|
||||
push_warning_printf(user_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
HA_ERR_TABLE_DEF_CHANGED,
|
||||
"InnoDB: insufficient history for index %u",
|
||||
keynr);
|
||||
/* The caller seems to ignore this. Thus, we must check
|
||||
this again in row_search_for_mysql(). */
|
||||
@ -5852,7 +5952,7 @@ create_table_def(
|
||||
number fits in one byte in prtype */
|
||||
push_warning_printf(
|
||||
(THD*) trx->mysql_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_CANT_CREATE_TABLE,
|
||||
"In InnoDB, charset-collation codes"
|
||||
" must be below 256."
|
||||
@ -5884,17 +5984,8 @@ create_table_def(
|
||||
/* First check whether the column to be added has a
|
||||
system reserved name. */
|
||||
if (dict_col_name_is_reserved(field->field_name)){
|
||||
push_warning_printf(
|
||||
(THD*) trx->mysql_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_CANT_CREATE_TABLE,
|
||||
"Error creating table '%s' with "
|
||||
"column name '%s'. '%s' is a "
|
||||
"reserved name. Please try to "
|
||||
"re-create the table with a "
|
||||
"different column name.",
|
||||
table->name, (char*) field->field_name,
|
||||
(char*) field->field_name);
|
||||
my_error(ER_WRONG_COLUMN_NAME, MYF(0),
|
||||
field->field_name);
|
||||
|
||||
dict_mem_table_free(table);
|
||||
trx_commit_for_mysql(trx);
|
||||
@ -5916,6 +6007,14 @@ create_table_def(
|
||||
|
||||
error = row_create_table_for_mysql(table, trx);
|
||||
|
||||
if (error == DB_DUPLICATE_KEY) {
|
||||
char buf[100];
|
||||
innobase_convert_identifier(buf, sizeof buf,
|
||||
table_name, strlen(table_name),
|
||||
trx->mysql_thd, TRUE);
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
|
||||
}
|
||||
|
||||
error_ret:
|
||||
error = convert_error_code_to_mysql(error, flags, NULL);
|
||||
|
||||
@ -6066,7 +6165,6 @@ create_clustered_index_when_no_primary(
|
||||
|
||||
/* We pass 0 as the space id, and determine at a lower level the space
|
||||
id where to store the table */
|
||||
|
||||
index = dict_mem_index_create(table_name,
|
||||
innobase_index_reserve_name,
|
||||
0, DICT_CLUSTERED, 0);
|
||||
@ -6121,7 +6219,7 @@ create_options_are_valid(
|
||||
/* Valid value. */
|
||||
break;
|
||||
default:
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
"InnoDB: invalid"
|
||||
" KEY_BLOCK_SIZE = %lu."
|
||||
@ -6135,7 +6233,7 @@ create_options_are_valid(
|
||||
/* If KEY_BLOCK_SIZE was specified, check for its
|
||||
dependencies. */
|
||||
if (kbs_specified && !srv_file_per_table) {
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
"InnoDB: KEY_BLOCK_SIZE"
|
||||
" requires innodb_file_per_table.");
|
||||
@ -6143,7 +6241,7 @@ create_options_are_valid(
|
||||
}
|
||||
|
||||
if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
"InnoDB: KEY_BLOCK_SIZE"
|
||||
" requires innodb_file_format >"
|
||||
@ -6167,7 +6265,7 @@ create_options_are_valid(
|
||||
if (!srv_file_per_table) {
|
||||
push_warning_printf(
|
||||
thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
"InnoDB: ROW_FORMAT=%s"
|
||||
" requires innodb_file_per_table.",
|
||||
@ -6179,7 +6277,7 @@ create_options_are_valid(
|
||||
if (srv_file_format < DICT_TF_FORMAT_ZIP) {
|
||||
push_warning_printf(
|
||||
thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
"InnoDB: ROW_FORMAT=%s"
|
||||
" requires innodb_file_format >"
|
||||
@ -6196,7 +6294,7 @@ create_options_are_valid(
|
||||
&& form->s->row_type == ROW_TYPE_DYNAMIC) {
|
||||
push_warning_printf(
|
||||
thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
"InnoDB: cannot specify"
|
||||
" ROW_FORMAT = DYNAMIC with"
|
||||
@ -6220,7 +6318,7 @@ create_options_are_valid(
|
||||
if (kbs_specified) {
|
||||
push_warning_printf(
|
||||
thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
"InnoDB: cannot specify"
|
||||
" ROW_FORMAT = %s with"
|
||||
@ -6233,7 +6331,7 @@ create_options_are_valid(
|
||||
|
||||
default:
|
||||
push_warning(thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
"InnoDB: invalid ROW_FORMAT specifier.");
|
||||
ret = FALSE;
|
||||
@ -6297,13 +6395,15 @@ ha_innobase::create(
|
||||
1. <database_name>/<table_name>: for normal table creation
|
||||
2. full path: for temp table creation, or sym link
|
||||
|
||||
When srv_file_per_table is on, check for full path pattern, i.e.
|
||||
When srv_file_per_table is on and mysqld_embedded is off,
|
||||
check for full path pattern, i.e.
|
||||
X:\dir\..., X is a driver letter, or
|
||||
\\dir1\dir2\..., UNC path
|
||||
returns error if it is in full path format, but not creating a temp.
|
||||
table. Currently InnoDB does not support symbolic link on Windows. */
|
||||
|
||||
if (srv_file_per_table
|
||||
&& !mysqld_embedded
|
||||
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
|
||||
|
||||
if ((name[1] == ':')
|
||||
@ -6521,6 +6621,7 @@ ha_innobase::create(
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/* Create the keys */
|
||||
|
||||
if (form->s->keys == 0 || primary_key_no == -1) {
|
||||
@ -6969,6 +7070,24 @@ ha_innobase::rename_table(
|
||||
innobase_commit_low(trx);
|
||||
trx_free_for_mysql(trx);
|
||||
|
||||
/* Add a special case to handle the Duplicated Key error
|
||||
and return DB_ERROR instead.
|
||||
This is to avoid a possible SIGSEGV error from mysql error
|
||||
handling code. Currently, mysql handles the Duplicated Key
|
||||
error by re-entering the storage layer and getting dup key
|
||||
info by calling get_dup_key(). This operation requires a valid
|
||||
table handle ('row_prebuilt_t' structure) which could no
|
||||
longer be available in the error handling stage. The suggested
|
||||
solution is to report a 'table exists' error message (since
|
||||
the dup key error here is due to an existing table whose name
|
||||
is the one we are trying to rename to) and return the generic
|
||||
error code. */
|
||||
if (error == (int) DB_DUPLICATE_KEY) {
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
|
||||
|
||||
error = DB_ERROR;
|
||||
}
|
||||
|
||||
error = convert_error_code_to_mysql(error, 0, NULL);
|
||||
|
||||
DBUG_RETURN(error);
|
||||
@ -7521,12 +7640,16 @@ ha_innobase::check(
|
||||
|
||||
ret = row_check_table_for_mysql(prebuilt);
|
||||
|
||||
if (ret == DB_SUCCESS) {
|
||||
switch (ret) {
|
||||
case DB_SUCCESS:
|
||||
return(HA_ADMIN_OK);
|
||||
}
|
||||
|
||||
case DB_INTERRUPTED:
|
||||
my_error(ER_QUERY_INTERRUPTED, MYF(0));
|
||||
return(-1);
|
||||
default:
|
||||
return(HA_ADMIN_CORRUPT);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Adds information about free space in the InnoDB tablespace to a table comment
|
||||
@ -8072,7 +8195,10 @@ ha_innobase::external_lock(
|
||||
ulong const tx_isolation = thd_tx_isolation(ha_thd());
|
||||
if (tx_isolation <= ISO_READ_COMMITTED
|
||||
&& binlog_format == BINLOG_FORMAT_STMT
|
||||
&& thd_binlog_filter_ok(thd))
|
||||
#if MYSQL_VERSION_ID > 50140
|
||||
&& thd_binlog_filter_ok(thd)
|
||||
#endif /* MYSQL_VERSION_ID > 50140 */
|
||||
)
|
||||
{
|
||||
char buf[256];
|
||||
my_snprintf(buf, sizeof(buf),
|
||||
@ -8185,6 +8311,23 @@ ha_innobase::external_lock(
|
||||
statement has ended */
|
||||
|
||||
if (trx->n_mysql_tables_in_use == 0) {
|
||||
#ifdef EXTENDED_SLOWLOG
|
||||
increment_thd_innodb_stats(thd, trx->io_reads,
|
||||
trx->io_read,
|
||||
trx->io_reads_wait_timer,
|
||||
trx->lock_que_wait_timer,
|
||||
trx->innodb_que_wait_timer,
|
||||
trx->distinct_page_access);
|
||||
|
||||
trx->io_reads = 0;
|
||||
trx->io_read = 0;
|
||||
trx->io_reads_wait_timer = 0;
|
||||
trx->lock_que_wait_timer = 0;
|
||||
trx->innodb_que_wait_timer = 0;
|
||||
trx->distinct_page_access = 0;
|
||||
if (trx->distinct_page_access_hash)
|
||||
memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
|
||||
#endif
|
||||
|
||||
trx->mysql_n_tables_locked = 0;
|
||||
prebuilt->used_in_HANDLER = FALSE;
|
||||
@ -8472,8 +8615,8 @@ innodb_mutex_show_status(
|
||||
rw_lock_wait_time += mutex->lspent_time;
|
||||
}
|
||||
#else /* UNIV_DEBUG */
|
||||
buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu",
|
||||
mutex->cfile_name, (ulong) mutex->cline);
|
||||
buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s",
|
||||
mutex->cmutex_name);
|
||||
buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
|
||||
mutex->count_os_wait);
|
||||
|
||||
@ -8498,8 +8641,8 @@ next_mutex:
|
||||
while (lock != NULL) {
|
||||
if (lock->count_os_wait
|
||||
&& !buf_pool_is_block_lock(lock)) {
|
||||
buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%lu",
|
||||
lock->cfile_name, (ulong) lock->cline);
|
||||
buf1len= my_snprintf(buf1, sizeof(buf1), "%s",
|
||||
lock->lock_name);
|
||||
buf2len= my_snprintf(buf2, sizeof(buf2),
|
||||
"os_waits=%lu", lock->count_os_wait);
|
||||
|
||||
@ -8720,6 +8863,7 @@ ha_innobase::store_lock(
|
||||
&& isolation_level != TRX_ISO_SERIALIZABLE
|
||||
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
|
||||
&& (sql_command == SQLCOM_INSERT_SELECT
|
||||
|| sql_command == SQLCOM_REPLACE_SELECT
|
||||
|| sql_command == SQLCOM_UPDATE
|
||||
|| sql_command == SQLCOM_CREATE_TABLE)) {
|
||||
|
||||
@ -8727,10 +8871,11 @@ ha_innobase::store_lock(
|
||||
option set or this session is using READ COMMITTED
|
||||
isolation level and isolation level of the transaction
|
||||
is not set to serializable and MySQL is doing
|
||||
INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
|
||||
CREATE ... SELECT... without FOR UPDATE or
|
||||
IN SHARE MODE in select, then we use consistent
|
||||
read for select. */
|
||||
INSERT INTO...SELECT or REPLACE INTO...SELECT
|
||||
or UPDATE ... = (SELECT ...) or CREATE ...
|
||||
SELECT... without FOR UPDATE or IN SHARE
|
||||
MODE in select, then we use consistent read
|
||||
for select. */
|
||||
|
||||
prebuilt->select_lock_type = LOCK_NONE;
|
||||
prebuilt->stored_select_lock_type = LOCK_NONE;
|
||||
@ -8960,7 +9105,6 @@ ha_innobase::get_auto_increment(
|
||||
table->next_number_field);
|
||||
|
||||
current = *first_value > col_max_value ? autoinc : *first_value;
|
||||
|
||||
need = *nb_reserved_values * increment;
|
||||
|
||||
/* Compute the last value in the interval */
|
||||
@ -9324,8 +9468,7 @@ innobase_xa_prepare(
|
||||
executing XA PREPARE and XA COMMIT commands.
|
||||
In this case we cannot know how many minutes or hours
|
||||
will be between XA PREPARE and XA COMMIT, and we don't want
|
||||
to block for undefined period of time.
|
||||
*/
|
||||
to block for undefined period of time. */
|
||||
pthread_mutex_lock(&prepare_commit_mutex);
|
||||
trx->active_trans = 2;
|
||||
}
|
||||
@ -9577,6 +9720,20 @@ ha_innobase::check_if_incompatible_data(
|
||||
DBUG_RETURN(COMPATIBLE_DATA_NO);
|
||||
}
|
||||
|
||||
/* Renaming column asynchronizes dictionary between mysqld and InnoDB...
|
||||
If not synchronized, treat as COMPATIBLE_DATA_NO
|
||||
until the bug http://bugs.mysql.com/47621 is fixed officialily */
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < table->s->fields; i++) {
|
||||
if (table->field[i]->flags & FIELD_IN_ADD_INDEX
|
||||
&& innobase_strcasecmp(table->field[i]->field_name,
|
||||
dict_table_get_col_name(prebuilt->table, i))) {
|
||||
return(COMPATIBLE_DATA_NO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if a column participating in a foreign key is being renamed.
|
||||
There is no mechanism for updating InnoDB foreign key definitions. */
|
||||
if (foreign_key_column_is_being_renamed(prebuilt, table)) {
|
||||
@ -9685,25 +9842,24 @@ innobase_file_format_check_on_off(
|
||||
/************************************************************//**
|
||||
Validate the file format check config parameters, as a side effect it
|
||||
sets the srv_check_file_format_at_startup variable.
|
||||
@return true if valid config value */
|
||||
@return the format_id if valid config value, otherwise, return -1 */
|
||||
static
|
||||
bool
|
||||
innobase_file_format_check_validate(
|
||||
int
|
||||
innobase_file_format_validate_and_set(
|
||||
/*================================*/
|
||||
const char* format_check) /*!< in: parameter value */
|
||||
{
|
||||
uint format_id;
|
||||
bool ret = true;
|
||||
|
||||
format_id = innobase_file_format_name_lookup(format_check);
|
||||
|
||||
if (format_id < DICT_TF_FORMAT_MAX + 1) {
|
||||
srv_check_file_format_at_startup = format_id;
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return((int) format_id);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
@ -9722,7 +9878,6 @@ innodb_file_format_name_validate(
|
||||
struct st_mysql_value* value) /*!< in: incoming string */
|
||||
{
|
||||
const char* file_format_input;
|
||||
char* file_format_input_strdup;
|
||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||
int len = sizeof(buff);
|
||||
|
||||
@ -9739,20 +9894,14 @@ innodb_file_format_name_validate(
|
||||
|
||||
if (format_id <= DICT_TF_FORMAT_MAX) {
|
||||
|
||||
/* Copy out from stack-allocated memory (which will not
|
||||
survive return from this function). The memory will be
|
||||
freed in innodb_file_format_check_update(). */
|
||||
file_format_input_strdup = thd_strmake(thd, file_format_input, len);
|
||||
/* Save a pointer to the name in the
|
||||
'file_format_name_map' constant array. */
|
||||
*static_cast<const char**>(save) =
|
||||
trx_sys_file_format_id_to_name(format_id);
|
||||
|
||||
*static_cast<char**>(save) = file_format_input_strdup;
|
||||
|
||||
if (file_format_input_strdup == NULL) {
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*static_cast<const char**>(save) = NULL;
|
||||
return(1);
|
||||
@ -9810,9 +9959,9 @@ innodb_file_format_check_validate(
|
||||
struct st_mysql_value* value) /*!< in: incoming string */
|
||||
{
|
||||
const char* file_format_input;
|
||||
char* file_format_input_strdup;
|
||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||
int len = sizeof(buff);
|
||||
int format_id;
|
||||
|
||||
ut_a(save != NULL);
|
||||
ut_a(value != NULL);
|
||||
@ -9825,28 +9974,29 @@ innodb_file_format_check_validate(
|
||||
message if they did so. */
|
||||
|
||||
if (innobase_file_format_check_on_off(file_format_input)) {
|
||||
sql_print_warning(
|
||||
push_warning_printf(thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WRONG_ARGUMENTS,
|
||||
"InnoDB: invalid innodb_file_format_check "
|
||||
"value; on/off can only be set at startup or "
|
||||
"in the configuration file");
|
||||
} else if (innobase_file_format_check_validate(
|
||||
file_format_input)) {
|
||||
|
||||
/* Copy out from stack-allocated memory (which will not
|
||||
survive return from this function). The memory will be
|
||||
freed in innodb_file_format_check_update(). */
|
||||
file_format_input_strdup = thd_strmake(thd, file_format_input, len);
|
||||
|
||||
*static_cast<char**>(save) = file_format_input_strdup;
|
||||
|
||||
if (file_format_input_strdup == NULL) {
|
||||
return(1);
|
||||
} else {
|
||||
format_id = innobase_file_format_validate_and_set(
|
||||
file_format_input);
|
||||
|
||||
if (format_id >= 0) {
|
||||
/* Save a pointer to the name in the
|
||||
'file_format_name_map' constant array. */
|
||||
*static_cast<const char**>(save) =
|
||||
trx_sys_file_format_id_to_name(
|
||||
(uint)format_id);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
} else {
|
||||
sql_print_warning(
|
||||
push_warning_printf(thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WRONG_ARGUMENTS,
|
||||
"InnoDB: invalid innodb_file_format_check "
|
||||
"value; can be any format up to %s "
|
||||
"or its equivalent numeric id",
|
||||
@ -9854,6 +10004,7 @@ innodb_file_format_check_validate(
|
||||
DICT_TF_FORMAT_MAX));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*static_cast<const char**>(save) = NULL;
|
||||
return(1);
|
||||
@ -9882,6 +10033,7 @@ innodb_file_format_check_update(
|
||||
ut_a(var_ptr != NULL);
|
||||
|
||||
format_name_in = *static_cast<const char*const*>(save);
|
||||
|
||||
if (!format_name_in) {
|
||||
|
||||
return;
|
||||
@ -9931,6 +10083,25 @@ innodb_adaptive_hash_index_update(
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Update the system variable innodb_old_blocks_pct using the "saved"
|
||||
value. This function is registered as a callback with MySQL. */
|
||||
static
|
||||
void
|
||||
innodb_old_blocks_pct_update(
|
||||
/*=========================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
void* var_ptr,/*!< out: where the
|
||||
formal string goes */
|
||||
const void* save) /*!< in: immediate result
|
||||
from check function */
|
||||
{
|
||||
innobase_old_blocks_pct = buf_LRU_old_ratio_update(
|
||||
*static_cast<const uint*>(save), TRUE);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Check if it is a valid value of innodb_change_buffering. This function is
|
||||
registered as a callback with MySQL.
|
||||
@ -10077,12 +10248,17 @@ static MYSQL_SYSVAR_BOOL(extra_undoslots, innobase_extra_undoslots,
|
||||
static MYSQL_SYSVAR_BOOL(fast_recovery, innobase_fast_recovery,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Enable to use speed hack of recovery avoiding flush list sorting.",
|
||||
NULL, NULL, TRUE);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(recovery_stats, innobase_recovery_stats,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Output statistics of recovery process after it.",
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(use_purge_thread, innobase_use_purge_thread,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Enable to use purge devoted thread.",
|
||||
NULL, NULL, FALSE);
|
||||
static MYSQL_SYSVAR_ULONG(use_purge_thread, srv_use_purge_thread,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Number of purge devoted threads. #### over 1 is EXPERIMENTAL ####",
|
||||
NULL, NULL, 1, 0, 64, 0);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
@ -10124,12 +10300,15 @@ static MYSQL_SYSVAR_STR(file_format, innobase_file_format_name,
|
||||
innodb_file_format_name_validate,
|
||||
innodb_file_format_name_update, "Antelope");
|
||||
|
||||
/* If a new file format is introduced, the file format
|
||||
name needs to be updated accordingly. Please refer to
|
||||
file_format_name_map[] defined in trx0sys.c for the next
|
||||
file format name. */
|
||||
static MYSQL_SYSVAR_STR(file_format_check, innobase_file_format_check,
|
||||
PLUGIN_VAR_OPCMDARG,
|
||||
"The highest file format in the tablespace.",
|
||||
innodb_file_format_check_validate,
|
||||
innodb_file_format_check_update,
|
||||
"on");
|
||||
innodb_file_format_check_update, "Barracuda");
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
|
||||
PLUGIN_VAR_OPCMDARG,
|
||||
@ -10138,7 +10317,7 @@ static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
|
||||
" or 2 (write at commit, flush once per second).",
|
||||
NULL, NULL, 1, 0, 2, 0);
|
||||
|
||||
static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
|
||||
static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||
"With which method to flush data.", NULL, NULL, NULL);
|
||||
|
||||
@ -10179,7 +10358,7 @@ static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
|
||||
static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
|
||||
PLUGIN_VAR_NOCMDARG,
|
||||
"Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
|
||||
NULL, NULL, TRUE);
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
@ -10275,7 +10454,7 @@ static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
|
||||
NULL, NULL, 500L, 1L, ~0L, 0);
|
||||
|
||||
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
|
||||
"Number of file I/O threads in InnoDB.",
|
||||
NULL, NULL, 4, 4, 64, 0);
|
||||
|
||||
@ -10314,6 +10493,18 @@ static MYSQL_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
|
||||
"Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
|
||||
NULL, NULL, 1, 1, 10, 0);
|
||||
|
||||
static MYSQL_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Percentage of the buffer pool to reserve for 'old' blocks.",
|
||||
NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
|
||||
|
||||
static MYSQL_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Move blocks to the 'new' end of the buffer pool if the first access"
|
||||
" was at least this many milliseconds ago."
|
||||
" The timeout is disabled if 0 (the default).",
|
||||
NULL, NULL, 0, 0, UINT_MAX32, 0);
|
||||
|
||||
static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||
"How many files at the maximum InnoDB keeps open at the same time.",
|
||||
@ -10392,13 +10583,18 @@ static MYSQL_SYSVAR_LONGLONG(ibuf_max_size, srv_ibuf_max_size,
|
||||
static MYSQL_SYSVAR_ULONG(ibuf_active_contract, srv_ibuf_active_contract,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Enable/Disable active_contract of insert buffer. 0:disable 1:enable",
|
||||
NULL, NULL, 0, 0, 1, 0);
|
||||
NULL, NULL, 1, 0, 1, 0);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(ibuf_accel_rate, srv_ibuf_accel_rate,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Tunes amount of insert buffer processing of background, in addition to innodb_io_capacity. (in percentage)",
|
||||
NULL, NULL, 100, 100, 999999999, 0);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(checkpoint_age_target, srv_checkpoint_age_target,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Control soft limit of checkpoint age. (0 : not control)",
|
||||
NULL, NULL, 0, 0, ~0UL, 0);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(flush_neighbor_pages, srv_flush_neighbor_pages,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Enable/Disable flushing also neighbor pages. 0:disable 1:enable",
|
||||
@ -10434,7 +10630,7 @@ TYPELIB read_ahead_typelib=
|
||||
};
|
||||
static MYSQL_SYSVAR_ENUM(read_ahead, srv_read_ahead,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Control read ahead activity. (none, random, [linear], both)",
|
||||
"Control read ahead activity (none, random, [linear], both). [from 1.0.5: random read ahead is ignored]",
|
||||
NULL, innodb_read_ahead_update, 2, &read_ahead_typelib);
|
||||
|
||||
static
|
||||
@ -10465,8 +10661,8 @@ TYPELIB adaptive_checkpoint_typelib=
|
||||
};
|
||||
static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Enable/Disable flushing along modified age. ([none], reflex, estimate)",
|
||||
NULL, innodb_adaptive_checkpoint_update, 0, &adaptive_checkpoint_typelib);
|
||||
"Enable/Disable flushing along modified age. (none, reflex, [estimate])",
|
||||
NULL, innodb_adaptive_checkpoint_update, 2, &adaptive_checkpoint_typelib);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_commit,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
@ -10488,6 +10684,11 @@ static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit,
|
||||
"Limit the allocated memory for dictionary cache. (0: unlimited)",
|
||||
NULL, NULL, 0, 0, LONG_MAX, 0);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(relax_table_creation, srv_relax_table_creation,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Relax limitation of column size at table creation as builtin InnoDB.",
|
||||
NULL, NULL, 0, 0, 1, 0);
|
||||
|
||||
static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(additional_mem_pool_size),
|
||||
MYSQL_SYSVAR(autoextend_increment),
|
||||
@ -10500,6 +10701,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(doublewrite),
|
||||
MYSQL_SYSVAR(extra_undoslots),
|
||||
MYSQL_SYSVAR(fast_recovery),
|
||||
MYSQL_SYSVAR(recovery_stats),
|
||||
MYSQL_SYSVAR(fast_shutdown),
|
||||
MYSQL_SYSVAR(file_io_threads),
|
||||
MYSQL_SYSVAR(read_io_threads),
|
||||
@ -10524,6 +10726,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(adaptive_flushing),
|
||||
MYSQL_SYSVAR(max_purge_lag),
|
||||
MYSQL_SYSVAR(mirrored_log_groups),
|
||||
MYSQL_SYSVAR(old_blocks_pct),
|
||||
MYSQL_SYSVAR(old_blocks_time),
|
||||
MYSQL_SYSVAR(open_files),
|
||||
MYSQL_SYSVAR(overwrite_relay_log_info),
|
||||
MYSQL_SYSVAR(rollback_on_timeout),
|
||||
@ -10550,6 +10754,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(ibuf_max_size),
|
||||
MYSQL_SYSVAR(ibuf_active_contract),
|
||||
MYSQL_SYSVAR(ibuf_accel_rate),
|
||||
MYSQL_SYSVAR(checkpoint_age_target),
|
||||
MYSQL_SYSVAR(flush_neighbor_pages),
|
||||
MYSQL_SYSVAR(read_ahead),
|
||||
MYSQL_SYSVAR(adaptive_checkpoint),
|
||||
@ -10562,6 +10767,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(read_ahead_threshold),
|
||||
MYSQL_SYSVAR(io_capacity),
|
||||
MYSQL_SYSVAR(use_purge_thread),
|
||||
MYSQL_SYSVAR(relax_table_creation),
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -10593,6 +10799,7 @@ i_s_innodb_cmpmem,
|
||||
i_s_innodb_cmpmem_reset,
|
||||
i_s_innodb_table_stats,
|
||||
i_s_innodb_index_stats,
|
||||
i_s_innodb_admin_command,
|
||||
i_s_innodb_patches
|
||||
mysql_declare_plugin_end;
|
||||
|
||||
|
@ -258,12 +258,14 @@ int thd_binlog_format(const MYSQL_THD thd);
|
||||
*/
|
||||
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
|
||||
|
||||
#if MYSQL_VERSION_ID > 50140
|
||||
/**
|
||||
Check if binary logging is filtered for thread's current db.
|
||||
@param thd Thread handle
|
||||
@retval 1 the query is not filtered, 0 otherwise.
|
||||
*/
|
||||
bool thd_binlog_filter_ok(const MYSQL_THD thd);
|
||||
#endif /* MYSQL_VERSION_ID > 50140 */
|
||||
}
|
||||
|
||||
typedef struct trx_struct trx_t;
|
||||
@ -289,6 +291,8 @@ trx_t*
|
||||
innobase_trx_allocate(
|
||||
/*==================*/
|
||||
MYSQL_THD thd); /*!< in: user thread handle */
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
This function checks each index name for a table against reserved
|
||||
system default primary index name 'GEN_CLUST_INDEX'. If a name
|
||||
|
@ -35,7 +35,6 @@ extern "C" {
|
||||
}
|
||||
|
||||
#include "ha_innodb.h"
|
||||
#include "handler0vars.h"
|
||||
|
||||
/*************************************************************//**
|
||||
Copies an InnoDB column to a MySQL field. This function is
|
||||
@ -629,7 +628,7 @@ ha_innobase::add_index(
|
||||
ulint num_created = 0;
|
||||
ibool dict_locked = FALSE;
|
||||
ulint new_primary;
|
||||
ulint error;
|
||||
int error;
|
||||
|
||||
DBUG_ENTER("ha_innobase::add_index");
|
||||
ut_a(table);
|
||||
@ -668,7 +667,7 @@ ha_innobase::add_index(
|
||||
if (UNIV_UNLIKELY(error)) {
|
||||
err_exit:
|
||||
mem_heap_free(heap);
|
||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||
trx_general_rollback_for_mysql(trx, NULL);
|
||||
trx_free_for_mysql(trx);
|
||||
trx_commit_for_mysql(prebuilt->trx);
|
||||
DBUG_RETURN(error);
|
||||
@ -766,10 +765,11 @@ err_exit:
|
||||
ut_ad(error == DB_SUCCESS);
|
||||
|
||||
/* Commit the data dictionary transaction in order to release
|
||||
the table locks on the system tables. Unfortunately, this
|
||||
means that if MySQL crashes while creating a new primary key
|
||||
inside row_merge_build_indexes(), indexed_table will not be
|
||||
dropped on crash recovery. Thus, it will become orphaned. */
|
||||
the table locks on the system tables. This means that if
|
||||
MySQL crashes while creating a new primary key inside
|
||||
row_merge_build_indexes(), indexed_table will not be dropped
|
||||
by trx_rollback_active(). It will have to be recovered or
|
||||
dropped by the database administrator. */
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
@ -806,7 +806,7 @@ error_handling:
|
||||
alter table t drop index b, add index (b);
|
||||
|
||||
The fix will have to parse the SQL and note that the index
|
||||
being added has the same name as the the one being dropped and
|
||||
being added has the same name as the one being dropped and
|
||||
ignore that in the dup index check.*/
|
||||
//dict_table_check_for_dup_indexes(prebuilt->table);
|
||||
#endif
|
||||
@ -868,6 +868,7 @@ error_handling:
|
||||
indexed_table->n_mysql_handles_opened++;
|
||||
|
||||
error = row_merge_drop_table(trx, innodb_table);
|
||||
innodb_table = indexed_table;
|
||||
goto convert_error;
|
||||
|
||||
case DB_TOO_BIG_RECORD:
|
||||
@ -882,7 +883,9 @@ error:
|
||||
/* fall through */
|
||||
default:
|
||||
if (new_primary) {
|
||||
if (indexed_table != innodb_table) {
|
||||
row_merge_drop_table(trx, indexed_table);
|
||||
}
|
||||
} else {
|
||||
if (!dict_locked) {
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2008, 2009, Innobase Oy. All Rights Reserved.
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
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
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
/*******************************************************************//**
|
||||
@file handler/handler0vars.h
|
||||
This file contains accessor functions for dynamic plugin on Windows.
|
||||
***********************************************************************/
|
||||
|
||||
#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
|
||||
/*******************************************************************//**
|
||||
This is a list of externals that can not be resolved by delay loading.
|
||||
They have to be resolved indirectly via their addresses in the .map file.
|
||||
All of them are external variables. */
|
||||
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_bin;
|
||||
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1;
|
||||
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename;
|
||||
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO* system_charset_info;
|
||||
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO* default_charset_info;
|
||||
//extern MYSQL_PLUGIN_IMPORT CHARSET_INFO** all_charsets;
|
||||
extern MYSQL_PLUGIN_IMPORT system_variables global_system_variables;
|
||||
//extern MYSQL_PLUGIN_IMPORT char* mysql_real_data_home;
|
||||
extern MYSQL_PLUGIN_IMPORT char* mysql_data_home;
|
||||
//extern MYSQL_PLUGIN_IMPORT char** tx_isolation_names;
|
||||
//extern MYSQL_PLUGIN_IMPORT char** binlog_format_names;
|
||||
//extern MYSQL_PLUGIN_IMPORT char reg_ext;
|
||||
extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
|
||||
extern MYSQL_PLUGIN_IMPORT key_map key_map_full;
|
||||
extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
|
||||
extern MYSQL_PLUGIN_IMPORT bool mysqld_embedded;
|
||||
extern MYSQL_PLUGIN_IMPORT uint lower_case_table_names;
|
||||
extern MYSQL_PLUGIN_IMPORT ulong specialflag;
|
||||
extern MYSQL_PLUGIN_IMPORT int my_umask;
|
||||
|
||||
extern MYSQL_PLUGIN_IMPORT char *relay_log_info_file;
|
||||
|
||||
/*
|
||||
#define my_charset_bin (*wdl_my_charset_bin)
|
||||
#define my_charset_latin1 (*wdl_my_charset_latin1)
|
||||
#define my_charset_filename (*wdl_my_charset_filename)
|
||||
#define system_charset_info (*wdl_system_charset_info)
|
||||
#define default_charset_info (*wdl_default_charset_info)
|
||||
#define all_charsets (wdl_all_charsets)
|
||||
#define global_system_variables (*wdl_global_system_variables)
|
||||
#define mysql_real_data_home (wdl_mysql_real_data_home)
|
||||
#define mysql_data_home (*wdl_mysql_data_home)
|
||||
#define tx_isolation_names (wdl_tx_isolation_names)
|
||||
#define binlog_format_names (wdl_binlog_format_names)
|
||||
#define reg_ext (wdl_reg_ext)
|
||||
#define LOCK_thread_count (*wdl_LOCK_thread_count)
|
||||
#define key_map_full (*wdl_key_map_full)
|
||||
#define mysql_tmpdir_list (*wdl_mysql_tmpdir_list)
|
||||
#define mysqld_embedded (*wdl_mysqld_embedded)
|
||||
*/
|
||||
//#define lower_case_table_names (*wdl_lower_case_table_names)
|
||||
//#define specialflag (*wdl_specialflag)
|
||||
//#define my_umask (*wdl_my_umask)
|
||||
|
||||
#endif
|
@ -47,6 +47,7 @@ extern "C" {
|
||||
#include "trx0rseg.h" /* for trx_rseg_struct */
|
||||
#include "trx0sys.h" /* for trx_sys */
|
||||
#include "dict0dict.h" /* for dict_sys */
|
||||
#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
|
||||
/* from buf0buf.c */
|
||||
struct buf_chunk_struct{
|
||||
ulint mem_size; /* allocated size of the chunk */
|
||||
@ -56,7 +57,6 @@ struct buf_chunk_struct{
|
||||
buf_block_t* blocks; /* array of buffer control blocks */
|
||||
};
|
||||
}
|
||||
#include "handler0vars.h"
|
||||
|
||||
static const char plugin_author[] = "Innobase Oy";
|
||||
|
||||
@ -84,14 +84,16 @@ do { \
|
||||
#define STRUCT_FLD(name, value) value
|
||||
#endif
|
||||
|
||||
static const ST_FIELD_INFO END_OF_ST_FIELD_INFO =
|
||||
{STRUCT_FLD(field_name, NULL),
|
||||
STRUCT_FLD(field_length, 0),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_NULL),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, 0),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)};
|
||||
/* Don't use a static const variable here, as some C++ compilers (notably
|
||||
HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
|
||||
#define END_OF_ST_FIELD_INFO \
|
||||
{STRUCT_FLD(field_name, NULL), \
|
||||
STRUCT_FLD(field_length, 0), \
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
|
||||
STRUCT_FLD(value, 0), \
|
||||
STRUCT_FLD(field_flags, 0), \
|
||||
STRUCT_FLD(old_name, ""), \
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
|
||||
|
||||
/*
|
||||
Use the following types mapping:
|
||||
@ -511,7 +513,7 @@ static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_index_fields_info[] =
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
{STRUCT_FLD(field_name, "accessed"),
|
||||
{STRUCT_FLD(field_name, "access_time"),
|
||||
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
|
||||
STRUCT_FLD(value, 0),
|
||||
@ -728,7 +730,7 @@ i_s_innodb_buffer_pool_pages_fill(
|
||||
field_store_string(table->field[0], page_type);
|
||||
table->field[1]->store(block->page.space);
|
||||
table->field[2]->store(block->page.offset);
|
||||
table->field[3]->store(block->page.LRU_position);
|
||||
table->field[3]->store(0);
|
||||
table->field[4]->store(block->page.buf_fix_count);
|
||||
table->field[5]->store(block->page.flush_type);
|
||||
|
||||
@ -817,11 +819,11 @@ i_s_innodb_buffer_pool_pages_index_fill(
|
||||
table->field[5]->store(page_get_n_recs(frame));
|
||||
table->field[6]->store(page_get_data_size(frame));
|
||||
table->field[7]->store(block->is_hashed);
|
||||
table->field[8]->store(block->page.accessed);
|
||||
table->field[8]->store(block->page.access_time);
|
||||
table->field[9]->store(block->page.newest_modification != 0);
|
||||
table->field[10]->store(block->page.oldest_modification != 0);
|
||||
table->field[11]->store(block->page.old);
|
||||
table->field[12]->store(block->page.LRU_position);
|
||||
table->field[12]->store(0);
|
||||
table->field[13]->store(block->page.buf_fix_count);
|
||||
table->field[14]->store(block->page.flush_type);
|
||||
|
||||
@ -915,7 +917,7 @@ i_s_innodb_buffer_pool_pages_blob_fill(
|
||||
table->field[4]->store(block->page.offset);
|
||||
}
|
||||
|
||||
table->field[5]->store(block->page.LRU_position);
|
||||
table->field[5]->store(0);
|
||||
table->field[6]->store(block->page.buf_fix_count);
|
||||
table->field[7]->store(block->page.flush_type);
|
||||
|
||||
@ -2953,3 +2955,170 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_index_stats =
|
||||
STRUCT_FLD(system_vars, NULL),
|
||||
STRUCT_FLD(__reserved1, NULL)
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
static ST_FIELD_INFO i_s_innodb_admin_command_info[] =
|
||||
{
|
||||
{STRUCT_FLD(field_name, "result_message"),
|
||||
STRUCT_FLD(field_length, 1024),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, 0),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
END_OF_ST_FIELD_INFO
|
||||
};
|
||||
|
||||
#ifndef INNODB_COMPATIBILITY_HOOKS
|
||||
#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
char **thd_query(MYSQL_THD thd);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
i_s_innodb_admin_command_fill(
|
||||
/*==========================*/
|
||||
THD* thd,
|
||||
TABLE_LIST* tables,
|
||||
COND* cond)
|
||||
{
|
||||
TABLE* i_s_table = (TABLE *) tables->table;
|
||||
CHARSET_INFO *cs= system_charset_info;
|
||||
char** query_str;
|
||||
char* ptr;
|
||||
char quote = '\0';
|
||||
char* command_head = "XTRA_";
|
||||
|
||||
DBUG_ENTER("i_s_innodb_admin_command_fill");
|
||||
|
||||
/* deny access to non-superusers */
|
||||
if (check_global_access(thd, PROCESS_ACL)) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if(thd_sql_command(thd) != SQLCOM_SELECT) {
|
||||
field_store_string(i_s_table->field[0],
|
||||
"SELECT command is only accepted.");
|
||||
goto end_func;
|
||||
}
|
||||
|
||||
query_str = thd_query(thd);
|
||||
ptr = *query_str;
|
||||
|
||||
for (; *ptr; ptr++) {
|
||||
if (*ptr == quote) {
|
||||
quote = '\0';
|
||||
} else if (quote) {
|
||||
} else if (*ptr == '`' || *ptr == '"') {
|
||||
quote = *ptr;
|
||||
} else {
|
||||
long i;
|
||||
for (i = 0; command_head[i]; i++) {
|
||||
if (toupper((int)(unsigned char)(ptr[i]))
|
||||
!= toupper((int)(unsigned char)
|
||||
(command_head[i]))) {
|
||||
goto nomatch;
|
||||
}
|
||||
}
|
||||
break;
|
||||
nomatch:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*ptr) {
|
||||
field_store_string(i_s_table->field[0],
|
||||
"No XTRA_* command in the SQL statement."
|
||||
" Please add /*!XTRA_xxxx*/ to the SQL.");
|
||||
goto end_func;
|
||||
}
|
||||
|
||||
if (!strncasecmp("XTRA_HELLO", ptr, 10)) {
|
||||
/* This is example command XTRA_HELLO */
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: administration command test for XtraDB"
|
||||
" 'XTRA_HELLO' was detected.\n");
|
||||
|
||||
field_store_string(i_s_table->field[0],
|
||||
"Hello!");
|
||||
goto end_func;
|
||||
}
|
||||
else if (!strncasecmp("XTRA_LRU_DUMP", ptr, 13)) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_DUMP'"
|
||||
" was detected.\n");
|
||||
|
||||
if (buf_LRU_file_dump()) {
|
||||
field_store_string(i_s_table->field[0],
|
||||
"XTRA_LRU_DUMP was succeeded.");
|
||||
} else {
|
||||
field_store_string(i_s_table->field[0],
|
||||
"XTRA_LRU_DUMP was failed.");
|
||||
}
|
||||
|
||||
goto end_func;
|
||||
}
|
||||
else if (!strncasecmp("XTRA_LRU_RESTORE", ptr, 16)) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_RESTORE'"
|
||||
" was detected.\n");
|
||||
|
||||
if (buf_LRU_file_restore()) {
|
||||
field_store_string(i_s_table->field[0],
|
||||
"XTRA_LRU_RESTORE was succeeded.");
|
||||
} else {
|
||||
field_store_string(i_s_table->field[0],
|
||||
"XTRA_LRU_RESTORE was failed.");
|
||||
}
|
||||
|
||||
goto end_func;
|
||||
}
|
||||
|
||||
field_store_string(i_s_table->field[0],
|
||||
"Undefined XTRA_* command.");
|
||||
goto end_func;
|
||||
|
||||
end_func:
|
||||
if (schema_table_store_record(thd, i_s_table)) {
|
||||
DBUG_RETURN(1);
|
||||
} else {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
i_s_innodb_admin_command_init(
|
||||
/*==========================*/
|
||||
void* p)
|
||||
{
|
||||
DBUG_ENTER("i_s_innodb_admin_command_init");
|
||||
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
|
||||
|
||||
schema->fields_info = i_s_innodb_admin_command_info;
|
||||
schema->fill_table = i_s_innodb_admin_command_fill;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command =
|
||||
{
|
||||
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
|
||||
STRUCT_FLD(info, &i_s_info),
|
||||
STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
|
||||
STRUCT_FLD(author, plugin_author),
|
||||
STRUCT_FLD(descr, "XtraDB specific command acceptor"),
|
||||
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
|
||||
STRUCT_FLD(init, i_s_innodb_admin_command_init),
|
||||
STRUCT_FLD(deinit, i_s_common_deinit),
|
||||
STRUCT_FLD(version, 0x0100 /* 1.0 */),
|
||||
STRUCT_FLD(status_vars, NULL),
|
||||
STRUCT_FLD(system_vars, NULL),
|
||||
STRUCT_FLD(__reserved1, NULL)
|
||||
};
|
||||
|
@ -40,5 +40,6 @@ extern struct st_mysql_plugin i_s_innodb_patches;
|
||||
extern struct st_mysql_plugin i_s_innodb_rseg;
|
||||
extern struct st_mysql_plugin i_s_innodb_table_stats;
|
||||
extern struct st_mysql_plugin i_s_innodb_index_stats;
|
||||
extern struct st_mysql_plugin i_s_innodb_admin_command;
|
||||
|
||||
#endif /* i_s_h */
|
||||
|
@ -38,5 +38,10 @@ struct innodb_enhancement {
|
||||
{"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_relax_table_creation","Relax limitation of column size at table creation as builtin InnoDB.","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -389,6 +389,27 @@ ibuf_count_set(
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************//**
|
||||
Closes insert buffer and frees the data structures. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_close(void)
|
||||
/*============*/
|
||||
{
|
||||
mutex_free(&ibuf_pessimistic_insert_mutex);
|
||||
memset(&ibuf_pessimistic_insert_mutex,
|
||||
0x0, sizeof(ibuf_pessimistic_insert_mutex));
|
||||
|
||||
mutex_free(&ibuf_mutex);
|
||||
memset(&ibuf_mutex, 0x0, sizeof(ibuf_mutex));
|
||||
|
||||
mutex_free(&ibuf_bitmap_mutex);
|
||||
memset(&ibuf_bitmap_mutex, 0x0, sizeof(ibuf_mutex));
|
||||
|
||||
mem_free(ibuf);
|
||||
ibuf = NULL;
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Updates the size information of the ibuf, assuming the segment size has not
|
||||
changed. */
|
||||
|
@ -618,7 +618,7 @@ enum btr_cur_method {
|
||||
hash_node, and might be necessary to
|
||||
update */
|
||||
BTR_CUR_BINARY, /*!< success using the binary search */
|
||||
BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
|
||||
BTR_CUR_INSERT_TO_IBUF /*!< performed the intended insert to
|
||||
the insert buffer */
|
||||
};
|
||||
|
||||
|
@ -41,6 +41,12 @@ void
|
||||
btr_search_sys_create(
|
||||
/*==================*/
|
||||
ulint hash_size); /*!< in: hash index hash table size */
|
||||
/*****************************************************************//**
|
||||
Frees the adaptive search system at a database shutdown. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_search_sys_free(void);
|
||||
/*=====================*/
|
||||
|
||||
/********************************************************************//**
|
||||
Disable the adaptive hash search system and empty the index. */
|
||||
|
@ -346,7 +346,7 @@ buf_page_release(
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
/********************************************************************//**
|
||||
Moves a page to the start of the buffer pool LRU list. This high-level
|
||||
function can be used to prevent an important page from from slipping out of
|
||||
function can be used to prevent an important page from slipping out of
|
||||
the buffer pool. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
@ -707,15 +707,6 @@ buf_page_belongs_to_unzip_LRU(
|
||||
/*==========================*/
|
||||
const buf_page_t* bpage) /*!< in: pointer to control block */
|
||||
__attribute__((pure));
|
||||
/*********************************************************************//**
|
||||
Determine the approximate LRU list position of a block.
|
||||
@return LRU list position */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_page_get_LRU_position(
|
||||
/*======================*/
|
||||
const buf_page_t* bpage) /*!< in: control block */
|
||||
__attribute__((pure));
|
||||
|
||||
/*********************************************************************//**
|
||||
Gets the mutex of a block.
|
||||
@ -825,14 +816,14 @@ buf_page_set_old(
|
||||
buf_page_t* bpage, /*!< in/out: control block */
|
||||
ibool old); /*!< in: old */
|
||||
/*********************************************************************//**
|
||||
Determine if a block has been accessed in the buffer pool.
|
||||
@return TRUE if accessed */
|
||||
Determine the time of first access of a block in the buffer pool.
|
||||
@return ut_time_ms() at the time of first access, 0 if not accessed */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
unsigned
|
||||
buf_page_is_accessed(
|
||||
/*=================*/
|
||||
const buf_page_t* bpage) /*!< in: control block */
|
||||
__attribute__((pure));
|
||||
__attribute__((nonnull, pure));
|
||||
/*********************************************************************//**
|
||||
Flag a block accessed. */
|
||||
UNIV_INLINE
|
||||
@ -840,7 +831,8 @@ void
|
||||
buf_page_set_accessed(
|
||||
/*==================*/
|
||||
buf_page_t* bpage, /*!< in/out: control block */
|
||||
ibool accessed); /*!< in: accessed */
|
||||
ulint time_ms) /*!< in: ut_time_ms() */
|
||||
__attribute__((nonnull));
|
||||
/*********************************************************************//**
|
||||
Gets the buf_block_t handle of a buffered file block if an uncompressed
|
||||
page frame exists, or NULL.
|
||||
@ -1026,14 +1018,6 @@ buf_block_hash_get(
|
||||
/*===============*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint offset);/*!< in: offset of the page within space */
|
||||
/*******************************************************************//**
|
||||
Increments the pool clock by one and returns its new value. Remember that
|
||||
in the 32 bit version the clock wraps around at 4 billion!
|
||||
@return new clock value */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_pool_clock_tic(void);
|
||||
/*====================*/
|
||||
/*********************************************************************//**
|
||||
Gets the current length of the free list of buffer blocks.
|
||||
@return length of the free list */
|
||||
@ -1073,16 +1057,10 @@ struct buf_page_struct{
|
||||
flushed to disk, this tells the
|
||||
flush_type.
|
||||
@see enum buf_flush */
|
||||
unsigned accessed:1; /*!< TRUE if the page has been accessed
|
||||
while in the buffer pool: read-ahead
|
||||
may read in pages which have not been
|
||||
accessed yet; a thread is allowed to
|
||||
read this for heuristic purposes
|
||||
without holding any mutex or latch */
|
||||
unsigned io_fix:2; /*!< type of pending I/O operation;
|
||||
also protected by buf_pool_mutex
|
||||
@see enum buf_io_fix */
|
||||
unsigned buf_fix_count:24;/*!< count of how manyfold this block
|
||||
unsigned buf_fix_count:25;/*!< count of how manyfold this block
|
||||
is currently bufferfixed */
|
||||
/* @} */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
@ -1112,7 +1090,16 @@ struct buf_page_struct{
|
||||
- BUF_BLOCK_FILE_PAGE: flush_list
|
||||
- BUF_BLOCK_ZIP_DIRTY: flush_list
|
||||
- BUF_BLOCK_ZIP_PAGE: zip_clean
|
||||
- BUF_BLOCK_ZIP_FREE: zip_free[] */
|
||||
- BUF_BLOCK_ZIP_FREE: zip_free[]
|
||||
|
||||
The contents of the list node
|
||||
is undefined if !in_flush_list
|
||||
&& state == BUF_BLOCK_FILE_PAGE,
|
||||
or if state is one of
|
||||
BUF_BLOCK_MEMORY,
|
||||
BUF_BLOCK_REMOVE_HASH or
|
||||
BUF_BLOCK_READY_IN_USE. */
|
||||
|
||||
/* resplit for optimistic use */
|
||||
UT_LIST_NODE_T(buf_page_t) free;
|
||||
UT_LIST_NODE_T(buf_page_t) flush_list;
|
||||
@ -1155,18 +1142,8 @@ struct buf_page_struct{
|
||||
debugging */
|
||||
//#endif /* UNIV_DEBUG */
|
||||
unsigned old:1; /*!< TRUE if the block is in the old
|
||||
blocks in the LRU list */
|
||||
unsigned LRU_position:31;/*!< value which monotonically
|
||||
decreases (or may stay
|
||||
constant if old==TRUE) toward
|
||||
the end of the LRU list, if
|
||||
buf_pool->ulint_clock has not
|
||||
wrapped around: NOTE that this
|
||||
value can only be used in
|
||||
heuristic algorithms, because
|
||||
of the possibility of a
|
||||
wrap-around! */
|
||||
unsigned freed_page_clock:32;/*!< the value of
|
||||
blocks in buf_pool->LRU_old */
|
||||
unsigned freed_page_clock:31;/*!< the value of
|
||||
buf_pool->freed_page_clock
|
||||
when this block was the last
|
||||
time put to the head of the
|
||||
@ -1174,6 +1151,9 @@ struct buf_page_struct{
|
||||
to read this for heuristic
|
||||
purposes without holding any
|
||||
mutex or latch */
|
||||
unsigned access_time:32; /*!< time of first access, or
|
||||
0 if the block was never accessed
|
||||
in the buffer pool */
|
||||
/* @} */
|
||||
# ifdef UNIV_DEBUG_FILE_ACCESSES
|
||||
ibool file_page_was_freed;
|
||||
@ -1318,6 +1298,31 @@ Compute the hash fold value for blocks in buf_pool->zip_hash. */
|
||||
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
|
||||
/* @} */
|
||||
|
||||
/** @brief The buffer pool statistics structure. */
|
||||
struct buf_pool_stat_struct{
|
||||
ulint n_page_gets; /*!< number of page gets performed;
|
||||
also successful searches through
|
||||
the adaptive hash index are
|
||||
counted as page gets; this field
|
||||
is NOT protected by the buffer
|
||||
pool mutex */
|
||||
ulint n_pages_read; /*!< number read operations */
|
||||
ulint n_pages_written;/*!< number write operations */
|
||||
ulint n_pages_created;/*!< number of pages created
|
||||
in the pool with no read */
|
||||
ulint n_ra_pages_read;/*!< number of pages read in
|
||||
as part of read ahead */
|
||||
ulint n_ra_pages_evicted;/*!< number of read ahead
|
||||
pages that are evicted without
|
||||
being accessed */
|
||||
ulint n_pages_made_young; /*!< number of pages made young, in
|
||||
calls to buf_LRU_make_block_young() */
|
||||
ulint n_pages_not_made_young; /*!< number of pages not made
|
||||
young because the first access
|
||||
was not long enough ago, in
|
||||
buf_page_peek_if_too_old() */
|
||||
};
|
||||
|
||||
/** @brief The buffer pool structure.
|
||||
|
||||
NOTE! The definition appears here only for other modules of this
|
||||
@ -1342,28 +1347,16 @@ struct buf_pool_struct{
|
||||
ulint n_pend_reads; /*!< number of pending read operations */
|
||||
ulint n_pend_unzip; /*!< number of pending decompressions */
|
||||
|
||||
time_t last_printout_time; /*!< when buf_print was last time
|
||||
time_t last_printout_time;
|
||||
/*!< when buf_print_io was last time
|
||||
called */
|
||||
ulint n_pages_read; /*!< number read operations */
|
||||
ulint n_pages_written;/*!< number write operations */
|
||||
ulint n_pages_created;/*!< number of pages created
|
||||
in the pool with no read */
|
||||
ulint n_page_gets; /*!< number of page gets performed;
|
||||
also successful searches through
|
||||
the adaptive hash index are
|
||||
counted as page gets; this field
|
||||
is NOT protected by the buffer
|
||||
pool mutex */
|
||||
ulint n_page_gets_old;/*!< n_page_gets when buf_print was
|
||||
last time called: used to calculate
|
||||
hit rate */
|
||||
ulint n_pages_read_old;/*!< n_pages_read when buf_print was
|
||||
last time called */
|
||||
ulint n_pages_written_old;/*!< number write operations */
|
||||
ulint n_pages_created_old;/*!< number of pages created in
|
||||
the pool with no read */
|
||||
buf_pool_stat_t stat; /*!< current statistics */
|
||||
buf_pool_stat_t old_stat; /*!< old statistics */
|
||||
|
||||
/* @} */
|
||||
|
||||
/** @name Page flushing algorithm fields */
|
||||
|
||||
/* @{ */
|
||||
|
||||
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
|
||||
@ -1379,10 +1372,6 @@ struct buf_pool_struct{
|
||||
/*!< this is in the set state
|
||||
when there is no flush batch
|
||||
of the given type running */
|
||||
ulint ulint_clock; /*!< a sequence number used to count
|
||||
time. NOTE! This counter wraps
|
||||
around at 4 billion (if ulint ==
|
||||
32 bits)! */
|
||||
ulint freed_page_clock;/*!< a sequence number used
|
||||
to count the number of buffer
|
||||
blocks removed from the end of
|
||||
@ -1406,17 +1395,18 @@ struct buf_pool_struct{
|
||||
block list */
|
||||
UT_LIST_BASE_NODE_T(buf_page_t) LRU;
|
||||
/*!< base node of the LRU list */
|
||||
buf_page_t* LRU_old; /*!< pointer to the about 3/8 oldest
|
||||
blocks in the LRU list; NULL if LRU
|
||||
length less than BUF_LRU_OLD_MIN_LEN;
|
||||
buf_page_t* LRU_old; /*!< pointer to the about
|
||||
buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
|
||||
oldest blocks in the LRU list;
|
||||
NULL if LRU length less than
|
||||
BUF_LRU_OLD_MIN_LEN;
|
||||
NOTE: when LRU_old != NULL, its length
|
||||
should always equal LRU_old_len */
|
||||
ulint LRU_old_len; /*!< length of the LRU list from
|
||||
the block to which LRU_old points
|
||||
onward, including that block;
|
||||
see buf0lru.c for the restrictions
|
||||
on this value; not defined if
|
||||
LRU_old == NULL;
|
||||
on this value; 0 if LRU_old == NULL;
|
||||
NOTE: LRU_old_len must be adjusted
|
||||
whenever LRU_old shrinks or grows! */
|
||||
|
||||
|
@ -72,9 +72,30 @@ buf_page_peek_if_too_old(
|
||||
/*=====================*/
|
||||
const buf_page_t* bpage) /*!< in: block to make younger */
|
||||
{
|
||||
return(buf_pool->freed_page_clock
|
||||
>= buf_page_get_freed_page_clock(bpage)
|
||||
+ 1 + (buf_pool->curr_size / 4));
|
||||
if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
|
||||
/* If eviction has not started yet, do not update the
|
||||
statistics or move blocks in the LRU list. This is
|
||||
either the warm-up phase or an in-memory workload. */
|
||||
return(FALSE);
|
||||
} else if (buf_LRU_old_threshold_ms && bpage->old) {
|
||||
unsigned access_time = buf_page_is_accessed(bpage);
|
||||
|
||||
if (access_time > 0
|
||||
&& (ut_time_ms() - access_time)
|
||||
>= buf_LRU_old_threshold_ms) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
buf_pool->stat.n_pages_not_made_young++;
|
||||
return(FALSE);
|
||||
} else {
|
||||
/* FIXME: bpage->freed_page_clock is 31 bits */
|
||||
return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
|
||||
> ((ulint) bpage->freed_page_clock
|
||||
+ (buf_pool->curr_size
|
||||
* (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
|
||||
/ (BUF_LRU_OLD_RATIO_DIV * 4))));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -125,23 +146,6 @@ try_again:
|
||||
|
||||
return(lsn);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Increments the buf_pool clock by one and returns its new value. Remember
|
||||
that in the 32 bit version the clock wraps around at 4 billion!
|
||||
@return new clock value */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_pool_clock_tic(void)
|
||||
/*====================*/
|
||||
{
|
||||
//ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(mutex_own(&LRU_list_mutex));
|
||||
|
||||
buf_pool->ulint_clock++;
|
||||
|
||||
return(buf_pool->ulint_clock);
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -287,21 +291,6 @@ buf_page_belongs_to_unzip_LRU(
|
||||
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Determine the approximate LRU list position of a block.
|
||||
@return LRU list position */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_page_get_LRU_position(
|
||||
/*======================*/
|
||||
const buf_page_t* bpage) /*!< in: control block */
|
||||
{
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
//ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
|
||||
|
||||
return(bpage->LRU_position);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Gets the mutex of a block.
|
||||
@return pointer to mutex protecting bpage */
|
||||
@ -508,10 +497,19 @@ buf_page_set_old(
|
||||
ut_ad(bpage->in_LRU_list);
|
||||
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)
|
||||
&& UT_LIST_GET_PREV(LRU, bpage)->old
|
||||
== UT_LIST_GET_NEXT(LRU, bpage)->old) {
|
||||
ut_a(UT_LIST_GET_PREV(LRU, bpage)->old == old);
|
||||
ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL));
|
||||
/* If a block is flagged "old", the LRU_old list must exist. */
|
||||
ut_a(!old || buf_pool->LRU_old);
|
||||
|
||||
if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) {
|
||||
const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
|
||||
const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage);
|
||||
if (prev->old == next->old) {
|
||||
ut_a(prev->old == old);
|
||||
} else {
|
||||
ut_a(!prev->old);
|
||||
ut_a(buf_pool->LRU_old == (old ? bpage : next));
|
||||
}
|
||||
}
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
@ -519,17 +517,17 @@ buf_page_set_old(
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Determine if a block has been accessed in the buffer pool.
|
||||
@return TRUE if accessed */
|
||||
Determine the time of first access of a block in the buffer pool.
|
||||
@return ut_time_ms() at the time of first access, 0 if not accessed */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
unsigned
|
||||
buf_page_is_accessed(
|
||||
/*=================*/
|
||||
const buf_page_t* bpage) /*!< in: control block */
|
||||
{
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
|
||||
return(bpage->accessed);
|
||||
return(bpage->access_time);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -539,12 +537,16 @@ void
|
||||
buf_page_set_accessed(
|
||||
/*==================*/
|
||||
buf_page_t* bpage, /*!< in/out: control block */
|
||||
ibool accessed) /*!< in: accessed */
|
||||
ulint time_ms) /*!< in: ut_time_ms() */
|
||||
{
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
//ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
|
||||
|
||||
bpage->accessed = accessed;
|
||||
if (!bpage->access_time) {
|
||||
/* Make this the time of the first access. */
|
||||
bpage->access_time = time_ms;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -825,15 +827,15 @@ buf_page_get_newest_modification(
|
||||
ib_uint64_t lsn;
|
||||
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
|
||||
|
||||
ut_a(block_mutex);
|
||||
|
||||
if (buf_page_in_file(bpage)) {
|
||||
if (block_mutex && buf_page_in_file(bpage)) {
|
||||
lsn = bpage->newest_modification;
|
||||
} else {
|
||||
lsn = 0;
|
||||
}
|
||||
|
||||
if (block_mutex) {
|
||||
mutex_exit(block_mutex);
|
||||
}
|
||||
|
||||
return(lsn);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ These are low-level functions
|
||||
#########################################################################*/
|
||||
|
||||
/** Minimum LRU list length for which the LRU_old pointer is defined */
|
||||
#define BUF_LRU_OLD_MIN_LEN 80
|
||||
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
|
||||
|
||||
/** Maximum LRU list search length in buf_flush_LRU_recommendation() */
|
||||
#define BUF_LRU_FREE_SEARCH_LEN (5 + 2 * BUF_READ_AHEAD_AREA)
|
||||
@ -84,15 +84,6 @@ void
|
||||
buf_LRU_invalidate_tablespace(
|
||||
/*==========================*/
|
||||
ulint id); /*!< in: space id */
|
||||
/******************************************************************//**
|
||||
Gets the minimum LRU_position field for the blocks in an initial segment
|
||||
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
|
||||
guaranteed to be precise, because the ulint_clock may wrap around.
|
||||
@return the limit; zero if could not determine it */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
buf_LRU_get_recent_limit(void);
|
||||
/*==========================*/
|
||||
/********************************************************************//**
|
||||
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
|
||||
UNIV_INTERN
|
||||
@ -203,6 +194,18 @@ void
|
||||
buf_LRU_make_block_old(
|
||||
/*===================*/
|
||||
buf_page_t* bpage); /*!< in: control block */
|
||||
/**********************************************************************//**
|
||||
Updates buf_LRU_old_ratio.
|
||||
@return updated old_pct */
|
||||
UNIV_INTERN
|
||||
uint
|
||||
buf_LRU_old_ratio_update(
|
||||
/*=====================*/
|
||||
uint old_pct,/*!< in: Reserve this percentage of
|
||||
the buffer pool for "old" blocks. */
|
||||
ibool adjust);/*!< in: TRUE=adjust the LRU list;
|
||||
FALSE=just assign buf_LRU_old_ratio
|
||||
during the initialization of InnoDB */
|
||||
/********************************************************************//**
|
||||
Update the historical stats that we are collecting for LRU eviction
|
||||
policy at the end of each interval. */
|
||||
@ -210,6 +213,18 @@ UNIV_INTERN
|
||||
void
|
||||
buf_LRU_stat_update(void);
|
||||
/*=====================*/
|
||||
/********************************************************************//**
|
||||
Dump the LRU page list to the specific file. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
buf_LRU_file_dump(void);
|
||||
/*===================*/
|
||||
/********************************************************************//**
|
||||
Read the pages based on the specific file.*/
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
buf_LRU_file_restore(void);
|
||||
/*======================*/
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
/**********************************************************************//**
|
||||
@ -229,6 +244,35 @@ buf_LRU_print(void);
|
||||
/*===============*/
|
||||
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
|
||||
|
||||
/** @name Heuristics for detecting index scan @{ */
|
||||
/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
|
||||
"old" blocks. Protected by buf_pool_mutex. */
|
||||
extern uint buf_LRU_old_ratio;
|
||||
/** The denominator of buf_LRU_old_ratio. */
|
||||
#define BUF_LRU_OLD_RATIO_DIV 1024
|
||||
/** Maximum value of buf_LRU_old_ratio.
|
||||
@see buf_LRU_old_adjust_len
|
||||
@see buf_LRU_old_ratio_update */
|
||||
#define BUF_LRU_OLD_RATIO_MAX BUF_LRU_OLD_RATIO_DIV
|
||||
/** Minimum value of buf_LRU_old_ratio.
|
||||
@see buf_LRU_old_adjust_len
|
||||
@see buf_LRU_old_ratio_update
|
||||
The minimum must exceed
|
||||
(BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */
|
||||
#define BUF_LRU_OLD_RATIO_MIN 51
|
||||
|
||||
#if BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX
|
||||
# error "BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX"
|
||||
#endif
|
||||
#if BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV
|
||||
# error "BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV"
|
||||
#endif
|
||||
|
||||
/** Move blocks to "new" LRU list only if the first access was at
|
||||
least this many milliseconds ago. Not protected by any mutex or latch. */
|
||||
extern uint buf_LRU_old_threshold_ms;
|
||||
/* @} */
|
||||
|
||||
/** @brief Statistics for selecting the LRU list for eviction.
|
||||
|
||||
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
|
||||
|
@ -27,28 +27,59 @@ Created 11/5/1995 Heikki Tuuri
|
||||
#define buf0rea_h
|
||||
|
||||
#include "univ.i"
|
||||
#include "trx0types.h"
|
||||
#include "buf0types.h"
|
||||
|
||||
/********************************************************************//**
|
||||
Low-level function which reads a page asynchronously from a file to the
|
||||
buffer buf_pool if it is not already there, in which case does nothing.
|
||||
Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
|
||||
flag is cleared and the x-lock released by an i/o-handler thread.
|
||||
@return 1 if a read request was queued, 0 if the page already resided
|
||||
in buf_pool, or if the page is in the doublewrite buffer blocks in
|
||||
which case it is never read into the pool, or if the tablespace does
|
||||
not exist or is being dropped
|
||||
@return 1 if read request is issued. 0 if it is not */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
buf_read_page_low(
|
||||
/*==============*/
|
||||
ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
|
||||
trying to read from a non-existent tablespace, or a
|
||||
tablespace which is just now being dropped */
|
||||
ibool sync, /*!< in: TRUE if synchronous aio is desired */
|
||||
ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
|
||||
ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
|
||||
at read-ahead functions) */
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size, or 0 */
|
||||
ibool unzip, /*!< in: TRUE=request uncompressed page */
|
||||
ib_int64_t tablespace_version, /*!< in: if the space memory object has
|
||||
this timestamp different from what we are giving here,
|
||||
treat the tablespace as dropped; this is a timestamp we
|
||||
use to stop dangling page reads from a tablespace
|
||||
which we have DISCARDed + IMPORTed back */
|
||||
ulint offset, /*!< in: page number */
|
||||
trx_t* trx);
|
||||
/********************************************************************//**
|
||||
High-level function which reads a page asynchronously from a file to the
|
||||
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
|
||||
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
|
||||
released by the i/o-handler thread. Does a random read-ahead if it seems
|
||||
sensible.
|
||||
@return number of page read requests issued: this can be greater than
|
||||
1 if read-ahead occurred */
|
||||
released by the i/o-handler thread.
|
||||
@return TRUE if page has been read in, FALSE in case of failure */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
ibool
|
||||
buf_read_page(
|
||||
/*==========*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset);/*!< in: page number */
|
||||
ulint offset, /*!< in: page number */
|
||||
trx_t* trx);
|
||||
/********************************************************************//**
|
||||
Applies linear read-ahead if in the buf_pool the page is a border page of
|
||||
a linear read-ahead area and all the pages in the area have been accessed.
|
||||
Does not read any page if the read-ahead mechanism is not activated. Note
|
||||
that the the algorithm looks at the 'natural' adjacent successor and
|
||||
that the algorithm looks at the 'natural' adjacent successor and
|
||||
predecessor of the page, which on the leaf level of a B-tree are the next
|
||||
and previous page in the chain of leaves. To know these, the page specified
|
||||
in (space, offset) must already be present in the buf_pool. Thus, the
|
||||
@ -74,8 +105,9 @@ buf_read_ahead_linear(
|
||||
/*==================*/
|
||||
ulint space, /*!< in: space id */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
||||
ulint offset);/*!< in: page number of a page; NOTE: the current thread
|
||||
ulint offset, /*!< in: page number of a page; NOTE: the current thread
|
||||
must want access to this page (see NOTE 3 above) */
|
||||
trx_t* trx);
|
||||
/********************************************************************//**
|
||||
Issues read requests for pages which the ibuf module wants to read in, in
|
||||
order to contract the insert buffer tree. Technically, this function is like
|
||||
|
@ -34,6 +34,8 @@ typedef struct buf_block_struct buf_block_t;
|
||||
typedef struct buf_chunk_struct buf_chunk_t;
|
||||
/** Buffer pool comprising buf_chunk_t */
|
||||
typedef struct buf_pool_struct buf_pool_t;
|
||||
/** Buffer pool statistics struct */
|
||||
typedef struct buf_pool_stat_struct buf_pool_stat_t;
|
||||
|
||||
/** A buffer frame. @see page_t */
|
||||
typedef byte buf_frame_t;
|
||||
|
@ -32,6 +32,7 @@ enum db_err {
|
||||
|
||||
/* The following are error codes */
|
||||
DB_ERROR,
|
||||
DB_INTERRUPTED,
|
||||
DB_OUT_OF_MEMORY,
|
||||
DB_OUT_OF_FILE_SPACE,
|
||||
DB_LOCK_WAIT,
|
||||
|
@ -110,7 +110,7 @@ dict_create_or_check_foreign_constraint_tables(void);
|
||||
Adds foreign key definitions to data dictionary tables in the database. We
|
||||
look at table->foreign_list, and also generate names to constraints that were
|
||||
not named by the user. A generated constraint has a name of the format
|
||||
databasename/tablename_ibfk_<number>, where the numbers start from 1, and are
|
||||
databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and are
|
||||
given locally for this table, that is, the number is not global, as in the
|
||||
old format constraints < 4.0.18 it used to be.
|
||||
@return error code or DB_SUCCESS */
|
||||
|
@ -712,7 +712,7 @@ dict_index_find_on_id_low(
|
||||
dulint id); /*!< in: index id */
|
||||
/**********************************************************************//**
|
||||
Adds an index to the dictionary cache.
|
||||
@return DB_SUCCESS or error code */
|
||||
@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
dict_index_add_to_cache(
|
||||
@ -1157,6 +1157,13 @@ void
|
||||
dict_ind_init(void);
|
||||
/*===============*/
|
||||
|
||||
/**********************************************************************//**
|
||||
Closes the data dictionary module. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_close(void);
|
||||
/*============*/
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "dict0dict.ic"
|
||||
#endif
|
||||
|
@ -317,7 +317,7 @@ struct dict_foreign_struct{
|
||||
char* id; /*!< id of the constraint as a
|
||||
null-terminated string */
|
||||
unsigned n_fields:10; /*!< number of indexes' first fields
|
||||
for which the the foreign key
|
||||
for which the foreign key
|
||||
constraint is defined: we allow the
|
||||
indexes to contain more fields than
|
||||
mentioned in the constraint, as long
|
||||
|
@ -224,15 +224,6 @@ fil_space_create(
|
||||
0 for uncompressed tablespaces */
|
||||
ulint purpose);/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
|
||||
/*******************************************************************//**
|
||||
Frees a space object from a the tablespace memory cache. Closes the files in
|
||||
the chain but does not delete them.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
fil_space_free(
|
||||
/*===========*/
|
||||
ulint id); /*!< in: space id */
|
||||
/*******************************************************************//**
|
||||
Returns the size of the space in pages. The tablespace must be cached in the
|
||||
memory cache.
|
||||
@return space size, 0 if space not found */
|
||||
@ -278,6 +269,12 @@ fil_init(
|
||||
ulint hash_size, /*!< in: hash table size */
|
||||
ulint max_n_open); /*!< in: max number of open files */
|
||||
/*******************************************************************//**
|
||||
Initializes the tablespace memory cache. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_close(void);
|
||||
/*===========*/
|
||||
/*******************************************************************//**
|
||||
Opens all log files and system tablespace data files. They stay open until the
|
||||
database server shutdown. This should be called at a server startup after the
|
||||
space objects for the log and the system tablespace have been created. The
|
||||
@ -614,9 +611,12 @@ fil_space_get_n_reserved_extents(
|
||||
Reads or writes data. This operation is asynchronous (aio).
|
||||
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
|
||||
i/o on a tablespace which does not exist */
|
||||
#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message) \
|
||||
_fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, NULL)
|
||||
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
fil_io(
|
||||
_fil_io(
|
||||
/*===*/
|
||||
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
|
||||
ORed to OS_FILE_LOG, if a log i/o
|
||||
@ -641,8 +641,25 @@ fil_io(
|
||||
void* buf, /*!< in/out: buffer where to store read data
|
||||
or from where to write; in aio this must be
|
||||
appropriately aligned */
|
||||
void* message); /*!< in: message for aio handler if non-sync
|
||||
void* message, /*!< in: message for aio handler if non-sync
|
||||
aio used, else ignored */
|
||||
trx_t* trx);
|
||||
/********************************************************************//**
|
||||
Confirm whether the parameters are valid or not */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
fil_area_is_exist(
|
||||
/*==============*/
|
||||
ulint space_id, /*!< in: space id */
|
||||
ulint zip_size, /*!< in: compressed page size in bytes;
|
||||
0 for uncompressed pages */
|
||||
ulint block_offset, /*!< in: offset in number of blocks */
|
||||
ulint byte_offset, /*!< in: remainder of offset in bytes; in
|
||||
aio this must be divisible by the OS block
|
||||
size */
|
||||
ulint len); /*!< in: how many bytes to read or write; this
|
||||
must not cross a file boundary; in aio this
|
||||
must be a block size multiple */
|
||||
/**********************************************************************//**
|
||||
Waits for an aio operation to complete. This function is used to write the
|
||||
handler for completed requests. The aio array of pending requests is divided
|
||||
|
@ -42,7 +42,7 @@ fsp_init(void);
|
||||
/*==========*/
|
||||
/**********************************************************************//**
|
||||
Gets the current free limit of the system tablespace. The free limit
|
||||
means the place of the first page which has never been put to the the
|
||||
means the place of the first page which has never been put to the
|
||||
free list for allocation. The space above that address is initialized
|
||||
to zero. Sets also the global variable log_fsp_current_free_limit.
|
||||
@return free limit in megabytes */
|
||||
|
@ -356,6 +356,12 @@ void
|
||||
ibuf_print(
|
||||
/*=======*/
|
||||
FILE* file); /*!< in: file where to print */
|
||||
/******************************************************************//**
|
||||
Closes insert buffer and frees the data structures. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_close(void);
|
||||
/*============*/
|
||||
|
||||
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
|
||||
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
|
||||
|
@ -59,6 +59,12 @@ lock_sys_create(
|
||||
/*============*/
|
||||
ulint n_cells); /*!< in: number of slots in lock hash table */
|
||||
/*********************************************************************//**
|
||||
Closes the lock system at database shutdown. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
lock_sys_close(void);
|
||||
/*================*/
|
||||
/*********************************************************************//**
|
||||
Checks if some transaction has an implicit x-lock on a record in a clustered
|
||||
index.
|
||||
@return transaction which has the x-lock, or NULL */
|
||||
@ -630,6 +636,14 @@ lock_number_of_rows_locked(
|
||||
/*=======================*/
|
||||
trx_t* trx); /*!< in: transaction */
|
||||
/*******************************************************************//**
|
||||
Check if a transaction holds any autoinc locks.
|
||||
@return TRUE if the transaction holds any AUTOINC locks. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
lock_trx_holds_autoinc_locks(
|
||||
/*=========================*/
|
||||
const trx_t* trx); /*!< in: transaction */
|
||||
/*******************************************************************//**
|
||||
Release all the transaction's autoinc locks. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
|
@ -118,10 +118,9 @@ UNIV_INLINE
|
||||
ib_uint64_t
|
||||
log_reserve_and_write_fast(
|
||||
/*=======================*/
|
||||
byte* str, /*!< in: string */
|
||||
const void* str, /*!< in: string */
|
||||
ulint len, /*!< in: string length */
|
||||
ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
|
||||
ibool* success);/*!< out: TRUE if success */
|
||||
ib_uint64_t* start_lsn);/*!< out: start lsn of the log record */
|
||||
/***********************************************************************//**
|
||||
Releases the log mutex. */
|
||||
UNIV_INLINE
|
||||
@ -283,7 +282,7 @@ log_make_checkpoint_at(
|
||||
later lsn, if IB_ULONGLONG_MAX, makes
|
||||
a checkpoint at the latest lsn */
|
||||
ibool write_always); /*!< in: the function normally checks if
|
||||
the the new checkpoint would have a
|
||||
the new checkpoint would have a
|
||||
greater lsn than the previous one: if
|
||||
not, then no physical write is done;
|
||||
by setting this parameter TRUE, a
|
||||
@ -573,6 +572,18 @@ UNIV_INTERN
|
||||
void
|
||||
log_refresh_stats(void);
|
||||
/*===================*/
|
||||
/**********************************************************
|
||||
Shutdown the log system but do not release all the memory. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_shutdown(void);
|
||||
/*==============*/
|
||||
/**********************************************************
|
||||
Free the log system data structures. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_mem_free(void);
|
||||
/*==============*/
|
||||
|
||||
extern log_t* log_sys;
|
||||
|
||||
@ -722,9 +733,12 @@ struct log_group_struct{
|
||||
ulint lsn_offset; /*!< the offset of the above lsn */
|
||||
ulint n_pending_writes;/*!< number of currently pending flush
|
||||
writes for this log group */
|
||||
byte** file_header_bufs_ptr;/*!< unaligned buffers */
|
||||
byte** file_header_bufs;/*!< buffers for each file
|
||||
header in the group */
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
/*-----------------------------*/
|
||||
byte** archive_file_header_bufs_ptr;/*!< unaligned buffers */
|
||||
byte** archive_file_header_bufs;/*!< buffers for each file
|
||||
header in the group */
|
||||
ulint archive_space_id;/*!< file space which
|
||||
@ -743,10 +757,12 @@ struct log_group_struct{
|
||||
completion function then sets the new
|
||||
value to ..._file_no */
|
||||
ulint next_archived_offset; /*!< like the preceding field */
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
/*-----------------------------*/
|
||||
ib_uint64_t scanned_lsn; /*!< used only in recovery: recovery scan
|
||||
succeeded up to this lsn in this log
|
||||
group */
|
||||
byte* checkpoint_buf_ptr;/*!< unaligned checkpoint header */
|
||||
byte* checkpoint_buf; /*!< checkpoint header is written from
|
||||
this buffer to the group */
|
||||
UT_LIST_NODE_T(log_group_t)
|
||||
@ -764,6 +780,7 @@ struct log_struct{
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
mutex_t mutex; /*!< mutex protecting the log */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
byte* buf_ptr; /* unaligned log buffer */
|
||||
byte* buf; /*!< log buffer */
|
||||
ulint buf_size; /*!< log buffer size in bytes */
|
||||
ulint max_buf_free; /*!< recommended maximum value of
|
||||
@ -900,6 +917,7 @@ struct log_struct{
|
||||
should wait for this without owning
|
||||
the log mutex */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
byte* checkpoint_buf_ptr;/* unaligned checkpoint header */
|
||||
byte* checkpoint_buf; /*!< checkpoint header is read to this
|
||||
buffer */
|
||||
/* @} */
|
||||
|
@ -27,6 +27,7 @@ Created 12/9/1995 Heikki Tuuri
|
||||
#include "mach0data.h"
|
||||
#include "mtr0mtr.h"
|
||||
|
||||
#ifdef UNIV_LOG_DEBUG
|
||||
/******************************************************//**
|
||||
Checks by parsing that the catenated log segment for a single mtr is
|
||||
consistent. */
|
||||
@ -34,11 +35,12 @@ UNIV_INTERN
|
||||
ibool
|
||||
log_check_log_recs(
|
||||
/*===============*/
|
||||
byte* buf, /*!< in: pointer to the start of
|
||||
const byte* buf, /*!< in: pointer to the start of
|
||||
the log segment in the
|
||||
log_sys->buf log buffer */
|
||||
ulint len, /*!< in: segment length in bytes */
|
||||
ib_uint64_t buf_start_lsn); /*!< in: buffer start lsn */
|
||||
#endif /* UNIV_LOG_DEBUG */
|
||||
|
||||
/************************************************************//**
|
||||
Gets a log block flush bit.
|
||||
@ -305,55 +307,76 @@ UNIV_INLINE
|
||||
ib_uint64_t
|
||||
log_reserve_and_write_fast(
|
||||
/*=======================*/
|
||||
byte* str, /*!< in: string */
|
||||
const void* str, /*!< in: string */
|
||||
ulint len, /*!< in: string length */
|
||||
ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
|
||||
ibool* success)/*!< out: TRUE if success */
|
||||
ib_uint64_t* start_lsn)/*!< out: start lsn of the log record */
|
||||
{
|
||||
log_t* log = log_sys;
|
||||
ulint data_len;
|
||||
ib_uint64_t lsn;
|
||||
#ifdef UNIV_LOG_LSN_DEBUG
|
||||
/* length of the LSN pseudo-record */
|
||||
ulint lsn_len = 1
|
||||
+ mach_get_compressed_size(log_sys->lsn >> 32)
|
||||
+ mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
|
||||
#endif /* UNIV_LOG_LSN_DEBUG */
|
||||
|
||||
*success = TRUE;
|
||||
mutex_enter(&log_sys->mutex);
|
||||
|
||||
mutex_enter(&(log->mutex));
|
||||
|
||||
data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
|
||||
data_len = len
|
||||
#ifdef UNIV_LOG_LSN_DEBUG
|
||||
+ lsn_len
|
||||
#endif /* UNIV_LOG_LSN_DEBUG */
|
||||
+ log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
|
||||
|
||||
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
|
||||
|
||||
/* The string does not fit within the current log block
|
||||
or the log block would become full */
|
||||
|
||||
*success = FALSE;
|
||||
|
||||
mutex_exit(&(log->mutex));
|
||||
mutex_exit(&log_sys->mutex);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
*start_lsn = log->lsn;
|
||||
*start_lsn = log_sys->lsn;
|
||||
|
||||
ut_memcpy(log->buf + log->buf_free, str, len);
|
||||
#ifdef UNIV_LOG_LSN_DEBUG
|
||||
{
|
||||
/* Write the LSN pseudo-record. */
|
||||
byte* b = &log_sys->buf[log_sys->buf_free];
|
||||
*b++ = MLOG_LSN | (MLOG_SINGLE_REC_FLAG & *(const byte*) str);
|
||||
/* Write the LSN in two parts,
|
||||
as a pseudo page number and space id. */
|
||||
b += mach_write_compressed(b, log_sys->lsn >> 32);
|
||||
b += mach_write_compressed(b, log_sys->lsn & 0xFFFFFFFFUL);
|
||||
ut_a(b - lsn_len == &log_sys->buf[log_sys->buf_free]);
|
||||
|
||||
log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
|
||||
memcpy(b, str, len);
|
||||
len += lsn_len;
|
||||
}
|
||||
#else /* UNIV_LOG_LSN_DEBUG */
|
||||
memcpy(log_sys->buf + log_sys->buf_free, str, len);
|
||||
#endif /* UNIV_LOG_LSN_DEBUG */
|
||||
|
||||
log_block_set_data_len((byte*) ut_align_down(log_sys->buf
|
||||
+ log_sys->buf_free,
|
||||
OS_FILE_LOG_BLOCK_SIZE),
|
||||
data_len);
|
||||
#ifdef UNIV_LOG_DEBUG
|
||||
log->old_buf_free = log->buf_free;
|
||||
log->old_lsn = log->lsn;
|
||||
log_sys->old_buf_free = log_sys->buf_free;
|
||||
log_sys->old_lsn = log_sys->lsn;
|
||||
#endif
|
||||
log->buf_free += len;
|
||||
log_sys->buf_free += len;
|
||||
|
||||
ut_ad(log->buf_free <= log->buf_size);
|
||||
ut_ad(log_sys->buf_free <= log_sys->buf_size);
|
||||
|
||||
lsn = log->lsn += len;
|
||||
log_sys->lsn += len;
|
||||
|
||||
#ifdef UNIV_LOG_DEBUG
|
||||
log_check_log_recs(log->buf + log->old_buf_free,
|
||||
log->buf_free - log->old_buf_free, log->old_lsn);
|
||||
log_check_log_recs(log_sys->buf + log_sys->old_buf_free,
|
||||
log_sys->buf_free - log_sys->old_buf_free,
|
||||
log_sys->old_lsn);
|
||||
#endif
|
||||
return(lsn);
|
||||
return(log_sys->lsn);
|
||||
}
|
||||
|
||||
/***********************************************************************//**
|
||||
|
@ -239,6 +239,18 @@ UNIV_INTERN
|
||||
void
|
||||
recv_sys_create(void);
|
||||
/*=================*/
|
||||
/**********************************************************//**
|
||||
Release recovery system mutexes. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_sys_close(void);
|
||||
/*================*/
|
||||
/********************************************************//**
|
||||
Frees the recovery system memory. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_sys_mem_free(void);
|
||||
/*===================*/
|
||||
/********************************************************//**
|
||||
Inits the recovery system for a recovery operation. */
|
||||
UNIV_INTERN
|
||||
@ -246,6 +258,12 @@ void
|
||||
recv_sys_init(
|
||||
/*==========*/
|
||||
ulint available_memory); /*!< in: available memory in bytes */
|
||||
/********************************************************//**
|
||||
Reset the state of the recovery system variables. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_sys_var_init(void);
|
||||
/*===================*/
|
||||
/*******************************************************************//**
|
||||
Empties the hash table of stored log records, applying them to appropriate
|
||||
pages. */
|
||||
@ -412,6 +430,39 @@ struct recv_sys_struct{
|
||||
hash_table_t* addr_hash;/*!< hash table of file addresses of pages */
|
||||
ulint n_addrs;/*!< number of not processed hashed file
|
||||
addresses in the hash table */
|
||||
|
||||
/* If you modified the following defines at original file,
|
||||
You should also modify them. */
|
||||
/* defined in os0file.c */
|
||||
#define OS_AIO_MERGE_N_CONSECUTIVE 64
|
||||
/* defined in log0recv.c */
|
||||
#define RECV_READ_AHEAD_AREA 32
|
||||
time_t stats_recv_start_time;
|
||||
ulint stats_recv_turns;
|
||||
|
||||
ulint stats_read_requested_pages;
|
||||
ulint stats_read_in_area[RECV_READ_AHEAD_AREA];
|
||||
|
||||
ulint stats_read_io_pages;
|
||||
ulint stats_read_io_consecutive[OS_AIO_MERGE_N_CONSECUTIVE];
|
||||
ulint stats_write_io_pages;
|
||||
ulint stats_write_io_consecutive[OS_AIO_MERGE_N_CONSECUTIVE];
|
||||
|
||||
ulint stats_doublewrite_check_pages;
|
||||
ulint stats_doublewrite_overwrite_pages;
|
||||
|
||||
ulint stats_recover_pages_with_read;
|
||||
ulint stats_recover_pages_without_read;
|
||||
|
||||
ulint stats_log_recs;
|
||||
ulint stats_log_len_sum;
|
||||
|
||||
ulint stats_applied_log_recs;
|
||||
ulint stats_applied_log_len_sum;
|
||||
ulint stats_pages_already_new;
|
||||
|
||||
ib_uint64_t stats_oldest_modified_lsn;
|
||||
ib_uint64_t stats_newest_modified_lsn;
|
||||
};
|
||||
|
||||
/** The recovery system */
|
||||
@ -433,6 +484,11 @@ are allowed yet: the variable name is misleading. */
|
||||
extern ibool recv_no_ibuf_operations;
|
||||
/** TRUE when recv_init_crash_recovery() has been called. */
|
||||
extern ibool recv_needed_recovery;
|
||||
#ifdef UNIV_DEBUG
|
||||
/** TRUE if writing to the redo log (mtr_commit) is forbidden.
|
||||
Protected by log_sys->mutex. */
|
||||
extern ibool recv_no_log_write;
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/** TRUE if buf_page_is_corrupted() should check if the log sequence
|
||||
number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
|
||||
|
@ -82,6 +82,13 @@ void
|
||||
mem_init(
|
||||
/*=====*/
|
||||
ulint size); /*!< in: common pool size in bytes */
|
||||
/******************************************************************//**
|
||||
Closes the memory system. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
mem_close(void);
|
||||
/*===========*/
|
||||
|
||||
/**************************************************************//**
|
||||
Use this macro instead of the corresponding function! Macro for memory
|
||||
heap creation. */
|
||||
|
@ -62,6 +62,13 @@ mem_pool_create(
|
||||
/*============*/
|
||||
ulint size); /*!< in: pool size in bytes */
|
||||
/********************************************************************//**
|
||||
Frees a memory pool. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
mem_pool_free(
|
||||
/*==========*/
|
||||
mem_pool_t* pool); /*!< in, own: memory pool */
|
||||
/********************************************************************//**
|
||||
Allocates memory from a pool. NOTE: This low-level function should only be
|
||||
used in mem0mem.*!
|
||||
@return own: allocated memory buffer */
|
||||
|
@ -106,6 +106,9 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */
|
||||
#define MLOG_IBUF_BITMAP_INIT ((byte)27) /*!< initialize an
|
||||
ibuf bitmap page */
|
||||
/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */
|
||||
#ifdef UNIV_LOG_LSN_DEBUG
|
||||
# define MLOG_LSN ((byte)28) /* current LSN */
|
||||
#endif
|
||||
#define MLOG_INIT_FILE_PAGE ((byte)29) /*!< this means that a
|
||||
file page is taken
|
||||
into use and the prior
|
||||
@ -118,7 +121,7 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */
|
||||
#define MLOG_WRITE_STRING ((byte)30) /*!< write a string to
|
||||
a page */
|
||||
#define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes
|
||||
log records for several pages,
|
||||
several log records,
|
||||
this log record ends the
|
||||
sequence of these records */
|
||||
#define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to
|
||||
|
@ -53,6 +53,7 @@ Created 10/21/1995 Heikki Tuuri
|
||||
#define os0file_h
|
||||
|
||||
#include "univ.i"
|
||||
#include "trx0types.h"
|
||||
|
||||
#ifndef __WIN__
|
||||
#include <dirent.h>
|
||||
@ -157,6 +158,8 @@ log. */
|
||||
to become available again */
|
||||
#define OS_FILE_SHARING_VIOLATION 76
|
||||
#define OS_FILE_ERROR_NOT_SPECIFIED 77
|
||||
#define OS_FILE_INSUFFICIENT_RESOURCE 78
|
||||
#define OS_FILE_OPERATION_ABORTED 79
|
||||
/* @} */
|
||||
|
||||
/** Types for aio operations @{ */
|
||||
@ -497,9 +500,12 @@ os_file_get_last_error(
|
||||
/*******************************************************************//**
|
||||
Requests a synchronous read operation.
|
||||
@return TRUE if request was successful, FALSE if fail */
|
||||
#define os_file_read(file, buf, offset, offset_high, n) \
|
||||
_os_file_read(file, buf, offset, offset_high, n, NULL)
|
||||
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
os_file_read(
|
||||
_os_file_read(
|
||||
/*=========*/
|
||||
os_file_t file, /*!< in: handle to a file */
|
||||
void* buf, /*!< in: buffer where to read */
|
||||
@ -507,7 +513,8 @@ os_file_read(
|
||||
offset where to read */
|
||||
ulint offset_high,/*!< in: most significant 32 bits of
|
||||
offset */
|
||||
ulint n); /*!< in: number of bytes to read */
|
||||
ulint n, /*!< in: number of bytes to read */
|
||||
trx_t* trx);
|
||||
/*******************************************************************//**
|
||||
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
|
||||
@ -619,6 +626,13 @@ os_aio_init(
|
||||
ulint n_write_segs, /*<! in: number of writer threads */
|
||||
ulint n_slots_sync); /*<! in: number of slots in the sync aio
|
||||
array */
|
||||
/***********************************************************************
|
||||
Frees the asynchronous io system. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
os_aio_free(void);
|
||||
/*=============*/
|
||||
|
||||
/*******************************************************************//**
|
||||
Requests an asynchronous i/o operation.
|
||||
@return TRUE if request was queued successfully, FALSE if fail */
|
||||
@ -654,10 +668,11 @@ os_aio(
|
||||
(can be used to identify a completed
|
||||
aio operation); ignored if mode is
|
||||
OS_AIO_SYNC */
|
||||
void* message2);/*!< in: message for the aio handler
|
||||
void* message2,/*!< in: message for the aio handler
|
||||
(can be used to identify a completed
|
||||
aio operation); ignored if mode is
|
||||
OS_AIO_SYNC */
|
||||
trx_t* trx);
|
||||
/************************************************************************//**
|
||||
Wakes up all async i/o threads so that they know to exit themselves in
|
||||
shutdown. */
|
||||
|
@ -285,43 +285,73 @@ os_fast_mutex_free(
|
||||
/**********************************************************//**
|
||||
Atomic compare-and-swap and increment for InnoDB. */
|
||||
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#if defined(HAVE_IB_GCC_ATOMIC_BUILTINS)
|
||||
|
||||
#define HAVE_ATOMIC_BUILTINS
|
||||
|
||||
/**********************************************************//**
|
||||
Returns true if swapped, ptr is pointer to target, old_val is value to
|
||||
compare to, new_val is the value to swap in. */
|
||||
|
||||
# define os_compare_and_swap(ptr, old_val, new_val) \
|
||||
__sync_bool_compare_and_swap(ptr, old_val, new_val)
|
||||
|
||||
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
|
||||
os_compare_and_swap(ptr, old_val, new_val)
|
||||
|
||||
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
|
||||
os_compare_and_swap(ptr, old_val, new_val)
|
||||
|
||||
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
|
||||
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
|
||||
os_compare_and_swap(ptr, old_val, new_val)
|
||||
# define INNODB_RW_LOCKS_USE_ATOMICS
|
||||
# define IB_ATOMICS_STARTUP_MSG \
|
||||
"Mutexes and rw_locks use GCC atomic builtins"
|
||||
# else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
|
||||
# define IB_ATOMICS_STARTUP_MSG \
|
||||
"Mutexes use GCC atomic builtins, rw_locks do not"
|
||||
# endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the resulting value, ptr is pointer to target, amount is the
|
||||
amount of increment. */
|
||||
|
||||
# define os_atomic_increment(ptr, amount) \
|
||||
__sync_add_and_fetch(ptr, amount)
|
||||
|
||||
# define os_atomic_increment_lint(ptr, amount) \
|
||||
os_atomic_increment(ptr, amount)
|
||||
|
||||
# define os_atomic_increment_ulint(ptr, amount) \
|
||||
os_atomic_increment(ptr, amount)
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||
|
||||
# define os_atomic_test_and_set_byte(ptr, new_val) \
|
||||
__sync_lock_test_and_set(ptr, new_val)
|
||||
|
||||
#elif defined(HAVE_IB_SOLARIS_ATOMICS)
|
||||
|
||||
#define HAVE_ATOMIC_BUILTINS
|
||||
|
||||
/* If not compiling with GCC or GCC doesn't support the atomic
|
||||
intrinsics and running on Solaris >= 10 use Solaris atomics */
|
||||
#elif defined(HAVE_SOLARIS_ATOMICS)
|
||||
|
||||
#include <atomic.h>
|
||||
|
||||
/**********************************************************//**
|
||||
Returns true if swapped, ptr is pointer to target, old_val is value to
|
||||
compare to, new_val is the value to swap in. */
|
||||
|
||||
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
|
||||
(atomic_cas_ulong(ptr, old_val, new_val) == old_val)
|
||||
|
||||
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
|
||||
((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
|
||||
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
|
||||
|
||||
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
|
||||
# if SIZEOF_PTHREAD_T == 4
|
||||
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
|
||||
((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
|
||||
@ -331,21 +361,35 @@ compare to, new_val is the value to swap in. */
|
||||
# else
|
||||
# error "SIZEOF_PTHREAD_T != 4 or 8"
|
||||
# endif /* SIZEOF_PTHREAD_T CHECK */
|
||||
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||
# define INNODB_RW_LOCKS_USE_ATOMICS
|
||||
# define IB_ATOMICS_STARTUP_MSG \
|
||||
"Mutexes and rw_locks use Solaris atomic functions"
|
||||
# else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
|
||||
# define IB_ATOMICS_STARTUP_MSG \
|
||||
"Mutexes use Solaris atomic functions, rw_locks do not"
|
||||
# endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the resulting value, ptr is pointer to target, amount is the
|
||||
amount of increment. */
|
||||
|
||||
# define os_atomic_increment_lint(ptr, amount) \
|
||||
atomic_add_long_nv((ulong_t*) ptr, amount)
|
||||
|
||||
# define os_atomic_increment_ulint(ptr, amount) \
|
||||
atomic_add_long_nv(ptr, amount)
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||
|
||||
# define os_atomic_test_and_set_byte(ptr, new_val) \
|
||||
atomic_swap_uchar(ptr, new_val)
|
||||
/* On Windows, use Windows atomics / interlocked */
|
||||
|
||||
#elif defined(HAVE_WINDOWS_ATOMICS)
|
||||
|
||||
#define HAVE_ATOMIC_BUILTINS
|
||||
|
||||
/* On Windows, use Windows atomics / interlocked */
|
||||
# ifdef _WIN64
|
||||
# define win_cmp_and_xchg InterlockedCompareExchange64
|
||||
# define win_xchg_and_add InterlockedExchangeAdd64
|
||||
@ -353,31 +397,46 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||
# define win_cmp_and_xchg InterlockedCompareExchange
|
||||
# define win_xchg_and_add InterlockedExchangeAdd
|
||||
# endif
|
||||
|
||||
/**********************************************************//**
|
||||
Returns true if swapped, ptr is pointer to target, old_val is value to
|
||||
compare to, new_val is the value to swap in. */
|
||||
|
||||
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
|
||||
(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
|
||||
|
||||
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
|
||||
(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
|
||||
# ifdef INNODB_RW_LOCKS_USE_ATOMICS
|
||||
|
||||
/* windows thread objects can always be passed to windows atomic functions */
|
||||
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
|
||||
(InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
|
||||
# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||
# define INNODB_RW_LOCKS_USE_ATOMICS
|
||||
# define IB_ATOMICS_STARTUP_MSG \
|
||||
"Mutexes and rw_locks use Windows interlocked functions"
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the resulting value, ptr is pointer to target, amount is the
|
||||
amount of increment. */
|
||||
|
||||
# define os_atomic_increment_lint(ptr, amount) \
|
||||
(win_xchg_and_add(ptr, amount) + amount)
|
||||
|
||||
# define os_atomic_increment_ulint(ptr, amount) \
|
||||
((ulint) (win_xchg_and_add(ptr, amount) + amount))
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the old value of *ptr, atomically sets *ptr to new_val.
|
||||
InterlockedExchange() operates on LONG, and the LONG will be
|
||||
clobbered */
|
||||
|
||||
# define os_atomic_test_and_set_byte(ptr, new_val) \
|
||||
((byte) InterlockedExchange(ptr, new_val))
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
|
||||
#else
|
||||
# define IB_ATOMICS_STARTUP_MSG \
|
||||
"Mutexes and rw_locks use InnoDB's own implementation"
|
||||
#endif
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "os0sync.ic"
|
||||
|
@ -76,8 +76,11 @@ typedef byte page_header_t;
|
||||
header which are set in a page create */
|
||||
/*----*/
|
||||
#define PAGE_LEVEL 26 /* level of the node in an index tree; the
|
||||
leaf level is the level 0 */
|
||||
#define PAGE_INDEX_ID 28 /* index id where the page belongs */
|
||||
leaf level is the level 0. This field should
|
||||
not be written to after page creation. */
|
||||
#define PAGE_INDEX_ID 28 /* index id where the page belongs.
|
||||
This field should not be written to after
|
||||
page creation. */
|
||||
#define PAGE_BTR_SEG_LEAF 36 /* file segment header for the leaf pages in
|
||||
a B-tree: defined only on the root page of a
|
||||
B-tree, but not in the root of an ibuf tree */
|
||||
|
@ -907,7 +907,7 @@ page_get_data_size(
|
||||
|
||||
/************************************************************//**
|
||||
Allocates a block of memory from the free list of an index page. */
|
||||
UNIV_INTERN
|
||||
UNIV_INLINE
|
||||
void
|
||||
page_mem_alloc_free(
|
||||
/*================*/
|
||||
|
@ -127,8 +127,12 @@ page_zip_decompress(
|
||||
/*================*/
|
||||
page_zip_des_t* page_zip,/*!< in: data, ssize;
|
||||
out: m_start, m_end, m_nonempty, n_blobs */
|
||||
page_t* page) /*!< out: uncompressed page, may be trashed */
|
||||
__attribute__((nonnull));
|
||||
page_t* page, /*!< out: uncompressed page, may be trashed */
|
||||
ibool all) /*!< in: TRUE=decompress the whole page;
|
||||
FALSE=verify but do not copy some
|
||||
page header fields that should not change
|
||||
after page creation */
|
||||
__attribute__((nonnull(1,2)));
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/**********************************************************************//**
|
||||
@ -385,8 +389,8 @@ IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
|
||||
non-clustered index, the caller must update the insert buffer free
|
||||
bits in the same mini-transaction in such a way that the modification
|
||||
will be redo-logged.
|
||||
@return TRUE on success, FALSE on failure; page and page_zip will be
|
||||
left intact on failure. */
|
||||
@return TRUE on success, FALSE on failure; page_zip will be left
|
||||
intact on failure, but page will be overwritten. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
page_zip_reorganize(
|
||||
|
@ -583,6 +583,12 @@ pars_info_get_bound_id(
|
||||
pars_info_t* info, /*!< in: info struct */
|
||||
const char* name); /*!< in: bound id name to find */
|
||||
|
||||
/******************************************************************//**
|
||||
Release any resources used by the lexer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
pars_lexer_close(void);
|
||||
/*==================*/
|
||||
|
||||
/** Extra information supplied for pars_sql(). */
|
||||
struct pars_info_struct {
|
||||
|
@ -89,7 +89,7 @@ cmp_dfield_dfield(
|
||||
/*************************************************************//**
|
||||
This function is used to compare a data tuple to a physical record.
|
||||
Only dtuple->n_fields_cmp first fields are taken into account for
|
||||
the the data tuple! If we denote by n = n_fields_cmp, then rec must
|
||||
the data tuple! If we denote by n = n_fields_cmp, then rec must
|
||||
have either m >= n fields, or it must differ from dtuple in some of
|
||||
the m fields rec has. If rec has an externally stored field we do not
|
||||
compare it but return with value 0 if such a comparison should be
|
||||
|
@ -65,7 +65,7 @@ most significant bytes and bits are written below less significant.
|
||||
- offset_of_this_record) mod 64Ki,
|
||||
where mod is the modulo as a non-negative
|
||||
number;
|
||||
we can calculate the the offset of the next
|
||||
we can calculate the offset of the next
|
||||
record with the formula:
|
||||
relative_offset + offset_of_this_record
|
||||
mod UNIV_PAGE_SIZE
|
||||
|
@ -45,7 +45,7 @@ row_ins_check_foreign_constraint(
|
||||
/*=============================*/
|
||||
ibool check_ref,/*!< in: TRUE If we want to check that
|
||||
the referenced table is ok, FALSE if we
|
||||
want to to check the foreign key table */
|
||||
want to check the foreign key table */
|
||||
dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
|
||||
tables mentioned in it must be in the
|
||||
dictionary cache if they exist at all */
|
||||
|
@ -177,7 +177,9 @@ row_update_prebuilt_trx(
|
||||
in MySQL handle */
|
||||
trx_t* trx); /*!< in: transaction handle */
|
||||
/*********************************************************************//**
|
||||
Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
|
||||
Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
|
||||
function should be called at the the end of an SQL statement, by the
|
||||
connection thread that owns the transaction (trx->mysql_thd). */
|
||||
UNIV_INTERN
|
||||
void
|
||||
row_unlock_table_autoinc_for_mysql(
|
||||
@ -754,8 +756,6 @@ struct row_prebuilt_struct {
|
||||
store it here so that we can return
|
||||
it to MySQL */
|
||||
/*----------------------*/
|
||||
UT_LIST_NODE_T(row_prebuilt_t) prebuilts;
|
||||
/*!< list node of table->prebuilts */
|
||||
ulint magic_n2; /*!< this should be the same as
|
||||
magic_n */
|
||||
};
|
||||
|
@ -80,6 +80,9 @@ at a time */
|
||||
#define SRV_AUTO_EXTEND_INCREMENT \
|
||||
(srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
|
||||
|
||||
/* prototypes for new functions added to ha_innodb.cc */
|
||||
ibool innobase_get_slow_log();
|
||||
|
||||
/* This is set to TRUE if the MySQL user has set it in MySQL */
|
||||
extern ibool srv_lower_case_table_names;
|
||||
|
||||
@ -133,8 +136,9 @@ extern ulint* srv_data_file_is_raw_partition;
|
||||
extern ibool srv_extra_undoslots;
|
||||
|
||||
extern ibool srv_fast_recovery;
|
||||
extern ibool srv_recovery_stats;
|
||||
|
||||
extern ibool srv_use_purge_thread;
|
||||
extern ulint srv_use_purge_thread;
|
||||
|
||||
extern ibool srv_auto_extend_last_data_file;
|
||||
extern ulint srv_last_file_size_max;
|
||||
@ -235,12 +239,14 @@ extern ulong srv_replication_delay;
|
||||
extern long long srv_ibuf_max_size;
|
||||
extern ulong srv_ibuf_active_contract;
|
||||
extern ulong srv_ibuf_accel_rate;
|
||||
extern ulint srv_checkpoint_age_target;
|
||||
extern ulong srv_flush_neighbor_pages;
|
||||
extern ulong srv_enable_unsafe_group_commit;
|
||||
extern ulong srv_read_ahead;
|
||||
extern ulong srv_adaptive_checkpoint;
|
||||
|
||||
extern ulong srv_expand_import;
|
||||
extern ulint srv_relax_table_creation;
|
||||
|
||||
extern ulong srv_extra_rsegments;
|
||||
extern ulong srv_dict_size_limit;
|
||||
@ -345,10 +351,6 @@ extern ulint srv_buf_pool_flushed;
|
||||
/** Number of buffer pool reads that led to the
|
||||
reading of a disk page */
|
||||
extern ulint srv_buf_pool_reads;
|
||||
/** Number of sequential read-aheads */
|
||||
extern ulint srv_read_ahead_seq;
|
||||
/** Number of random read-aheads */
|
||||
extern ulint srv_read_ahead_rnd;
|
||||
|
||||
/** Status variables to be passed to MySQL */
|
||||
typedef struct export_var_struct export_struc;
|
||||
@ -428,6 +430,7 @@ enum srv_thread_type {
|
||||
SRV_INSERT, /**< thread flushing the insert buffer to disk */
|
||||
#endif
|
||||
SRV_PURGE, /* thread purging undo records */
|
||||
SRV_PURGE_WORKER, /* thread purging undo records */
|
||||
SRV_MASTER /**< the master thread, (whose type number must
|
||||
be biggest) */
|
||||
};
|
||||
@ -446,7 +449,7 @@ void
|
||||
srv_init(void);
|
||||
/*==========*/
|
||||
/*********************************************************************//**
|
||||
Frees the OS fast mutex created in srv_boot(). */
|
||||
Frees the data structures created in srv_init(). */
|
||||
UNIV_INTERN
|
||||
void
|
||||
srv_free(void);
|
||||
@ -509,6 +512,13 @@ srv_purge_thread(
|
||||
/*=============*/
|
||||
void* arg); /* in: a dummy parameter required by
|
||||
os_thread_create */
|
||||
/*************************************************************************
|
||||
The undo purge thread. */
|
||||
UNIV_INTERN
|
||||
os_thread_ret_t
|
||||
srv_purge_worker_thread(
|
||||
/*====================*/
|
||||
void* arg);
|
||||
/*******************************************************************//**
|
||||
Tells the Innobase server that there has been activity in the database
|
||||
and wakes up the master thread if it is suspended (not sleeping). Used
|
||||
@ -645,13 +655,13 @@ struct export_var_struct{
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint innodb_buffer_pool_pages_latched; /*!< Latched pages */
|
||||
#endif /* UNIV_DEBUG */
|
||||
ulint innodb_buffer_pool_read_requests; /*!< buf_pool->n_page_gets */
|
||||
ulint innodb_buffer_pool_read_requests; /*!< buf_pool->stat.n_page_gets */
|
||||
ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */
|
||||
ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */
|
||||
ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */
|
||||
ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
|
||||
ulint innodb_buffer_pool_read_ahead_seq;/*!< srv_read_ahead_seq */
|
||||
ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */
|
||||
ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
|
||||
ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
|
||||
ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
|
||||
ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
|
||||
ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
|
||||
@ -663,9 +673,9 @@ struct export_var_struct{
|
||||
ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */
|
||||
ulint innodb_os_log_pending_fsyncs; /*!< fil_n_pending_log_flushes */
|
||||
ulint innodb_page_size; /*!< UNIV_PAGE_SIZE */
|
||||
ulint innodb_pages_created; /*!< buf_pool->n_pages_created */
|
||||
ulint innodb_pages_read; /*!< buf_pool->n_pages_read */
|
||||
ulint innodb_pages_written; /*!< buf_pool->n_pages_written */
|
||||
ulint innodb_pages_created; /*!< buf_pool->stat.n_pages_created */
|
||||
ulint innodb_pages_read; /*!< buf_pool->stat.n_pages_read */
|
||||
ulint innodb_pages_written; /*!< buf_pool->stat.n_pages_written */
|
||||
ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */
|
||||
ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */
|
||||
ib_int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time
|
||||
|
@ -120,7 +120,7 @@ is necessary only if the memory block containing it is freed. */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
#else /* UNIV_DEBUG */
|
||||
# define rw_lock_create(L, level) \
|
||||
rw_lock_create_func((L), __FILE__, __LINE__)
|
||||
rw_lock_create_func((L), #L, NULL, 0)
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/******************************************************************//**
|
||||
@ -137,8 +137,8 @@ rw_lock_create_func(
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
const char* cfile_name, /*!< in: file name where created */
|
||||
ulint cline); /*!< in: file line where created */
|
||||
/******************************************************************//**
|
||||
@ -540,7 +540,8 @@ struct rw_lock_struct {
|
||||
ulint level; /*!< Level in the global latching order. */
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
ulint count_os_wait; /*!< Count of os_waits. May not be accurate */
|
||||
const char* cfile_name;/*!< File name where lock created */
|
||||
//const char* cfile_name;/*!< File name where lock created */
|
||||
const char* lock_name;/*!< lock name */
|
||||
/* last s-lock file/line is not guaranteed to be correct */
|
||||
const char* last_s_file_name;/*!< File name where last s-locked */
|
||||
const char* last_x_file_name;/*!< File name where last x-locked */
|
||||
@ -551,7 +552,7 @@ struct rw_lock_struct {
|
||||
are at the start of this struct, thus we can
|
||||
peek this field without causing much memory
|
||||
bus traffic */
|
||||
unsigned cline:14; /*!< Line where created */
|
||||
//unsigned cline:14; /*!< Line where created */
|
||||
unsigned last_s_line:14; /*!< Line number where last time s-locked */
|
||||
unsigned last_x_line:14; /*!< Line number where last time x-locked */
|
||||
ulint magic_n; /*!< RW_LOCK_MAGIC_N */
|
||||
|
@ -80,7 +80,7 @@ necessary only if the memory block containing it is freed. */
|
||||
# endif
|
||||
#else
|
||||
# define mutex_create(M, level) \
|
||||
mutex_create_func((M), __FILE__, __LINE__)
|
||||
mutex_create_func((M), #M, NULL, 0)
|
||||
#endif
|
||||
|
||||
/******************************************************************//**
|
||||
@ -93,8 +93,8 @@ void
|
||||
mutex_create_func(
|
||||
/*==============*/
|
||||
mutex_t* mutex, /*!< in: pointer to memory */
|
||||
#ifdef UNIV_DEBUG
|
||||
const char* cmutex_name, /*!< in: mutex name */
|
||||
#ifdef UNIV_DEBUG
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
ulint level, /*!< in: level */
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
@ -513,7 +513,7 @@ struct mutex_struct {
|
||||
os_fast_mutex; /*!< We use this OS mutex in place of lock_word
|
||||
when atomic operations are not enabled */
|
||||
#endif
|
||||
ulint waiters; /*!< This ulint is set to 1 if there are (or
|
||||
volatile ulint waiters; /*!< This ulint is set to 1 if there are (or
|
||||
may be) threads waiting in the global wait
|
||||
array for this mutex to be released.
|
||||
Otherwise, this is 0. */
|
||||
@ -524,9 +524,9 @@ struct mutex_struct {
|
||||
ulint line; /*!< Line where the mutex was locked */
|
||||
ulint level; /*!< Level in the global latching order */
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
#ifdef UNIV_DEBUG
|
||||
const char* cfile_name;/*!< File name where mutex created */
|
||||
ulint cline; /*!< Line where created */
|
||||
#ifdef UNIV_DEBUG
|
||||
os_thread_id_t thread_id; /*!< The thread id of the thread
|
||||
which locked the mutex. */
|
||||
ulint magic_n; /*!< MUTEX_MAGIC_N */
|
||||
@ -541,9 +541,9 @@ struct mutex_struct {
|
||||
ulong count_os_yield; /*!< count of os_wait */
|
||||
ulonglong lspent_time; /*!< mutex os_wait timer msec */
|
||||
ulonglong lmax_spent_time;/*!< mutex os_wait timer msec */
|
||||
const char* cmutex_name; /*!< mutex name */
|
||||
ulint mutex_type; /*!< 0=usual mutex, 1=rw_lock mutex */
|
||||
#endif /* UNIV_DEBUG */
|
||||
const char* cmutex_name; /*!< mutex name */
|
||||
};
|
||||
|
||||
/** The global array of wait cells for implementation of the databases own
|
||||
|
@ -39,6 +39,12 @@ UNIV_INTERN
|
||||
void
|
||||
thr_local_init(void);
|
||||
/*================*/
|
||||
/****************************************************************//**
|
||||
Close the thread local storage module. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
thr_local_close(void);
|
||||
/*=================*/
|
||||
/*******************************************************************//**
|
||||
Creates a local storage struct for the calling new thread. */
|
||||
UNIV_INTERN
|
||||
|
@ -141,6 +141,13 @@ void
|
||||
trx_i_s_cache_init(
|
||||
/*===============*/
|
||||
trx_i_s_cache_t* cache); /*!< out: cache to init */
|
||||
/*******************************************************************//**
|
||||
Free the INFORMATION SCHEMA trx related cache. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_i_s_cache_free(
|
||||
/*===============*/
|
||||
trx_i_s_cache_t* cache); /*!< in/out: cache to free */
|
||||
|
||||
/*******************************************************************//**
|
||||
Issue a shared/read lock on the tables cache. */
|
||||
|
@ -71,6 +71,12 @@ void
|
||||
trx_purge_sys_create(void);
|
||||
/*======================*/
|
||||
/********************************************************************//**
|
||||
Frees the global purge system control structure. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_purge_sys_close(void);
|
||||
/*======================*/
|
||||
/************************************************************************
|
||||
Adds the update undo log as the first log in the history list. Removes the
|
||||
update undo log segment from the rseg slot if it is too big for reuse. */
|
||||
UNIV_INTERN
|
||||
@ -108,6 +114,25 @@ UNIV_INTERN
|
||||
ulint
|
||||
trx_purge(void);
|
||||
/*===========*/
|
||||
/**********************************************************************
|
||||
This function runs a purge worker batch */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_purge_worker(
|
||||
/*=============*/
|
||||
ulint worker_id);
|
||||
/**********************************************************************
|
||||
This function waits the event for worker batch */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_purge_worker_wait(void);
|
||||
/*========================*/
|
||||
/**********************************************************************
|
||||
This function wakes the waiting worker batch */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_purge_worker_wake(void);
|
||||
/*========================*/
|
||||
/******************************************************************//**
|
||||
Prints information of the purge system to stderr. */
|
||||
UNIV_INTERN
|
||||
@ -125,6 +150,11 @@ struct trx_purge_struct{
|
||||
of the trx system and it never ends */
|
||||
que_t* query; /*!< The query graph which will do the
|
||||
parallelized purge operation */
|
||||
ulint n_worker;
|
||||
os_event_t worker_event;
|
||||
sess_t** sess_arr;
|
||||
trx_t** trx_arr;
|
||||
que_t** query_arr;
|
||||
rw_lock_t latch; /*!< The latch protecting the purge view.
|
||||
A purge operation must acquire an
|
||||
x-latch here for the instant at which
|
||||
|
@ -44,7 +44,7 @@ UNIV_INLINE
|
||||
trx_undo_rec_t*
|
||||
trx_undo_rec_copy(
|
||||
/*==============*/
|
||||
trx_undo_rec_t* undo_rec, /*!< in: undo log record */
|
||||
const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
|
||||
mem_heap_t* heap); /*!< in: heap where copied */
|
||||
/**********************************************************************//**
|
||||
Reads the undo log record type.
|
||||
|
@ -100,7 +100,7 @@ UNIV_INLINE
|
||||
trx_undo_rec_t*
|
||||
trx_undo_rec_copy(
|
||||
/*==============*/
|
||||
trx_undo_rec_t* undo_rec, /*!< in: undo log record */
|
||||
const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
|
||||
mem_heap_t* heap) /*!< in: heap where copied */
|
||||
{
|
||||
ulint len;
|
||||
|
@ -133,6 +133,17 @@ trx_rollback(
|
||||
Rollback or clean up any incomplete transactions which were
|
||||
encountered in crash recovery. If the transaction already was
|
||||
committed, then we clean up a possible insert undo log. If the
|
||||
transaction was not yet committed, then we roll it back. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_rollback_or_clean_recovered(
|
||||
/*============================*/
|
||||
ibool all); /*!< in: FALSE=roll back dictionary transactions;
|
||||
TRUE=roll back all non-PREPARED transactions */
|
||||
/*******************************************************************//**
|
||||
Rollback or clean up any incomplete transactions which were
|
||||
encountered in crash recovery. If the transaction already was
|
||||
committed, then we clean up a possible insert undo log. If the
|
||||
transaction was not yet committed, then we roll it back.
|
||||
Note: this is done in a background thread.
|
||||
@return a dummy parameter */
|
||||
@ -208,9 +219,9 @@ int
|
||||
trx_general_rollback_for_mysql(
|
||||
/*===========================*/
|
||||
trx_t* trx, /*!< in: transaction handle */
|
||||
ibool partial,/*!< in: TRUE if partial rollback requested */
|
||||
trx_savept_t* savept);/*!< in: pointer to savepoint undo number, if
|
||||
partial rollback requested */
|
||||
partial rollback requested, or NULL for
|
||||
complete rollback */
|
||||
/*******************************************************************//**
|
||||
Rolls back a transaction back to a named savepoint. Modifications after the
|
||||
savepoint are undone but InnoDB does NOT release the corresponding locks
|
||||
|
@ -125,6 +125,13 @@ trx_rseg_create(
|
||||
ulint max_size, /*!< in: max size in pages */
|
||||
ulint* id, /*!< out: rseg id */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
/***************************************************************************
|
||||
Free's an instance of the rollback segment in memory. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_rseg_mem_free(
|
||||
/*==============*/
|
||||
trx_rseg_t* rseg); /* in, own: instance to free */
|
||||
|
||||
|
||||
/* Real max value may be 4076 in usual. But reserve 4 slot for safety or etc... */
|
||||
|
@ -344,6 +344,12 @@ void
|
||||
trx_sys_file_format_tag_init(void);
|
||||
/*==============================*/
|
||||
/*****************************************************************//**
|
||||
Shutdown/Close the transaction system. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_sys_close(void);
|
||||
/*===============*/
|
||||
/*****************************************************************//**
|
||||
Get the name representation of the file format from its id.
|
||||
@return pointer to the name */
|
||||
UNIV_INTERN
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user