Commit 13029651 authored by unknown's avatar unknown

Merge XtraDB 9 into MariaDB.

parents d121e663 5b0ab60a
......@@ -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%";
......
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;
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;
This diff is collapsed.
......@@ -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)
......
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;
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'
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;
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;
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
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;
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;
--loose-innodb_lock_wait_timeout=2
-- 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;
-- 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;
--binlog_cache_size=32768 --innodb_lock_wait_timeout=1
--binlog_cache_size=32768 --loose_innodb_lock_wait_timeout=1
--innodb_lock_wait_timeout=2
--loose-innodb_lock_wait_timeout=2
--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;
--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;
#
# 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;
# 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;
# 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
-- 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;
-- enable_result_log
-- 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
# 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.
SET @counter := 0;
while (`SELECT (@counter := @counter + 1) <= 50 AND COUNT(*) != 14 FROM INFORMATION_SCHEMA.INNODB_LOCKS`)
{
sleep 0.1;
}
-- enable_result_log
# 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,36 +13,41 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
SET(WIN64 TRUE)
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
# This is the CMakeLists for InnoDB Plugin
# 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")
# 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)
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
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/extra/yassl/include)
# 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
# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
IF(MSVC AND $(WIN64))
IF (MSVC AND $(WIN64))
SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
PROPERTIES COMPILE_FLAGS -Od)
ENDIF(MSVC AND $(WIN64))
ENDIF (MSVC AND $(WIN64))
SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
......@@ -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)
MYSQL_STORAGE_ENGINE(INNOBASE)
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")
This diff is collapsed.
......@@ -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);
}
mutex_exit(mutex);
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);
......
This diff is collapsed.
......@@ -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);
ready = buf_flush_ready_for_flush(bpage, flush_type);
mutex_exit(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++;
}
mutex_exit(block_mutex);
if (block_mutex) {
mutex_exit(block_mutex);
}
distance++;
......
This diff is collapsed.
This diff is collapsed.
......@@ -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
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
/* TODO: adjust to zip_size, like below? */
#else
if (space->id == 0) {
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
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;
mutex_enter(&fil_system->mutex);
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));
mutex_exit(&fil_system->mutex);
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,7 +3656,17 @@ fil_load_single_table_tablespace(
if (!success) {
goto func_exit;
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
......@@ -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,11 +2077,37 @@ 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);
}
/**********************************************************************//**
Gets the page number from the nth fragment page slot.
@return page number, FIL_NULL if not in use */
......@@ -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
......
This diff is collapsed.
......@@ -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) {
row_merge_drop_table(trx, indexed_table);
if (indexed_table != innodb_table) {
row_merge_drop_table(trx, indexed_table);
}
} else {
if (!dict_locked) {
row_mysql_lock_data_dictionary(trx);
......
/*****************************************************************************
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}
};
This diff is collapsed.
......@@ -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! */
......
This diff is collapsed.
......@@ -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
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment