Updated/added copyright headers

This commit is contained in:
Kent Boortz 2011-07-04 01:25:49 +02:00
commit 0f03af653c
140 changed files with 3215 additions and 1588 deletions

View file

@ -1,17 +1 @@
# Copyright (c) 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
@CMAKE_CONFIGURABLE_FILE_CONTENT@

View file

@ -1,6 +1,5 @@
/*
Copyright (c) 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc.
Use is subject to license terms.
Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -64,7 +65,8 @@ static struct my_option my_long_options[] =
&ndb_code, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
#ifdef HAVE_SYS_ERRLIST
{"all", 'a', "Print all the error messages and the number.",
{"all", 'a', "Print all the error messages and the number. Deprecated,"
" will be removed in a future release.",
&print_all_codes, &print_all_codes, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
#endif
@ -295,6 +297,8 @@ int main(int argc,char *argv[])
if (print_all_codes)
{
HA_ERRORS *ha_err_ptr;
printf("WARNING: option '-a/--all' is deprecated and will be removed in a"
" future release.\n");
for (code=1 ; code < sys_nerr ; code++)
{
if (sys_errlist[code] && sys_errlist[code][0])

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,6 +1,5 @@
/*
Copyright (c) 2005-2007 MySQL AB, 2008, 2010 Sun Microsystems, Inc.
Use is subject to license terms.
Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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
@ -129,7 +128,7 @@ void SetErrorString(unsigned long error, char* buffer)
break;
case badVersion_error :
strncpy(buffer, "protocl version mismatch", max);
strncpy(buffer, "protocol version mismatch", max);
break;
case compress_error :

View file

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
reserved
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -12,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* This file should be included when using heap_database_functions */
/* Author: Michael Widenius */

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2001, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2001, 2011, Oracle and/or its affiliates. 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

View file

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
reserved
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -531,8 +531,8 @@ int init_embedded_server(int argc, char **argv, char **groups)
return 1;
defaults_argc= *argcp;
defaults_argv= *argvp;
remaining_argc= argc;
remaining_argv= argv;
remaining_argc= *argcp;
remaining_argv= *argvp;
/* Must be initialized early for comparison of options name */
system_charset_info= &my_charset_utf8_general_ci;

View file

@ -1,5 +1,5 @@
# -*- cperl -*-
# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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

View file

@ -171,6 +171,7 @@ our $exe_mysql;
our $exe_mysqladmin;
our $exe_mysqltest;
our $exe_libtool;
our $exe_mysql_embedded;
our $opt_big_test= 0;
@ -1950,6 +1951,8 @@ sub executable_setup () {
$exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
$exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
$exe_mysql_embedded= mtr_exe_maybe_exists("$basedir/libmysqld/examples/mysql_embedded");
if ( ! $opt_skip_ndbcluster )
{
# Look for single threaded NDB
@ -2354,6 +2357,7 @@ sub environment_setup {
$ENV{'MYSQLADMIN'}= native_path($exe_mysqladmin);
$ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments();
$ENV{'EXE_MYSQL'}= $exe_mysql;
$ENV{'MYSQL_EMBEDDED'}= $exe_mysql_embedded;
# ----------------------------------------------------
# bug25714 executable may _not_ exist in

View file

@ -1345,6 +1345,35 @@ DROP TABLE t1;
CREATE TABLE t1 (a TEXT, id INT, b INT);
ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST;
DROP TABLE t1;
#
# Test for bug #12652385 - "61493: REORDERING COLUMNS TO POSITION
# FIRST CAN CAUSE DATA TO BE CORRUPTED".
#
drop table if exists t1;
# Use MyISAM engine as the fact that InnoDB doesn't support
# in-place ALTER TABLE in cases when columns are being renamed
# hides some bugs.
create table t1 (i int, j int) engine=myisam;
insert into t1 value (1, 2);
# First, test for original problem described in the bug report.
select * from t1;
i j
1 2
# Change of column order by the below ALTER TABLE statement should
# affect both column names and column contents.
alter table t1 modify column j int first;
select * from t1;
j i
2 1
# Now test for similar problem with the same root.
# The below ALTER TABLE should change not only the name but
# also the value for the last column of the table.
alter table t1 drop column i, add column k int default 0;
select * from t1;
j k
2 0
# Clean-up.
drop table t1;
End of 5.1 tests
CREATE TABLE t1(c CHAR(10),
i INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY);

View file

@ -466,3 +466,26 @@ ALTER TABLE t1 COMMENT 'test';
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
UNLOCK TABLES;
DROP TABLE t1;
#
# Test for bug #12641342 - "61401: UPDATE PERFORMANCE DEGRADES
# GRADUALLY IF A TRIGGER EXISTS".
#
# One of side-effects of this bug was that a transaction which
# involved DML statements requiring prelocking blocked concurrent
# FLUSH TABLES WITH READ LOCK for the whole its duration, while
# correct behavior in this case is to block FTWRL only for duration
# of individual DML statements.
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (id INT PRIMARY KEY, value INT);
INSERT INTO t1 VALUES (1, 1);
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW SET @var = "a";
BEGIN;
UPDATE t1 SET value= value + 1 WHERE id = 1;
# Switching to connection 'con1'.
# The below FLUSH TABLES WITH READ LOCK should succeed and
# should not be blocked by the transaction in default connection.
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
# Switching to connection 'default'.
COMMIT;
DROP TABLE t1;

View file

@ -697,4 +697,40 @@ SELECT * FROM t1;
pk a
1 2
DROP TABLE t1;
end of tests
#
# BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS
# UPDATED TWICE
#
CREATE TABLE t1 (
col_int_key int,
pk int,
col_int int,
key(col_int_key),
primary key (pk)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,2,3);
CREATE TABLE t2 (
col_int_key int,
pk_1 int,
pk_2 int,
col_int int,
key(col_int_key),
primary key (pk_1,pk_2)
) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1,2,3,4);
UPDATE t1 AS A NATURAL JOIN t1 B SET A.pk=5,B.pk=7;
SELECT * FROM t1;
col_int_key pk col_int
1 7 3
UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_1=5,B.pk_1=7;
UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11;
SELECT * FROM t2;
col_int_key pk_1 pk_2 col_int
1 7 11 4
DROP TABLE t1,t2;

View file

@ -27,3 +27,43 @@ pk a b
0 1 2
DROP VIEW v1;
DROP TABLE t1;
#
# BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS
# UPDATED TWICE
#
CREATE TABLE t1 (
col_int_key int,
pk int,
col_int int,
key(col_int_key),
primary key (pk)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,2,3);
CREATE TABLE t2 (
col_int_key int,
pk_1 int,
pk_2 int,
col_int int,
key(col_int_key),
primary key (pk_1,pk_2)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1,2,3,4);
UPDATE t1 AS A NATURAL JOIN t1 B SET A.pk=5,B.pk=7;
ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'.
SELECT * FROM t1;
col_int_key pk col_int
1 2 3
UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_1=5,B.pk_1=7;
ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'.
UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11;
ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'.
SELECT * FROM t2;
col_int_key pk_1 pk_2 col_int
1 2 3 4
DROP TABLE t1,t2;

View file

@ -0,0 +1,5 @@
#
# Bug#12561297 : LIBMYSQLD/EXAMPLE/MYSQL_EMBEDDED IS ABORTING.
#
1
1

View file

@ -1,5 +1,34 @@
drop table if exists t1, t2;
#
# Bug#11765667: bug#58655: ASSERTION FAILED,
# SERVER CRASHES WITH MYSQLD GOT SIGNAL 6
#
CREATE TABLE t1 (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
dt DATE, st VARCHAR(255), uid INT,
id2nd LONGBLOB, filler VARCHAR(255), PRIMARY KEY(id, dt)
);
INSERT INTO t1 (dt, st, uid, id2nd, filler) VALUES
('1991-03-14', 'Initial Insert', 200, 1234567, 'No Data'),
('1991-02-26', 'Initial Insert', 201, 1234567, 'No Data'),
('1992-03-16', 'Initial Insert', 234, 1234567, 'No Data'),
('1992-07-02', 'Initial Insert', 287, 1234567, 'No Data'),
('1991-05-26', 'Initial Insert', 256, 1234567, 'No Data'),
('1991-04-25', 'Initial Insert', 222, 1234567, 'No Data'),
('1993-03-12', 'Initial Insert', 267, 1234567, 'No Data'),
('1993-03-14', 'Initial Insert', 291, 1234567, 'No Data'),
('1991-12-20', 'Initial Insert', 298, 1234567, 'No Data'),
('1994-10-31', 'Initial Insert', 220, 1234567, 'No Data');
ALTER TABLE t1 PARTITION BY LIST (YEAR(dt)) (
PARTITION d1 VALUES IN (1991, 1994),
PARTITION d2 VALUES IN (1993),
PARTITION d3 VALUES IN (1992, 1995, 1996)
);
INSERT INTO t1 (dt, st, uid, id2nd, filler) VALUES
('1991-07-14', 'After Partitioning Insert', 299, 1234567, 'Insert row');
UPDATE t1 SET filler='Updating the row' WHERE uid=298;
DROP TABLE t1;
#
# Bug#59297: Can't find record in 'tablename' on update inner join
#
CREATE TABLE t1 (
@ -189,6 +218,15 @@ a b
2007-07-30 17:35:48 p1
2009-07-14 17:35:55 pmax
2009-09-21 17:31:42 pmax
SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
a b
2007-07-30 17:35:48 p1
EXPLAIN PARTITIONS SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 system PRIMARY NULL NULL NULL 1
EXPLAIN PARTITIONS SELECT * FROM t1 where a = '2007-07-30 17:35:48';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 system PRIMARY NULL NULL NULL 1
ALTER TABLE t1 REORGANIZE PARTITION pmax INTO (
PARTITION p3 VALUES LESS THAN (1247688000),
PARTITION pmax VALUES LESS THAN MAXVALUE);
@ -197,6 +235,15 @@ a b
2007-07-30 17:35:48 p1
2009-07-14 17:35:55 pmax
2009-09-21 17:31:42 pmax
SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
a b
2007-07-30 17:35:48 p1
EXPLAIN PARTITIONS SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 system PRIMARY NULL NULL NULL 1
EXPLAIN PARTITIONS SELECT * FROM t1 where a = '2007-07-30 17:35:48';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1 system PRIMARY NULL NULL NULL 1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
Tests of syncronization of stored procedure execution.
Tests of synchronization of stored procedure execution.
SET DEBUG_SYNC= 'RESET';
#
# Bug #30977 Concurrent statement using stored function and
@ -92,4 +92,16 @@ COUNT(f1(a))
DROP PROCEDURE p1;
DROP FUNCTION f1;
DROP TABLES t0, t1;
SET DEBUG_SYNC= 'RESET';
#
# test for bug#11756013
#
DROP SCHEMA IF EXISTS s1;
CREATE SCHEMA s1;
CREATE PROCEDURE s1.p1() BEGIN END;
SET DEBUG_SYNC='before_db_dir_check SIGNAL check_db WAIT_FOR dropped_schema';
CALL s1.p1;
SET DEBUG_SYNC='now WAIT_FOR check_db';
DROP SCHEMA s1;
SET DEBUG_SYNC='now SIGNAL dropped_schema';
ERROR 42000: Unknown database 's1'
SET DEBUG_SYNC = 'RESET';

View file

@ -918,6 +918,19 @@ ERROR HY000: Too big row
alter table t1 row_format=compact;
create index t1u on t1 (u(767));
drop table t1;
SET @r=REPEAT('a',500);
CREATE TABLE t1(a INT,
v1 VARCHAR(500), v2 VARCHAR(500), v3 VARCHAR(500),
v4 VARCHAR(500), v5 VARCHAR(500), v6 VARCHAR(500),
v7 VARCHAR(500), v8 VARCHAR(500), v9 VARCHAR(500),
v10 VARCHAR(500), v11 VARCHAR(500), v12 VARCHAR(500),
v13 VARCHAR(500), v14 VARCHAR(500), v15 VARCHAR(500),
v16 VARCHAR(500), v17 VARCHAR(500), v18 VARCHAR(500)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
CREATE INDEX idx1 ON t1(a,v1);
INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
UPDATE t1 SET a=1000;
DROP TABLE t1;
set global innodb_file_per_table=0;
set global innodb_file_format=Antelope;
set global innodb_file_format_max=Antelope;
@ -1085,3 +1098,44 @@ t2 CREATE TABLE `t2` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t1;
CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
CREATE TABLE t2 (a INT, b CHAR(1)) ENGINE=InnoDB;
INSERT INTO t2 SELECT * FROM t1;
BEGIN;
SELECT * FROM t1;
a b
3 a
3 b
1 c
0 d
1 e
SET lock_wait_timeout=1;
CREATE INDEX t1a ON t1(a);
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
CREATE INDEX t2a ON t2(a);
SELECT * FROM t2;
a b
3 a
3 b
1 c
0 d
1 e
SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
ERROR HY000: Table definition has changed, please retry transaction
SELECT * FROM t2;
a b
3 a
3 b
1 c
0 d
1 e
COMMIT;
SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
a b
0 d
1 c
1 e
3 a
3 b
DROP TABLE t1,t2;

View file

@ -9,40 +9,45 @@ SELECT @@GLOBAL.innodb_use_sys_malloc;
@@GLOBAL.innodb_use_sys_malloc
1
1 Expected
drop table if exists t1;
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
create table t1(a int not null,key(a,a)) engine=innodb DEFAULT CHARSET=latin1;
ERROR 42S21: Duplicate column name 'a'
create table t1(a int,b text,key(b(768))) engine=innodb DEFAULT CHARSET=latin1;
ERROR HY000: Index column size too large. The maximum column size is 767 bytes.
create table t1(a int not null,b text) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,'');
create index t1aa on t1(a,a);
ERROR 42S21: Duplicate column name 'a'
create index t1b on t1(b(768));
ERROR HY000: Index column size too large. The maximum column size is 767 bytes.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` text
) ENGINE=InnoDB DEFAULT CHARSET=latin1
select * from t1;
a
1
2
3
4
5
6
7
drop table t1;
SELECT @@GLOBAL.innodb_use_sys_malloc;
@@GLOBAL.innodb_use_sys_malloc
1
1 Expected
SET @@GLOBAL.innodb_use_sys_malloc=0;
ERROR HY000: Variable 'innodb_use_sys_malloc' is a read only variable
Expected error 'Read only variable'
SELECT @@GLOBAL.innodb_use_sys_malloc;
@@GLOBAL.innodb_use_sys_malloc
1
1 Expected
drop table if exists t1;
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
select * from t1;
a
1
2
3
4
5
6
7
a b
1
2
3
4
5
6
7
drop table t1;
CREATE TABLE t2(a int primary key, b text) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,'');
CREATE INDEX t2aa on t2(a,a);
ERROR 42S21: Duplicate column name 'a'
CREATE INDEX t2b on t2(b(768));
ERROR HY000: Index column size too large. The maximum column size is 767 bytes.
SELECT * FROM t2;
a b
1
2
3
4
5
6
7
DROP TABLE t2;

View file

@ -401,6 +401,22 @@ alter table t1 row_format=compact;
create index t1u on t1 (u(767));
drop table t1;
# Bug#12637786
SET @r=REPEAT('a',500);
CREATE TABLE t1(a INT,
v1 VARCHAR(500), v2 VARCHAR(500), v3 VARCHAR(500),
v4 VARCHAR(500), v5 VARCHAR(500), v6 VARCHAR(500),
v7 VARCHAR(500), v8 VARCHAR(500), v9 VARCHAR(500),
v10 VARCHAR(500), v11 VARCHAR(500), v12 VARCHAR(500),
v13 VARCHAR(500), v14 VARCHAR(500), v15 VARCHAR(500),
v16 VARCHAR(500), v17 VARCHAR(500), v18 VARCHAR(500)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
CREATE INDEX idx1 ON t1(a,v1);
INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
UPDATE t1 SET a=1000;
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_max=$format;
@ -516,34 +532,35 @@ SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
# The following tests are disabled because of the introduced timeouts for
# metadata locks at the MySQL level as part of the fix for
# Bug#45225 Locking: hang if drop table with no timeout
# The following CREATE INDEX t1a ON t1(a); causes a lock wait timeout
# start disabled45225_2
#connect (a,localhost,root,,);
#connect (b,localhost,root,,);
#connection a;
#CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
#INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
#connection b;
#BEGIN;
#SELECT * FROM t1;
#connection a;
#CREATE INDEX t1a ON t1(a);
#connection b;
#SELECT * FROM t1;
#--error ER_TABLE_DEF_CHANGED
#SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
#SELECT * FROM t1;
#COMMIT;
#SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
#connection default;
#disconnect a;
#disconnect b;
#
#DROP TABLE t1;
# end disabled45225_2
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
CREATE TABLE t2 (a INT, b CHAR(1)) ENGINE=InnoDB;
INSERT INTO t2 SELECT * FROM t1;
connection b;
BEGIN;
# This acquires a MDL lock on t1 until commit.
SELECT * FROM t1;
connection a;
# This times out before of the MDL lock held by connection b.
SET lock_wait_timeout=1;
--error ER_LOCK_WAIT_TIMEOUT
CREATE INDEX t1a ON t1(a);
CREATE INDEX t2a ON t2(a);
connection b;
SELECT * FROM t2;
--error ER_TABLE_DEF_CHANGED
SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
SELECT * FROM t2;
COMMIT;
SELECT * FROM t2 FORCE INDEX(t2a) ORDER BY a;
connection default;
disconnect a;
disconnect b;
DROP TABLE t1,t2;
#
# restore environment to the state it was before this test execution

View file

@ -1,3 +1,2 @@
--default-storage-engine=MyISAM
--loose-innodb-use-sys-malloc=true
--loose-innodb-use-sys-malloc=true
--innodb-use-sys-malloc=true
--innodb-large-prefix=true

View file

@ -1,4 +1,4 @@
--source include/have_innodb.inc
-- source include/have_innodb.inc
#display current value of innodb_use_sys_malloc
SELECT @@GLOBAL.innodb_use_sys_malloc;
@ -13,36 +13,33 @@ SELECT @@GLOBAL.innodb_use_sys_malloc;
--echo 1 Expected
#do some stuff to see if it works.
--disable_warnings
drop table if exists t1;
--enable_warnings
# Do some stuff to see if it works.
# Also, test the code paths of
# Bug #12699505 MEMORY LEAK IN ROW_CREATE_INDEX_FOR_MYSQL()
# (the leak would only be triggered if
# ha_innobase::max_supported_key_part_length() were set
# higher than the limit used in row_create_index_for_mysql())
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
select * from t1;
drop table t1;
--source include/have_innodb.inc
#display current value of innodb_use_sys_malloc
SELECT @@GLOBAL.innodb_use_sys_malloc;
--echo 1 Expected
#try changing it. Should fail.
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
SET @@GLOBAL.innodb_use_sys_malloc=0;
--echo Expected error 'Read only variable'
SELECT @@GLOBAL.innodb_use_sys_malloc;
--echo 1 Expected
#do some stuff to see if it works.
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
--error ER_DUP_FIELDNAME
create table t1(a int not null,key(a,a)) engine=innodb DEFAULT CHARSET=latin1;
# thanks to --innodb-large-prefix=1 this will not be truncated to b(767)
-- error ER_INDEX_COLUMN_TOO_LONG
create table t1(a int,b text,key(b(768))) engine=innodb DEFAULT CHARSET=latin1;
create table t1(a int not null,b text) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,'');
--error ER_DUP_FIELDNAME
create index t1aa on t1(a,a);
-- error ER_INDEX_COLUMN_TOO_LONG
create index t1b on t1(b(768));
SHOW CREATE TABLE t1;
select * from t1;
drop table t1;
CREATE TABLE t2(a int primary key, b text) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,'');
--error ER_DUP_FIELDNAME
CREATE INDEX t2aa on t2(a,a);
-- error ER_INDEX_COLUMN_TOO_LONG
CREATE INDEX t2b on t2(b(768));
SELECT * FROM t2;
DROP TABLE t2;

View file

@ -9,6 +9,8 @@
# #
######################################################################
# Don't test this under valgrind, memory leaks will occur due restart
--source include/not_valgrind.inc
# Test restart the server and "shutdown_server" looks for pid file
# which is not there with embedded mode
--source include/not_embedded.inc

View file

@ -1,12 +1,13 @@
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009, 2011, Oracle and/or its affiliates. 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 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
# 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
@ -17,9 +18,15 @@
update performance_schema.setup_instruments set enabled='YES';
connection con1;
disconnect con1;
--source include/wait_until_disconnected.inc
connection con2;
disconnect con2;
--source include/wait_until_disconnected.inc
connection con3;
disconnect con3;
--source include/wait_until_disconnected.inc
connection default;

View file

@ -17,8 +17,10 @@
# $out_file and $err_file must be set within pfs_upgrade.test.
#
--source include/count_sessions.inc
--error 1
--exec $MYSQL_UPGRADE --skip-verbose --force > $out_file 2> $err_file
--source include/wait_until_count_sessions.inc
# Verify that mysql_upgrade complained about the performance_schema
--cat_file $err_file

View file

@ -52,10 +52,11 @@ select
EVENT_NAME,
if (count_star > 0, "MANY", "NONE") as COUNT_STAR
from performance_schema.events_waits_summary_global_by_event_name
where event_name like "%MYSQL_BIN_LOG%" order by event_name;
where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::update_cond"
order by event_name;
EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_prep_xids NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::update_cond MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_prep_xids NONE
"Expect no slave relay log"
@ -68,9 +69,10 @@ EVENT_NAME COUNT_READ COUNT_WRITE SUM_NUMBER_OF_BYTES_READ SUM_NUMBER_OF_BYTES_W
wait/io/file/sql/relaylog 0 0 0 0
wait/io/file/sql/relaylog_index 0 0 0 0
select * from performance_schema.events_waits_summary_global_by_event_name
where event_name like "%MYSQL_RELAY_LOG%" order by event_name;
where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name;
EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
wait/synch/cond/sql/MYSQL_RELAY_LOG::update_cond 0 0 0 0 0
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index 0 0 0 0 0
"============ Performance schema on slave ============"
select * from performance_schema.file_summary_by_instance
@ -123,10 +125,11 @@ select
EVENT_NAME,
if (count_star > 0, "MANY", "NONE") as COUNT_STAR
from performance_schema.events_waits_summary_global_by_event_name
where event_name like "%MYSQL_BIN_LOG%" order by event_name;
where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::update_cond"
order by event_name;
EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_BIN_LOG::COND_prep_xids NONE
wait/synch/cond/sql/MYSQL_BIN_LOG::update_cond NONE
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index MANY
wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_prep_xids NONE
"Expect a slave relay log"
@ -162,8 +165,9 @@ select
EVENT_NAME,
if (count_star > 0, "MANY", "NONE") as COUNT_STAR
from performance_schema.events_waits_summary_global_by_event_name
where event_name like "%MYSQL_RELAY_LOG%" order by event_name;
where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name;
EVENT_NAME COUNT_STAR
wait/synch/cond/sql/MYSQL_RELAY_LOG::update_cond MANY
wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index MANY
include/stop_slave.inc

View file

@ -62,6 +62,7 @@ SELECT EVENT_ID FROM performance_schema.events_waits_current
WHERE 1 = 2;
CREATE EVENT t_ps_event
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND
ON COMPLETION PRESERVE
DO INSERT INTO t_event
SELECT DISTINCT EVENT_ID
FROM performance_schema.events_waits_current
@ -106,5 +107,6 @@ EVENT_ID
[EVENT_ID]
DROP PROCEDURE t_ps_proc;
DROP FUNCTION t_ps_func;
DROP EVENT t_ps_event;
DROP TABLE t1;
DROP TABLE t_event;

View file

@ -41,6 +41,8 @@ drop table test.t1;
# To ensure robustness:
# - log file rotation is limited to file .000001 and .000002
# - statistics are normalized to "NONE" or "MANY"
# - statistics on ::update_cond conditions are not collected,
# since this is too much dependent on execution.
#
connection master;
@ -84,7 +86,9 @@ select
EVENT_NAME,
if (count_star > 0, "MANY", "NONE") as COUNT_STAR
from performance_schema.events_waits_summary_global_by_event_name
where event_name like "%MYSQL_BIN_LOG%" order by event_name;
where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::update_cond"
order by event_name;
-- echo "Expect no slave relay log"
@ -95,7 +99,9 @@ select * from performance_schema.file_summary_by_event_name
where event_name like "%relaylog%" order by event_name;
select * from performance_schema.events_waits_summary_global_by_event_name
where event_name like "%MYSQL_RELAY_LOG%" order by event_name;
where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name;
sync_slave_with_master;
-- echo "============ Performance schema on slave ============"
@ -142,7 +148,9 @@ select
EVENT_NAME,
if (count_star > 0, "MANY", "NONE") as COUNT_STAR
from performance_schema.events_waits_summary_global_by_event_name
where event_name like "%MYSQL_BIN_LOG%" order by event_name;
where event_name like "%MYSQL_BIN_LOG%"
and event_name not like "%MYSQL_BIN_LOG::update_cond"
order by event_name;
-- echo "Expect a slave relay log"
@ -173,7 +181,9 @@ select
EVENT_NAME,
if (count_star > 0, "MANY", "NONE") as COUNT_STAR
from performance_schema.events_waits_summary_global_by_event_name
where event_name like "%MYSQL_RELAY_LOG%" order by event_name;
where event_name like "%MYSQL_RELAY_LOG%"
and event_name not like "%MYSQL_RELAY_LOG::update_cond"
order by event_name;
--source include/stop_slave.inc

View file

@ -1,4 +1,4 @@
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2008, 2011, Oracle and/or its affiliates. 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
@ -97,6 +97,7 @@ SELECT EVENT_ID FROM performance_schema.events_waits_current
WHERE 1 = 2;
CREATE EVENT t_ps_event
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND
ON COMPLETION PRESERVE
DO INSERT INTO t_event
SELECT DISTINCT EVENT_ID
FROM performance_schema.events_waits_current
@ -168,7 +169,7 @@ delimiter ;|
SELECT t_ps_func(connection_id()) = @p_id;
# We might reach this point too early which means the event scheduler has not
# execute our "t_ps_event". Therefore we poll till the record was inserted
# executed our "t_ps_event". Therefore we poll till the record was inserted
# and run our test statement afterwards.
let $wait_timeout= 20;
let $wait_condition= SELECT COUNT(*) = 1 FROM t_event;
@ -179,5 +180,6 @@ SELECT * FROM t_event;
# Clean up
DROP PROCEDURE t_ps_proc;
DROP FUNCTION t_ps_func;
DROP EVENT t_ps_event;
DROP TABLE t1;
DROP TABLE t_event;

View file

@ -1073,6 +1073,33 @@ ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST;
DROP TABLE t1;
--echo #
--echo # Test for bug #12652385 - "61493: REORDERING COLUMNS TO POSITION
--echo # FIRST CAN CAUSE DATA TO BE CORRUPTED".
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
--echo # Use MyISAM engine as the fact that InnoDB doesn't support
--echo # in-place ALTER TABLE in cases when columns are being renamed
--echo # hides some bugs.
create table t1 (i int, j int) engine=myisam;
insert into t1 value (1, 2);
--echo # First, test for original problem described in the bug report.
select * from t1;
--echo # Change of column order by the below ALTER TABLE statement should
--echo # affect both column names and column contents.
alter table t1 modify column j int first;
select * from t1;
--echo # Now test for similar problem with the same root.
--echo # The below ALTER TABLE should change not only the name but
--echo # also the value for the last column of the table.
alter table t1 drop column i, add column k int default 0;
select * from t1;
--echo # Clean-up.
drop table t1;
--echo End of 5.1 tests
#

View file

@ -668,3 +668,36 @@ ALTER TABLE t1 COMMENT 'test';
UNLOCK TABLES;
DROP TABLE t1;
--echo #
--echo # Test for bug #12641342 - "61401: UPDATE PERFORMANCE DEGRADES
--echo # GRADUALLY IF A TRIGGER EXISTS".
--echo #
--echo # One of side-effects of this bug was that a transaction which
--echo # involved DML statements requiring prelocking blocked concurrent
--echo # FLUSH TABLES WITH READ LOCK for the whole its duration, while
--echo # correct behavior in this case is to block FTWRL only for duration
--echo # of individual DML statements.
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (id INT PRIMARY KEY, value INT);
INSERT INTO t1 VALUES (1, 1);
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW SET @var = "a";
BEGIN;
UPDATE t1 SET value= value + 1 WHERE id = 1;
--echo # Switching to connection 'con1'.
connect(con1, localhost, root);
--echo # The below FLUSH TABLES WITH READ LOCK should succeed and
--echo # should not be blocked by the transaction in default connection.
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
disconnect con1;
--source include/wait_until_disconnected.inc
--echo # Switching to connection 'default'.
connection default;
COMMIT;
DROP TABLE t1;

View file

@ -703,4 +703,50 @@ UPDATE t1 AS A, t1 AS B SET A.pk = 1, B.a = 2;
SELECT * FROM t1;
DROP TABLE t1;
--echo end of tests
--echo #
--echo # BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS
--echo # UPDATED TWICE
--echo #
# Results differ between storage engines. This test is to verify that
# the bugfix did NOT change behavior for MyISAM.
# See multi_update_innodb.test for the InnoDB variant of this test
CREATE TABLE t1 (
col_int_key int,
pk int,
col_int int,
key(col_int_key),
primary key (pk)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,2,3);
--echo
CREATE TABLE t2 (
col_int_key int,
pk_1 int,
pk_2 int,
col_int int,
key(col_int_key),
primary key (pk_1,pk_2)
) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1,2,3,4);
--echo
UPDATE t1 AS A NATURAL JOIN t1 B SET A.pk=5,B.pk=7;
--echo
SELECT * FROM t1;
--echo
UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_1=5,B.pk_1=7;
--echo
UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11;
--echo
SELECT * FROM t2;
DROP TABLE t1,t2;

View file

@ -31,3 +31,47 @@ SELECT * FROM t1;
DROP VIEW v1;
DROP TABLE t1;
--echo #
--echo # BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS
--echo # UPDATED TWICE
--echo #
# Results differ between storage engines.
# See multi_update.test for the MyISAM variant of this test
CREATE TABLE t1 (
col_int_key int,
pk int,
col_int int,
key(col_int_key),
primary key (pk)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,2,3);
--echo
CREATE TABLE t2 (
col_int_key int,
pk_1 int,
pk_2 int,
col_int int,
key(col_int_key),
primary key (pk_1,pk_2)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1,2,3,4);
--echo
--error ER_MULTI_UPDATE_KEY_CONFLICT
UPDATE t1 AS A NATURAL JOIN t1 B SET A.pk=5,B.pk=7;
--echo
SELECT * FROM t1;
--echo
--error ER_MULTI_UPDATE_KEY_CONFLICT
UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_1=5,B.pk_1=7;
--echo
--error ER_MULTI_UPDATE_KEY_CONFLICT
UPDATE t2 AS A NATURAL JOIN t2 B SET A.pk_2=10,B.pk_2=11;
--echo
SELECT * FROM t2;
DROP TABLE t1,t2;

View file

@ -0,0 +1,12 @@
--echo #
--echo # Bug#12561297 : LIBMYSQLD/EXAMPLE/MYSQL_EMBEDDED IS ABORTING.
--echo #
--source include/is_embedded.inc
# Test case require mysql_embedded to be present
if(!$MYSQL_EMBEDDED)
{
--skip Test requires mysql_embedded executable
}
--exec $MYSQL_EMBEDDED -e 'select 1'

View file

@ -14,6 +14,37 @@
drop table if exists t1, t2;
--enable_warnings
--echo #
--echo # Bug#11765667: bug#58655: ASSERTION FAILED,
--echo # SERVER CRASHES WITH MYSQLD GOT SIGNAL 6
--echo #
CREATE TABLE t1 (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
dt DATE, st VARCHAR(255), uid INT,
id2nd LONGBLOB, filler VARCHAR(255), PRIMARY KEY(id, dt)
);
INSERT INTO t1 (dt, st, uid, id2nd, filler) VALUES
('1991-03-14', 'Initial Insert', 200, 1234567, 'No Data'),
('1991-02-26', 'Initial Insert', 201, 1234567, 'No Data'),
('1992-03-16', 'Initial Insert', 234, 1234567, 'No Data'),
('1992-07-02', 'Initial Insert', 287, 1234567, 'No Data'),
('1991-05-26', 'Initial Insert', 256, 1234567, 'No Data'),
('1991-04-25', 'Initial Insert', 222, 1234567, 'No Data'),
('1993-03-12', 'Initial Insert', 267, 1234567, 'No Data'),
('1993-03-14', 'Initial Insert', 291, 1234567, 'No Data'),
('1991-12-20', 'Initial Insert', 298, 1234567, 'No Data'),
('1994-10-31', 'Initial Insert', 220, 1234567, 'No Data');
ALTER TABLE t1 PARTITION BY LIST (YEAR(dt)) (
PARTITION d1 VALUES IN (1991, 1994),
PARTITION d2 VALUES IN (1993),
PARTITION d3 VALUES IN (1992, 1995, 1996)
);
INSERT INTO t1 (dt, st, uid, id2nd, filler) VALUES
('1991-07-14', 'After Partitioning Insert', 299, 1234567, 'Insert row');
UPDATE t1 SET filler='Updating the row' WHERE uid=298;
DROP TABLE t1;
--echo #
--echo # Bug#59297: Can't find record in 'tablename' on update inner join
--echo #
@ -196,10 +227,16 @@ INSERT INTO t1 VALUES ('2009-07-14 17:35:55', 'pmax');
INSERT INTO t1 VALUES ('2009-09-21 17:31:42', 'pmax');
SELECT * FROM t1;
SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
EXPLAIN PARTITIONS SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
EXPLAIN PARTITIONS SELECT * FROM t1 where a = '2007-07-30 17:35:48';
ALTER TABLE t1 REORGANIZE PARTITION pmax INTO (
PARTITION p3 VALUES LESS THAN (1247688000),
PARTITION pmax VALUES LESS THAN MAXVALUE);
SELECT * FROM t1;
SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
EXPLAIN PARTITIONS SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01';
EXPLAIN PARTITIONS SELECT * FROM t1 where a = '2007-07-30 17:35:48';
SHOW CREATE TABLE t1;
DROP TABLE t1;

View file

@ -7,6 +7,7 @@
# BUG#48164 limited size to 3072 bytes
#
-- source include/have_partition.inc
-- source include/have_innodb.inc
--disable_warnings
drop table if exists t1;
@ -233,3 +234,312 @@ show create table t1;
insert into t1 values (1),(4),(7),(10),(13),(16),(19),(22),(25),(28),(31),(34);
select hex(a) from t1 where a = 7;
drop table t1;
--echo #
--echo # Bug#28928: UNIX_TIMESTAMP() should be considered unary monotonic
--echo # by partition pruning
SET @old_time_zone= @@session.time_zone;
SET @@session.time_zone = 'UTC';
--echo # Using MyISAM to get stable values on TABLE_ROWS in I_S.PARTITIONS
CREATE TABLE t1
(a TIMESTAMP NULL,
tz varchar(16))
ENGINE = MyISAM;
CREATE TABLE t2 LIKE t1;
ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a))
(PARTITION `p0` VALUES LESS THAN (0),
PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01')),
PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP('2011-03-26 23:00:00')),
PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-29 22:00:00')),
PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-29 23:00:00')),
PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-30 00:00:00')),
PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP('2012-03-24 23:00:00')),
PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP('2038-01-19 03:14:07')),
PARTITION `pMax` VALUES LESS THAN MAXVALUE);
--echo # Test 'odd' values
INSERT INTO t1 VALUES (NULL, 'UTC');
INSERT INTO t1 VALUES ('0000-00-00 00:00:00', 'UTC');
--echo # Test invalid values
INSERT INTO t1 VALUES ('1901-01-01 00:00:00', 'UTCI');
INSERT INTO t1 VALUES ('1969-12-31 23:59:59', 'UTCI');
INSERT INTO t1 VALUES ('2038-01-19 03:14:08', 'UTCI');
INSERT INTO t1 VALUES ('1970-01-01 00:00:00', 'UTCI');
--echo # Test start range
INSERT INTO t1 VALUES ('1970-01-01 00:00:01', 'UTC');
INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'UTC');
--echo # Test end range
INSERT INTO t1 VALUES ('2038-01-19 03:14:06', 'UTC');
INSERT INTO t1 VALUES ('2038-01-19 03:14:07', 'UTC');
--echo # Test Daylight saving shift
INSERT INTO t1 VALUES ('2011-03-26 22:59:59', 'UTC');
INSERT INTO t1 VALUES ('2011-03-26 23:00:00', 'UTC');
INSERT INTO t1 VALUES ('2011-03-26 23:00:01', 'UTC');
INSERT INTO t1 VALUES ('2011-10-29 21:59:59', 'UTC');
INSERT INTO t1 VALUES ('2011-10-29 22:00:00', 'UTC');
INSERT INTO t1 VALUES ('2011-10-29 22:00:01', 'UTC');
INSERT INTO t1 VALUES ('2011-10-29 22:59:59', 'UTC');
INSERT INTO t1 VALUES ('2011-10-29 23:00:00', 'UTC');
INSERT INTO t1 VALUES ('2011-10-29 23:00:01', 'UTC');
INSERT INTO t1 VALUES ('2011-10-29 23:59:59', 'UTC');
INSERT INTO t1 VALUES ('2011-10-30 00:00:00', 'UTC');
INSERT INTO t1 VALUES ('2011-10-30 00:00:01', 'UTC');
SET @@session.time_zone = 'Europe/Moscow';
--echo # Test 'odd' values
INSERT INTO t1 VALUES (NULL, 'Moscow');
INSERT INTO t1 VALUES ('0000-00-00 00:00:00', 'Moscow');
--echo # Test invalid values
INSERT INTO t1 VALUES ('0000-00-00 03:00:00', 'MoscowI');
INSERT INTO t1 VALUES ('1901-01-01 00:00:00', 'MoscowI');
INSERT INTO t1 VALUES ('1969-12-31 23:59:59', 'MoscowI');
INSERT INTO t1 VALUES ('1970-01-01 02:29:29', 'MoscowI');
INSERT INTO t1 VALUES ('2038-01-19 06:14:08', 'MoscowI');
INSERT INTO t1 VALUES ('1970-01-01 03:00:00', 'MoscowI');
--echo # values truncated to 03:00:00 due to daylight saving shift
INSERT INTO t1 VALUES ('2011-03-27 02:00:00', 'MoscowI');
INSERT INTO t1 VALUES ('2011-03-27 02:00:01', 'MoscowI');
INSERT INTO t1 VALUES ('2011-03-27 02:59:59', 'MoscowI');
--echo # Test start range
INSERT INTO t1 VALUES ('1970-01-01 03:00:01', 'Moscow');
INSERT INTO t1 VALUES ('1974-02-05 21:28:16', 'Moscow');
--echo # Test end range
INSERT INTO t1 VALUES ('2038-01-19 06:14:06', 'Moscow');
INSERT INTO t1 VALUES ('2038-01-19 06:14:07', 'Moscow');
--echo # Test Daylight saving shift
INSERT INTO t1 VALUES ('2011-03-27 01:59:59', 'Moscow');
INSERT INTO t1 VALUES ('2011-03-27 03:00:00', 'Moscow');
INSERT INTO t1 VALUES ('2011-03-27 03:00:01', 'Moscow');
INSERT INTO t1 VALUES ('2011-10-30 01:59:59', 'Moscow');
--echo # All values between 02:00 and 02:59:59 will be interpretated as DST
INSERT INTO t1 VALUES ('2011-10-30 02:00:00', 'MoscowD');
INSERT INTO t1 VALUES ('2011-10-30 02:00:01', 'MoscowD');
INSERT INTO t1 VALUES ('2011-10-30 02:59:59', 'MoscowD');
INSERT INTO t1 VALUES ('2011-10-30 03:00:00', 'Moscow');
INSERT INTO t1 VALUES ('2011-10-30 03:00:01', 'Moscow');
SET @@session.time_zone = 'UTC';
INSERT INTO t2 SELECT * FROM t1;
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 't2';
SELECT * FROM t1 ORDER BY a, tz;
SELECT * FROM t2 ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 23:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 23:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 22:59:59' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-26 22:59:59' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-03-26 22:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-03-26 22:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-03-26 23:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-03-26 23:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 23:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 23:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 22:59:59' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 22:59:59' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 22:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 22:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 23:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 23:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
--echo # Test end range changes
DELETE FROM t2 WHERE a = 0;
INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC');
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t2 WHERE a = 0;
SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
UPDATE t2 SET a = TIMESTAMPADD(SECOND, 1, a);
SELECT MIN(a), MAX(a) FROM t2;
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t2 WHERE a = 0;
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 't2';
SELECT * FROM t2 ORDER BY a, tz;
--echo # Test start range changes
INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'UTC');
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t2 WHERE a = 0;
SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
UPDATE t2 SET a = TIMESTAMPADD(SECOND, -1, a);
SELECT MIN(a), MAX(a) FROM t2;
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t2 WHERE a = 0;
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 't2';
SELECT * FROM t2 ORDER BY a, tz;
SHOW CREATE TABLE t2;
TRUNCATE TABLE t2;
SET @@session.time_zone = 'Europe/Moscow';
INSERT INTO t2 SELECT * FROM t1;
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 't2';
SELECT * FROM t1 ORDER BY a, tz;
SELECT * FROM t2 ORDER BY a, tz;
--echo # Testing the leap from 01:59:59 to 03:00:00
SELECT * FROM t2
WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 03:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 03:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 01:59:59' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-03-01 00:00:00' and '2011-03-27 01:59:59' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-03-26 01:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-03-26 01:59:59' and '2011-03-28 00:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-03-26 03:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-03-26 03:00:00' and '2011-03-28 00:00:00' ORDER BY a, tz;
--echo # Testing the leap from 02:59:59 to 02:00:00
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:59:59' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 02:59:59' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 03:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 03:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 01:59:59' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-01 00:00:00' and '2011-10-29 01:59:59' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 02:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 02:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 02:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 02:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 03:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 03:00:00' and '2011-10-31 00:00:00' ORDER BY a, tz;
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 01:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
EXPLAIN PARTITIONS
SELECT * FROM t2
WHERE a BETWEEN '2011-10-29 01:59:59' and '2011-10-31 00:00:00' ORDER BY a, tz;
--echo # Test end range changes
DELETE FROM t2 WHERE a = 0;
INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow');
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t2 WHERE a = 0;
SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
UPDATE t2 SET a = TIMESTAMPADD(SECOND, 1, a);
SELECT MIN(a), MAX(a) FROM t2;
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t2 WHERE a = 0;
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 't2';
SELECT * FROM t2 ORDER BY a, tz;
--echo # Test start range changes
INSERT INTO t2 VALUES ('1970-01-01 00:00:00', 'Moscow');
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t2 WHERE a = 0;
SELECT * FROM t2 ORDER BY a, tz LIMIT 3;
SELECT * FROM t2 ORDER BY a DESC, tz LIMIT 3;
UPDATE t2 SET a = TIMESTAMPADD(SECOND, -1, a);
SELECT MIN(a), MAX(a) FROM t2;
SELECT COUNT(*) FROM t2;
SELECT COUNT(*) FROM t2 WHERE a = 0;
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 't2';
SELECT * FROM t2 ORDER BY a, tz;
SHOW CREATE TABLE t2;
TRUNCATE TABLE t2;
DROP TABLE t1, t2;
SET @@session.time_zone= @old_time_zone;

View file

@ -1,7 +1,7 @@
# This test should work in embedded server after mysqltest is fixed
-- source include/not_embedded.inc
--echo Tests of syncronization of stored procedure execution.
--echo Tests of synchronization of stored procedure execution.
--source include/have_debug_sync.inc
@ -149,9 +149,34 @@ disconnect con2;
DROP PROCEDURE p1;
DROP FUNCTION f1;
DROP TABLES t0, t1;
SET DEBUG_SYNC= 'RESET';
--echo #
--echo # test for bug#11756013
--echo #
--disable_warnings
DROP SCHEMA IF EXISTS s1;
--enable_warnings
CREATE SCHEMA s1;
CREATE PROCEDURE s1.p1() BEGIN END;
connect (con3, localhost, root);
SET DEBUG_SYNC='before_db_dir_check SIGNAL check_db WAIT_FOR dropped_schema';
--send CALL s1.p1
connection default;
SET DEBUG_SYNC='now WAIT_FOR check_db';
DROP SCHEMA s1;
SET DEBUG_SYNC='now SIGNAL dropped_schema';
connection con3;
--error ER_BAD_DB_ERROR
--reap
connection default;
disconnect con3;
SET DEBUG_SYNC = 'RESET';
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -193,7 +193,7 @@ size_t cleanup_dirname(register char *to, const char *from)
while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */
pos--;
if (pos[1] == FN_HOMELIB ||
(pos > start && memcmp(pos, parent, length) == 0))
(pos >= start && memcmp(pos, parent, length) == 0))
{ /* Don't remove ~user/ */
pos=strmov(end_parentdir+1,parent);
*pos=FN_LIBCHAR;

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2001, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2006, 2011, Oracle and/or its affiliates. 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

View file

@ -1,6 +1,8 @@
#ifndef _EVENT_DB_REPOSITORY_H_
#define _EVENT_DB_REPOSITORY_H_
/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2006, 2011, Oracle and/or its affiliates. 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
@ -13,7 +15,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
@addtogroup Event_Scheduler

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2008, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2008, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
@file

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2006, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "sql_priv.h"
#include "unireg.h" // REQUIRED: for other includes

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
This handler was developed by Mikael Ronstrom for version 5.1 of MySQL.
@ -3456,9 +3458,13 @@ exit:
index)
mysql_update does not set table->next_number_field, so we use
table->found_next_number_field instead.
Also checking that the field is marked in the write set.
*/
if (table->found_next_number_field && new_data == table->record[0] &&
!table->s->next_number_keypart)
if (table->found_next_number_field &&
new_data == table->record[0] &&
!table->s->next_number_keypart &&
bitmap_is_set(table->write_set,
table->found_next_number_field->field_index))
{
if (!table_share->ha_part_data->auto_inc_initialized)
info(HA_STATUS_AUTO);
@ -4110,6 +4116,7 @@ void ha_partition::position(const uchar *record)
void ha_partition::column_bitmaps_signal()
{
handler::column_bitmaps_signal();
/* Must read all partition fields to make position() call possible */
bitmap_union(table->read_set, &m_part_info->full_part_field_set);
}

View file

@ -1,7 +1,8 @@
#ifndef HA_PARTITION_INCLUDED
#define HA_PARTITION_INCLUDED
/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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

View file

@ -1,7 +1,8 @@
#ifndef HANDLER_INCLUDED
#define HANDLER_INCLUDED
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -15,8 +16,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Definitions for parameters to do with handler-routines */

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
@file

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -1388,6 +1389,26 @@ longlong Item_func_unix_timestamp::val_int()
return (longlong) TIME_to_timestamp(current_thd, &ltime, &not_used);
}
enum_monotonicity_info Item_func_unix_timestamp::get_monotonicity_info() const
{
if (args[0]->type() == Item::FIELD_ITEM &&
(args[0]->field_type() == MYSQL_TYPE_TIMESTAMP))
return MONOTONIC_INCREASING;
return NON_MONOTONIC;
}
longlong Item_func_unix_timestamp::val_int_endpoint(bool left_endp, bool *incl_endp)
{
DBUG_ASSERT(fixed == 1);
DBUG_ASSERT(arg_count == 1 &&
args[0]->type() == Item::FIELD_ITEM &&
args[0]->field_type() == MYSQL_TYPE_TIMESTAMP);
Field *field=((Item_field*) args[0])->field;
/* Leave the incl_endp intact */
return ((Field_timestamp*) field)->get_timestamp(&null_value);
}
longlong Item_func_time_to_sec::val_int()
{

View file

@ -391,6 +391,8 @@ public:
Item_func_unix_timestamp(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "unix_timestamp"; }
enum_monotonicity_info get_monotonicity_info() const;
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
/*
UNIX_TIMESTAMP() depends on the current timezone

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,6 +1,6 @@
#ifndef MDL_H
#define MDL_H
/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2009, 2011, Oracle and/or its affiliates. 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
@ -152,11 +152,24 @@ enum enum_mdl_type {
/** Duration of metadata lock. */
enum enum_mdl_duration { MDL_STATEMENT= 0,
MDL_TRANSACTION,
MDL_EXPLICIT,
/* This should be the last ! */
MDL_DURATION_END };
enum enum_mdl_duration {
/**
Locks with statement duration are automatically released at the end
of statement or transaction.
*/
MDL_STATEMENT= 0,
/**
Locks with transaction duration are automatically released at the end
of transaction.
*/
MDL_TRANSACTION,
/**
Locks with explicit duration survive the end of statement and transaction.
They have to be released explicitly by calling MDL_context::release_lock().
*/
MDL_EXPLICIT,
/* This should be the last ! */
MDL_DURATION_END };
/** Maximal length of key for metadata locking subsystem. */

View file

@ -7633,6 +7633,7 @@ static int fix_paths(void)
{
if (*opt_secure_file_priv == 0)
{
my_free(opt_secure_file_priv);
opt_secure_file_priv= 0;
}
else

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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
@ -756,6 +757,43 @@ static sp_head *sp_compile(THD *thd, String *defstr, ulong sql_mode,
}
class Bad_db_error_handler : public Internal_error_handler
{
public:
Bad_db_error_handler()
:m_error_caught(false)
{}
virtual bool handle_condition(THD *thd,
uint sql_errno,
const char* sqlstate,
MYSQL_ERROR::enum_warning_level level,
const char* message,
MYSQL_ERROR ** cond_hdl);
bool error_caught() const { return m_error_caught; }
private:
bool m_error_caught;
};
bool
Bad_db_error_handler::handle_condition(THD *thd,
uint sql_errno,
const char* sqlstate,
MYSQL_ERROR::enum_warning_level level,
const char* message,
MYSQL_ERROR ** cond_hdl)
{
if (sql_errno == ER_BAD_DB_ERROR)
{
m_error_caught= true;
return true;
}
return false;
}
static int
db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
ulong sql_mode, const char *params, const char *returns,
@ -769,7 +807,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed;
Bad_db_error_handler db_not_exists_handler;
char definer_user_name_holder[USERNAME_LENGTH + 1];
LEX_STRING definer_user_name= { definer_user_name_holder,
USERNAME_LENGTH };
@ -808,6 +846,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
goto end;
}
thd->push_internal_handler(&db_not_exists_handler);
/*
Change the current database (if needed).
@ -818,6 +857,15 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
&cur_db_changed))
{
ret= SP_INTERNAL_ERROR;
thd->pop_internal_handler();
goto end;
}
thd->pop_internal_handler();
if (db_not_exists_handler.error_caught())
{
ret= SP_INTERNAL_ERROR;
my_error(ER_BAD_DB_ERROR, MYF(0), name->m_db.str);
goto end;
}

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*****************************************************************************
@ -3790,16 +3792,24 @@ void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var)
void THD::leave_locked_tables_mode()
{
if (locked_tables_mode == LTM_LOCK_TABLES)
{
/*
When leaving LOCK TABLES mode we have to change the duration of most
of the metadata locks being held, except for HANDLER and GRL locks,
to transactional for them to be properly released at UNLOCK TABLES.
*/
mdl_context.set_transaction_duration_for_all_locks();
/*
Make sure we don't release the global read lock and commit blocker
when leaving LTM.
*/
global_read_lock.set_explicit_lock_duration(this);
/* Also ensure that we don't release metadata locks for open HANDLERs. */
if (handler_tables_hash.records)
mysql_ha_set_explicit_lock_duration(this);
}
locked_tables_mode= LTM_NONE;
mdl_context.set_transaction_duration_for_all_locks();
/*
Make sure we don't release the global read lock and commit blocker
when leaving LTM.
*/
global_read_lock.set_explicit_lock_duration(this);
/* Also ensure that we don't release metadata locks for open HANDLERs. */
if (handler_tables_hash.records)
mysql_ha_set_explicit_lock_duration(this);
}
void THD::get_definer(LEX_USER *definer)

View file

@ -2795,7 +2795,19 @@ public:
{
DBUG_ASSERT(locked_tables_mode == LTM_NONE);
mdl_context.set_explicit_duration_for_all_locks();
if (mode_arg == LTM_LOCK_TABLES)
{
/*
When entering LOCK TABLES mode we should set explicit duration
for all metadata locks acquired so far in order to avoid releasing
them till UNLOCK TABLES statement.
We don't do this when entering prelocked mode since sub-statements
don't release metadata locks and restoring status-quo after leaving
prelocking mode gets complicated.
*/
mdl_context.set_explicit_duration_for_all_locks();
}
locked_tables_mode= mode_arg;
}
void leave_locked_tables_mode();

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
Functions to autenticate and handle reqests for a connection

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -39,6 +40,7 @@
#ifdef __WIN__
#include <direct.h>
#endif
#include "debug_sync.h"
#define MAX_DROP_TABLE_Q_LEN 1024
@ -1536,6 +1538,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
}
#endif
DEBUG_SYNC(thd, "before_db_dir_check");
if (check_db_dir_existence(new_db_file_name.str))
{
if (force_switch)

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Insert of records */

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1308,7 +1308,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
length= my_snprintf(buff, buff_len - 1,
"Uptime: %lu Threads: %d Questions: %lu "
"Slow queries: %lu Opens: %lu Flush tables: %lu "
"Open tables: %u Queries per second avg: %u.%u",
"Open tables: %u Queries per second avg: %u.%03u",
uptime,
(int) thread_count, (ulong) thd->query_id,
current_global_status_var.long_query_count,
@ -2027,6 +2027,11 @@ mysql_execute_command(THD *thd)
*/
if (stmt_causes_implicit_commit(thd, CF_IMPLICT_COMMIT_BEGIN))
{
/*
Note that this should never happen inside of stored functions
or triggers as all such statements prohibited there.
*/
DBUG_ASSERT(! thd->in_sub_stmt);
/* Commit or rollback the statement transaction. */
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
/* Commit the normal transaction if one is active. */

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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 */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* drop and alter of tables */
@ -5326,6 +5328,12 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (drop)
{
drop_it.remove();
/*
ALTER TABLE DROP COLUMN always changes table data even in cases
when new version of the table has the same structure as the old
one.
*/
alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
continue;
}
/* Check if field is changed */
@ -5403,7 +5411,14 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (!def->after)
new_create_list.push_back(def);
else if (def->after == first_keyword)
{
new_create_list.push_front(def);
/*
Re-ordering columns in table can't be done using in-place algorithm
as it always changes table data.
*/
alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
}
else
{
Create_field *find;
@ -5419,6 +5434,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
goto err;
}
find_it.after(def); // Put element after this
/*
Re-ordering columns in table can't be done using in-place algorithm
as it always changes table data.
*/
alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
}
}

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2004, 2011, Oracle and/or its affiliates. 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

View file

@ -1,7 +1,8 @@
#ifndef SQL_TRIGGER_INCLUDED
#define SQL_TRIGGER_INCLUDED
/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2004, 2011, Oracle and/or its affiliates. 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

View file

@ -1071,17 +1071,27 @@ bool unsafe_key_update(TABLE_LIST *leaves, table_map tables_for_update)
return true;
}
if (primkey_clustered &&
(bitmap_is_set(table1->write_set, table1->s->primary_key) ||
bitmap_is_set(table2->write_set, table2->s->primary_key)))
if (primkey_clustered)
{
// Clustered primary key is updated
my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0),
tl->belong_to_view ? tl->belong_to_view->alias
: tl->alias,
tl2->belong_to_view ? tl2->belong_to_view->alias
: tl2->alias);
return true;
// The primary key can cover multiple columns
KEY key_info= table1->key_info[table1->s->primary_key];
KEY_PART_INFO *key_part= key_info.key_part;
KEY_PART_INFO *key_part_end= key_part + key_info.key_parts;
for (;key_part != key_part_end; ++key_part)
{
if (bitmap_is_set(table1->write_set, key_part->fieldnr-1) ||
bitmap_is_set(table2->write_set, key_part->fieldnr-1))
{
// Clustered primary key is updated
my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0),
tl->belong_to_view ? tl->belong_to_view->alias
: tl->alias,
tl2->belong_to_view ? tl2->belong_to_view->alias
: tl2->alias);
return true;
}
}
}
}
}

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -627,8 +627,8 @@ struct TABLE_SHARE
uint db_options_in_use; /* Options in use */
uint db_record_offset; /* if HA_REC_IN_SEQ */
uint rowid_field_offset; /* Field_nr +1 to rowid field */
/* Index of auto-updated TIMESTAMP field in field array */
uint primary_key;
/* Primary key index number, used in TABLE::key_info[] */
uint primary_key;
uint next_number_index; /* autoincrement key number */
uint next_number_key_offset; /* autoinc keypart offset in a key */
uint next_number_keypart; /* autoinc keypart number in a key */

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@ -11,7 +12,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
Functions to create a unireg form-file from a FIELD and a fieldname-fieldinfo

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2004, 2011, Oracle and/or its affiliates. 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
@ -12,8 +13,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA */
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1994, 2011, Oracle and/or its affiliates. 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
@ -2275,7 +2275,7 @@ btr_attach_half_pages(
/*==================*/
dict_index_t* index, /*!< in: the index tree */
buf_block_t* block, /*!< in/out: page to be split */
rec_t* split_rec, /*!< in: first record on upper
const rec_t* split_rec, /*!< in: first record on upper
half page */
buf_block_t* new_block, /*!< in/out: the new half page */
ulint direction, /*!< in: FSP_UP or FSP_DOWN */
@ -2967,15 +2967,16 @@ btr_node_ptr_delete(
ut_a(err == DB_SUCCESS);
if (!compressed) {
btr_cur_compress_if_useful(&cursor, mtr);
btr_cur_compress_if_useful(&cursor, FALSE, mtr);
}
}
/*************************************************************//**
If page is the only on its level, this function moves its records to the
father page, thus reducing the tree height. */
father page, thus reducing the tree height.
@return father block */
static
void
buf_block_t*
btr_lift_page_up(
/*=============*/
dict_index_t* index, /*!< in: index tree */
@ -3092,6 +3093,8 @@ btr_lift_page_up(
}
ut_ad(page_validate(father_page, index));
ut_ad(btr_check_node_ptr(index, father_block, mtr));
return(father_block);
}
/*************************************************************//**
@ -3108,11 +3111,13 @@ UNIV_INTERN
ibool
btr_compress(
/*=========*/
btr_cur_t* cursor, /*!< in: cursor on the page to merge or lift;
the page must not be empty: in record delete
use btr_discard_page if the page would become
empty */
mtr_t* mtr) /*!< in: mtr */
btr_cur_t* cursor, /*!< in/out: cursor on the page to merge
or lift; the page must not be empty:
when deleting records, use btr_discard_page()
if the page would become empty */
ibool adjust, /*!< in: TRUE if should adjust the
cursor position even if compression occurs */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
dict_index_t* index;
ulint space;
@ -3130,12 +3135,14 @@ btr_compress(
ulint* offsets;
ulint data_size;
ulint n_recs;
ulint nth_rec = 0; /* remove bogus warning */
ulint max_ins_size;
ulint max_ins_size_reorg;
block = btr_cur_get_block(cursor);
page = btr_cur_get_page(cursor);
index = btr_cur_get_index(cursor);
ut_a((ibool) !!page_is_comp(page) == dict_table_is_comp(index->table));
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
@ -3156,6 +3163,10 @@ btr_compress(
offsets = btr_page_get_father_block(NULL, heap, index, block, mtr,
&father_cursor);
if (adjust) {
nth_rec = page_rec_get_n_recs_before(btr_cur_get_rec(cursor));
}
/* Decide the page to which we try to merge and which will inherit
the locks */
@ -3182,9 +3193,9 @@ btr_compress(
} else {
/* The page is the only one on the level, lift the records
to the father */
btr_lift_page_up(index, block, mtr);
mem_heap_free(heap);
return(TRUE);
merge_block = btr_lift_page_up(index, block, mtr);
goto func_exit;
}
n_recs = page_get_n_recs(page);
@ -3266,6 +3277,10 @@ err_exit:
btr_node_ptr_delete(index, block, mtr);
lock_update_merge_left(merge_block, orig_pred, block);
if (adjust) {
nth_rec += page_rec_get_n_recs_before(orig_pred);
}
} else {
rec_t* orig_succ;
#ifdef UNIV_BTR_DEBUG
@ -3330,7 +3345,6 @@ err_exit:
}
btr_blob_dbg_remove(page, index, "btr_compress");
mem_heap_free(heap);
if (!dict_index_is_clust(index) && page_is_leaf(merge_page)) {
/* Update the free bits of the B-tree page in the
@ -3382,6 +3396,16 @@ err_exit:
btr_page_free(index, block, mtr);
ut_ad(btr_check_node_ptr(index, merge_block, mtr));
func_exit:
mem_heap_free(heap);
if (adjust) {
btr_cur_position(
index,
page_rec_get_nth(merge_block->frame, nth_rec),
merge_block, cursor);
}
return(TRUE);
}

View file

@ -1972,7 +1972,6 @@ btr_cur_optimistic_update(
ulint old_rec_size;
dtuple_t* new_entry;
roll_ptr_t roll_ptr;
trx_t* trx;
mem_heap_t* heap;
ulint i;
ulint n_ext;
@ -1990,7 +1989,8 @@ btr_cur_optimistic_update(
heap = mem_heap_create(1024);
offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(rec, offsets));
ut_a(!rec_offs_any_null_extern(rec, offsets)
|| trx_is_recv(thr_get_trx(thr)));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
#ifdef UNIV_DEBUG
@ -2114,13 +2114,11 @@ any_extern:
page_cur_move_to_prev(page_cursor);
trx = thr_get_trx(thr);
if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR,
roll_ptr);
row_upd_index_entry_sys_field(new_entry, index, DATA_TRX_ID,
trx->id);
thr_get_trx(thr)->id);
}
/* There are no externally stored columns in new_entry */
@ -2206,7 +2204,9 @@ btr_cur_pessimistic_update(
/*=======================*/
ulint flags, /*!< in: undo logging, locking, and rollback
flags */
btr_cur_t* cursor, /*!< in: cursor on the record to update */
btr_cur_t* cursor, /*!< in/out: cursor on the record to update;
cursor may become invalid if *big_rec == NULL
|| !(flags & BTR_KEEP_POS_FLAG) */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or NULL */
@ -2345,7 +2345,7 @@ btr_cur_pessimistic_update(
record to be inserted: we have to remember which fields were such */
ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec));
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, heap);
ut_ad(rec_offs_validate(rec, index, offsets));
n_ext += btr_push_update_extern_fields(new_entry, update, *heap);
if (UNIV_LIKELY_NULL(page_zip)) {
@ -2368,6 +2368,10 @@ make_external:
err = DB_TOO_BIG_RECORD;
goto return_after_reservations;
}
ut_ad(page_is_leaf(page));
ut_ad(dict_index_is_clust(index));
ut_ad(flags & BTR_KEEP_POS_FLAG);
}
/* Store state of explicit locks on rec on the page infimum record,
@ -2395,6 +2399,8 @@ make_external:
rec = btr_cur_insert_if_possible(cursor, new_entry, n_ext, mtr);
if (rec) {
page_cursor->rec = rec;
lock_rec_restore_from_page_infimum(btr_cur_get_block(cursor),
rec, block);
@ -2408,7 +2414,10 @@ make_external:
rec, index, offsets, mtr);
}
btr_cur_compress_if_useful(cursor, mtr);
btr_cur_compress_if_useful(
cursor,
big_rec_vec != NULL && (flags & BTR_KEEP_POS_FLAG),
mtr);
if (page_zip && !dict_index_is_clust(index)
&& page_is_leaf(page)) {
@ -2428,6 +2437,21 @@ make_external:
}
}
if (big_rec_vec) {
ut_ad(page_is_leaf(page));
ut_ad(dict_index_is_clust(index));
ut_ad(flags & BTR_KEEP_POS_FLAG);
/* btr_page_split_and_insert() in
btr_cur_pessimistic_insert() invokes
mtr_memo_release(mtr, index->lock, MTR_MEMO_X_LOCK).
We must keep the index->lock when we created a
big_rec, so that row_upd_clust_rec() can store the
big_rec in the same mini-transaction. */
mtr_x_lock(dict_index_get_lock(index), mtr);
}
/* Was the record to be updated positioned as the first user
record on its page? */
was_first = page_cur_is_before_first(page_cursor);
@ -2443,6 +2467,7 @@ make_external:
ut_a(rec);
ut_a(err == DB_SUCCESS);
ut_a(dummy_big_rec == NULL);
page_cursor->rec = rec;
if (dict_index_is_sec_or_ibuf(index)) {
/* Update PAGE_MAX_TRX_ID in the index page header.
@ -2501,6 +2526,39 @@ return_after_reservations:
return(err);
}
/**************************************************************//**
Commits and restarts a mini-transaction so that it will retain an
x-lock on index->lock and the cursor page. */
UNIV_INTERN
void
btr_cur_mtr_commit_and_start(
/*=========================*/
btr_cur_t* cursor, /*!< in: cursor */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
buf_block_t* block;
block = btr_cur_get_block(cursor);
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(cursor->index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
/* Keep the locks across the mtr_commit(mtr). */
rw_lock_x_lock(dict_index_get_lock(cursor->index));
rw_lock_x_lock(&block->lock);
mutex_enter(&block->mutex);
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
mutex_exit(&block->mutex);
/* Write out the redo log. */
mtr_commit(mtr);
mtr_start(mtr);
/* Reassociate the locks with the mini-transaction.
They will be released on mtr_commit(mtr). */
mtr_memo_push(mtr, dict_index_get_lock(cursor->index),
MTR_MEMO_X_LOCK);
mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);
}
/*==================== B-TREE DELETE MARK AND UNMARK ===============*/
/****************************************************************//**
@ -2881,10 +2939,12 @@ UNIV_INTERN
ibool
btr_cur_compress_if_useful(
/*=======================*/
btr_cur_t* cursor, /*!< in: cursor on the page to compress;
cursor does not stay valid if compression
occurs */
mtr_t* mtr) /*!< in: mtr */
btr_cur_t* cursor, /*!< in/out: cursor on the page to compress;
cursor does not stay valid if !adjust and
compression occurs */
ibool adjust, /*!< in: TRUE if should adjust the
cursor position even if compression occurs */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ut_ad(mtr_memo_contains(mtr,
dict_index_get_lock(btr_cur_get_index(cursor)),
@ -2893,7 +2953,7 @@ btr_cur_compress_if_useful(
MTR_MEMO_PAGE_X_FIX));
return(btr_cur_compress_recommendation(cursor, mtr)
&& btr_compress(cursor, mtr));
&& btr_compress(cursor, adjust, mtr));
}
/*******************************************************//**
@ -3135,7 +3195,7 @@ return_after_reservations:
mem_heap_free(heap);
if (ret == FALSE) {
ret = btr_cur_compress_if_useful(cursor, mtr);
ret = btr_cur_compress_if_useful(cursor, FALSE, mtr);
}
if (n_extents > 0) {
@ -4095,7 +4155,7 @@ btr_blob_free(
&& buf_block_get_space(block) == space
&& buf_block_get_page_no(block) == page_no) {
if (buf_LRU_free_block(&block->page, all) != BUF_LRU_FREED
if (!buf_LRU_free_block(&block->page, all)
&& all && block->page.zip.data) {
/* Attempt to deallocate the uncompressed page
if the whole block cannot be deallocted. */

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2006, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 2006, 2011, Oracle and/or its affiliates. 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
@ -56,6 +56,14 @@ buf_buddy_get(
}
}
/** Validate a given zip_free list. */
#define BUF_BUDDY_LIST_VALIDATE(b, i) \
UT_LIST_VALIDATE(list, buf_page_t, \
b->zip_free[i], \
ut_ad(buf_page_get_state( \
ut_list_node_313) \
== BUF_BLOCK_ZIP_FREE))
/**********************************************************************//**
Add a block to the head of the appropriate buddy free list. */
UNIV_INLINE
@ -67,21 +75,10 @@ buf_buddy_add_to_free(
ulint i) /*!< in: index of
buf_pool->zip_free[] */
{
#ifdef UNIV_DEBUG_VALGRIND
buf_page_t* b = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
#endif /* UNIV_DEBUG_VALGRIND */
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
ut_ad(buf_pool->zip_free[i].start != bpage);
UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
#ifdef UNIV_DEBUG_VALGRIND
if (b) UNIV_MEM_FREE(b, BUF_BUDDY_LOW << i);
UNIV_MEM_ASSERT_AND_FREE(bpage, BUF_BUDDY_LOW << i);
#endif /* UNIV_DEBUG_VALGRIND */
}
/**********************************************************************//**
@ -95,25 +92,17 @@ buf_buddy_remove_from_free(
ulint i) /*!< in: index of
buf_pool->zip_free[] */
{
#ifdef UNIV_DEBUG_VALGRIND
#ifdef UNIV_DEBUG
buf_page_t* prev = UT_LIST_GET_PREV(list, bpage);
buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
if (prev) UNIV_MEM_VALID(prev, BUF_BUDDY_LOW << i);
if (next) UNIV_MEM_VALID(next, BUF_BUDDY_LOW << i);
ut_ad(!prev || buf_page_get_state(prev) == BUF_BLOCK_ZIP_FREE);
ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
#endif /* UNIV_DEBUG_VALGRIND */
#endif /* UNIV_DEBUG */
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
#ifdef UNIV_DEBUG_VALGRIND
if (prev) UNIV_MEM_FREE(prev, BUF_BUDDY_LOW << i);
if (next) UNIV_MEM_FREE(next, BUF_BUDDY_LOW << i);
#endif /* UNIV_DEBUG_VALGRIND */
}
/**********************************************************************//**
@ -130,17 +119,13 @@ buf_buddy_alloc_zip(
ut_ad(buf_pool_mutex_own(buf_pool));
ut_a(i < BUF_BUDDY_SIZES);
ut_a(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
ut_ad(buf_page_get_state(ut_list_node_313)
== BUF_BLOCK_ZIP_FREE)));
#endif /* !UNIV_DEBUG_VALGRIND */
bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
if (bpage) {
UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
buf_buddy_remove_from_free(buf_pool, bpage, i);
@ -159,13 +144,10 @@ buf_buddy_alloc_zip(
}
}
#ifdef UNIV_DEBUG
if (bpage) {
memset(bpage, ~i, BUF_BUDDY_LOW << i);
ut_d(memset(bpage, ~i, BUF_BUDDY_LOW << i));
UNIV_MEM_ALLOC(bpage, BUF_BUDDY_SIZES << i);
}
#endif /* UNIV_DEBUG */
UNIV_MEM_ALLOC(bpage, BUF_BUDDY_SIZES << i);
return(bpage);
}
@ -253,6 +235,7 @@ buf_buddy_alloc_from(
{
ulint offs = BUF_BUDDY_LOW << j;
ut_ad(j <= BUF_BUDDY_SIZES);
ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
ut_ad(j >= i);
ut_ad(!ut_align_offset(buf, offs));
@ -266,13 +249,7 @@ buf_buddy_alloc_from(
bpage = (buf_page_t*) ((byte*) buf + offs);
ut_d(memset(bpage, j, BUF_BUDDY_LOW << j));
bpage->state = BUF_BLOCK_ZIP_FREE;
#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
ut_ad(buf_page_get_state(
ut_list_node_313)
== BUF_BLOCK_ZIP_FREE)));
#endif /* !UNIV_DEBUG_VALGRIND */
ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
buf_buddy_add_to_free(buf_pool, bpage, j);
}
@ -282,26 +259,27 @@ buf_buddy_alloc_from(
/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex.
The buf_pool->mutex may only be released and reacquired if lru != NULL.
@return allocated block, possibly NULL if lru==NULL */
The buf_pool_mutex may be released and reacquired.
@return allocated block, never NULL */
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool* lru) /*!< in: pointer to a variable that
will be assigned TRUE if storage was
allocated from the LRU list and
buf_pool->mutex was temporarily
released, or NULL if the LRU list
should not be used */
released */
{
buf_block_t* block;
ut_ad(lru);
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
if (i < BUF_BUDDY_SIZES) {
/* Try to allocate from the buddy system. */
@ -320,11 +298,6 @@ buf_buddy_alloc_low(
goto alloc_big;
}
if (!lru) {
return(NULL);
}
/* Try replacing an uncompressed page in the buffer pool. */
buf_pool_mutex_exit(buf_pool);
block = buf_LRU_get_free_block(buf_pool);
@ -342,63 +315,6 @@ func_exit:
return(block);
}
/**********************************************************************//**
Try to relocate the control block of a compressed page.
@return TRUE if relocated */
static
ibool
buf_buddy_relocate_block(
/*=====================*/
buf_page_t* bpage, /*!< in: block to relocate */
buf_page_t* dpage) /*!< in: free block to relocate to */
{
buf_page_t* b;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(buf_pool_mutex_own(buf_pool));
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_FREE:
case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_FILE_PAGE:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
ut_error;
case BUF_BLOCK_ZIP_DIRTY:
/* Cannot relocate dirty pages. */
return(FALSE);
case BUF_BLOCK_ZIP_PAGE:
break;
}
mutex_enter(&buf_pool->zip_mutex);
if (!buf_page_can_relocate(bpage)) {
mutex_exit(&buf_pool->zip_mutex);
return(FALSE);
}
buf_relocate(bpage, dpage);
ut_d(bpage->state = BUF_BLOCK_ZIP_FREE);
/* relocate buf_pool->zip_clean */
b = UT_LIST_GET_PREV(list, dpage);
UT_LIST_REMOVE(list, buf_pool->zip_clean, dpage);
if (b) {
UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, dpage);
} else {
UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, dpage);
}
UNIV_MEM_INVALID(bpage, sizeof *bpage);
mutex_exit(&buf_pool->zip_mutex);
return(TRUE);
}
/**********************************************************************//**
Try to relocate a block.
@return TRUE if relocated */
@ -415,108 +331,88 @@ buf_buddy_relocate(
buf_page_t* bpage;
const ulint size = BUF_BUDDY_LOW << i;
ullint usec = ut_time_us(NULL);
mutex_t* mutex;
ulint space;
ulint page_no;
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(!ut_align_offset(src, size));
ut_ad(!ut_align_offset(dst, size));
ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
UNIV_MEM_ASSERT_W(dst, size);
/* We assume that all memory from buf_buddy_alloc()
is used for either compressed pages or buf_page_t
objects covering compressed pages. */
is used for compressed page frames. */
/* We look inside the allocated objects returned by
buf_buddy_alloc() and assume that anything of
PAGE_ZIP_MIN_SIZE or larger is a compressed page that contains
a valid space_id and page_no in the page header. Should the
fields be invalid, we will be unable to relocate the block.
We also assume that anything that fits sizeof(buf_page_t)
actually is a properly initialized buf_page_t object. */
buf_buddy_alloc() and assume that each block is a compressed
page that contains a valid space_id and page_no in the page
header. Should the fields be invalid, we will be unable to
relocate the block. */
if (size >= PAGE_ZIP_MIN_SIZE) {
/* This is a compressed page. */
mutex_t* mutex;
/* The src block may be split into smaller blocks,
some of which may be free. Thus, the
mach_read_from_4() calls below may attempt to read
from free memory. The memory is "owned" by the buddy
allocator (and it has been allocated from the buffer
pool), so there is nothing wrong about this. The
mach_read_from_4() calls here will only trigger bogus
Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
space = mach_read_from_4((const byte *) src
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
page_no = mach_read_from_4((const byte *) src
+ FIL_PAGE_OFFSET);
/* Suppress Valgrind warnings about conditional jump
on uninitialized value. */
UNIV_MEM_VALID(&space, sizeof space);
UNIV_MEM_VALID(&page_no, sizeof page_no);
bpage = buf_page_hash_get(buf_pool, space, page_no);
/* The src block may be split into smaller blocks,
some of which may be free. Thus, the
mach_read_from_4() calls below may attempt to read
from free memory. The memory is "owned" by the buddy
allocator (and it has been allocated from the buffer
pool), so there is nothing wrong about this. The
mach_read_from_4() calls here will only trigger bogus
Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
ulint space = mach_read_from_4(
(const byte*) src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ulint page_no = mach_read_from_4(
(const byte*) src + FIL_PAGE_OFFSET);
/* Suppress Valgrind warnings about conditional jump
on uninitialized value. */
UNIV_MEM_VALID(&space, sizeof space);
UNIV_MEM_VALID(&page_no, sizeof page_no);
bpage = buf_page_hash_get(buf_pool, space, page_no);
if (!bpage || bpage->zip.data != src) {
/* The block has probably been freshly
allocated by buf_LRU_get_free_block() but not
added to buf_pool->page_hash yet. Obviously,
it cannot be relocated. */
if (!bpage || bpage->zip.data != src) {
/* The block has probably been freshly
allocated by buf_LRU_get_free_block() but not
added to buf_pool->page_hash yet. Obviously,
it cannot be relocated. */
return(FALSE);
}
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
if (page_zip_get_size(&bpage->zip) != size) {
/* The block is of different size. We would
have to relocate all blocks covered by src.
For the sake of simplicity, give up. */
ut_ad(page_zip_get_size(&bpage->zip) < size);
return(FALSE);
}
/* The block must have been allocated, but it may
contain uninitialized data. */
UNIV_MEM_ASSERT_W(src, size);
mutex = buf_page_get_mutex(bpage);
mutex_enter(mutex);
if (buf_page_can_relocate(bpage)) {
/* Relocate the compressed page. */
ut_a(bpage->zip.data == src);
memcpy(dst, src, size);
bpage->zip.data = dst;
mutex_exit(mutex);
success:
UNIV_MEM_INVALID(src, size);
{
buf_buddy_stat_t* buddy_stat
= &buf_pool->buddy_stat[i];
buddy_stat->relocated++;
buddy_stat->relocated_usec
+= ut_time_us(NULL) - usec;
}
return(TRUE);
}
mutex_exit(mutex);
} else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
/* This must be a buf_page_t object. */
#if UNIV_WORD_SIZE == 4
/* On 32-bit systems, there is no padding in
buf_page_t. On other systems, Valgrind could complain
about uninitialized pad bytes. */
UNIV_MEM_ASSERT_RW(src, size);
#endif
if (buf_buddy_relocate_block(src, dst)) {
goto success;
}
return(FALSE);
}
if (page_zip_get_size(&bpage->zip) != size) {
/* The block is of different size. We would
have to relocate all blocks covered by src.
For the sake of simplicity, give up. */
ut_ad(page_zip_get_size(&bpage->zip) < size);
return(FALSE);
}
/* The block must have been allocated, but it may
contain uninitialized data. */
UNIV_MEM_ASSERT_W(src, size);
mutex = buf_page_get_mutex(bpage);
mutex_enter(mutex);
if (buf_page_can_relocate(bpage)) {
/* Relocate the compressed page. */
ut_a(bpage->zip.data == src);
memcpy(dst, src, size);
bpage->zip.data = dst;
mutex_exit(mutex);
UNIV_MEM_INVALID(src, size);
{
buf_buddy_stat_t* buddy_stat
= &buf_pool->buddy_stat[i];
buddy_stat->relocated++;
buddy_stat->relocated_usec
+= ut_time_us(NULL) - usec;
}
return(TRUE);
}
mutex_exit(mutex);
return(FALSE);
}
@ -538,12 +434,13 @@ buf_buddy_free_low(
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(!mutex_own(&buf_pool->zip_mutex));
ut_ad(i <= BUF_BUDDY_SIZES);
ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
ut_ad(buf_pool->buddy_stat[i].used > 0);
buf_pool->buddy_stat[i].used--;
recombine:
UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i);
ut_d(((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE);
((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE;
if (i == BUF_BUDDY_SIZES) {
buf_buddy_block_free(buf_pool, buf);
@ -554,32 +451,36 @@ recombine:
ut_ad(buf == ut_align_down(buf, BUF_BUDDY_LOW << i));
ut_ad(!buf_pool_contains_zip(buf_pool, buf));
/* Try to combine adjacent blocks. */
/* Do not recombine blocks if there are few free blocks.
We may waste up to 15360*max_len bytes to free blocks
(1024 + 2048 + 4096 + 8192 = 15360) */
if (UT_LIST_GET_LEN(buf_pool->zip_free[i]) < 16) {
goto func_exit;
}
/* Try to combine adjacent blocks. */
buddy = (buf_page_t*) buf_buddy_get(((byte*) buf), BUF_BUDDY_LOW << i);
#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
/* When Valgrind instrumentation is not enabled, we can read
buddy->state to quickly determine that a block is not free.
When the block is not free, buddy->state belongs to a compressed
page frame that may be flagged uninitialized in our Valgrind
instrumentation. */
if (buddy->state != BUF_BLOCK_ZIP_FREE) {
goto buddy_nonfree;
}
/* The field buddy->state can only be trusted for free blocks.
If buddy->state == BUF_BLOCK_ZIP_FREE, the block is free if
it is in the free list. */
#endif /* !UNIV_DEBUG_VALGRIND */
for (bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]); bpage; ) {
UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
if (bpage == buddy) {
buddy_free:
/* The buddy is free: recombine */
buf_buddy_remove_from_free(buf_pool, bpage, i);
buddy_free2:
buddy_is_free:
ut_ad(buf_page_get_state(buddy) == BUF_BLOCK_ZIP_FREE);
ut_ad(!buf_pool_contains_zip(buf_pool, buddy));
i++;
@ -589,122 +490,42 @@ buddy_free2:
}
ut_a(bpage != buf);
{
buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
UNIV_MEM_ASSERT_AND_FREE(bpage, BUF_BUDDY_LOW << i);
bpage = next;
}
UNIV_MEM_ASSERT_W(bpage, BUF_BUDDY_LOW << i);
bpage = UT_LIST_GET_NEXT(list, bpage);
}
#ifndef UNIV_DEBUG_VALGRIND
buddy_nonfree:
/* Valgrind would complain about accessing free memory. */
ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
ut_ad(buf_page_get_state(ut_list_node_313)
== BUF_BLOCK_ZIP_FREE)));
#endif /* UNIV_DEBUG_VALGRIND */
#endif /* !UNIV_DEBUG_VALGRIND */
ut_d(BUF_BUDDY_LIST_VALIDATE(buf_pool, i));
/* The buddy is not free. Is there a free block of this size? */
bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
if (bpage) {
/* Remove the block from the free list, because a successful
buf_buddy_relocate() will overwrite bpage->list. */
UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
buf_buddy_remove_from_free(buf_pool, bpage, i);
/* Try to relocate the buddy of buf to the free block. */
if (buf_buddy_relocate(buf_pool, buddy, bpage, i)) {
ut_d(buddy->state = BUF_BLOCK_ZIP_FREE);
goto buddy_free2;
buddy->state = BUF_BLOCK_ZIP_FREE;
goto buddy_is_free;
}
buf_buddy_add_to_free(buf_pool, bpage, i);
/* Try to relocate the buddy of the free block to buf. */
buddy = (buf_page_t*) buf_buddy_get(((byte*) bpage),
BUF_BUDDY_LOW << i);
#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
/* The buddy must not be (completely) free, because we
always recombine adjacent free blocks.
(Parts of the buddy can be free in
buf_pool->zip_free[j] with j < i.) */
ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
ut_ad(buf_page_get_state(
ut_list_node_313)
== BUF_BLOCK_ZIP_FREE
&& ut_list_node_313 != buddy)));
#endif /* !UNIV_DEBUG_VALGRIND */
if (buf_buddy_relocate(buf_pool, buddy, buf, i)) {
buf = bpage;
UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
ut_d(buddy->state = BUF_BLOCK_ZIP_FREE);
goto buddy_free;
}
}
func_exit:
/* Free the block to the buddy list. */
bpage = buf;
#ifdef UNIV_DEBUG
if (i < buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE)) {
/* This area has most likely been allocated for at
least one compressed-only block descriptor. Check
that there are no live objects in the area. This is
not a complete check: it may yield false positives as
well as false negatives. Also, due to buddy blocks
being recombined, it is possible (although unlikely)
that this branch is never reached. */
char* c;
# ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing
uninitialized memory. Besides, Valgrind performs a
more exhaustive check, at every memory access. */
const buf_page_t* b = buf;
const buf_page_t* const b_end = (buf_page_t*)
((char*) b + (BUF_BUDDY_LOW << i));
for (; b < b_end; b++) {
/* Avoid false positives (and cause false
negatives) by checking for b->space < 1000. */
if ((b->state == BUF_BLOCK_ZIP_PAGE
|| b->state == BUF_BLOCK_ZIP_DIRTY)
&& b->space > 0 && b->space < 1000) {
fprintf(stderr,
"buddy dirty %p %u (%u,%u) %p,%lu\n",
(void*) b,
b->state, b->space, b->offset,
buf, i);
}
}
# endif /* !UNIV_DEBUG_VALGRIND */
/* Scramble the block. This should make any pointers
invalid and trigger a segmentation violation. Because
the scrambling can be reversed, it may be possible to
track down the object pointing to the freed data by
dereferencing the unscrambled bpage->LRU or
bpage->list pointers. */
for (c = (char*) buf + (BUF_BUDDY_LOW << i);
c-- > (char*) buf; ) {
*c = ~*c ^ i;
}
} else {
/* Fill large blocks with a constant pattern. */
memset(bpage, i, BUF_BUDDY_LOW << i);
}
#endif /* UNIV_DEBUG */
/* Fill large blocks with a constant pattern. */
ut_d(memset(bpage, i, BUF_BUDDY_LOW << i));
UNIV_MEM_INVALID(bpage, BUF_BUDDY_LOW << i);
bpage->state = BUF_BLOCK_ZIP_FREE;
buf_buddy_add_to_free(buf_pool, bpage, i);
}

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@ -1099,70 +1099,6 @@ buf_chunk_not_freed(
return(NULL);
}
/*********************************************************************//**
Checks that all blocks in the buffer chunk are in BUF_BLOCK_NOT_USED state.
@return TRUE if all freed */
static
ibool
buf_chunk_all_free(
/*===============*/
const buf_chunk_t* chunk) /*!< in: chunk being checked */
{
const buf_block_t* block;
ulint i;
block = chunk->blocks;
for (i = chunk->size; i--; block++) {
if (buf_block_get_state(block) != BUF_BLOCK_NOT_USED) {
return(FALSE);
}
}
return(TRUE);
}
/********************************************************************//**
Frees a chunk of buffer frames. */
static
void
buf_chunk_free(
/*===========*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
buf_chunk_t* chunk) /*!< out: chunk of buffers */
{
buf_block_t* block;
const buf_block_t* block_end;
ut_ad(buf_pool_mutex_own(buf_pool));
block_end = chunk->blocks + chunk->size;
for (block = chunk->blocks; block < block_end; block++) {
ut_a(buf_block_get_state(block) == BUF_BLOCK_NOT_USED);
ut_a(!block->page.zip.data);
ut_ad(!block->page.in_LRU_list);
ut_ad(!block->in_unzip_LRU_list);
ut_ad(!block->page.in_flush_list);
/* Remove the block from the free list. */
ut_ad(block->page.in_free_list);
UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
/* Free the latches. */
mutex_free(&block->mutex);
rw_lock_free(&block->lock);
#ifdef UNIV_SYNC_DEBUG
rw_lock_free(&block->debug_latch);
#endif /* UNIV_SYNC_DEBUG */
UNIV_MEM_UNDESC(block);
}
os_mem_free_large(chunk->mem, chunk->mem_size);
}
/********************************************************************//**
Set buffer pool size variables after resizing it */
static
@ -1272,8 +1208,6 @@ buf_pool_free_instance(
chunk = chunks + buf_pool->n_chunks;
while (--chunk >= chunks) {
/* Bypass the checks of buf_chunk_free(), since they
would fail at shutdown. */
os_mem_free_large(chunk->mem, chunk->mem_size);
}
@ -1533,281 +1467,6 @@ buf_relocate(
}
/********************************************************************//**
Shrinks a buffer pool instance. */
static
void
buf_pool_shrink_instance(
/*=====================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
ulint chunk_size) /*!< in: number of pages to remove */
{
buf_chunk_t* chunks;
buf_chunk_t* chunk;
ulint max_size;
ulint max_free_size;
buf_chunk_t* max_chunk;
buf_chunk_t* max_free_chunk;
ut_ad(!buf_pool_mutex_own(buf_pool));
try_again:
btr_search_disable(); /* Empty the adaptive hash index again */
buf_pool_mutex_enter(buf_pool);
shrink_again:
if (buf_pool->n_chunks <= 1) {
/* Cannot shrink if there is only one chunk */
goto func_done;
}
/* Search for the largest free chunk
not larger than the size difference */
chunks = buf_pool->chunks;
chunk = chunks + buf_pool->n_chunks;
max_size = max_free_size = 0;
max_chunk = max_free_chunk = NULL;
while (--chunk >= chunks) {
if (chunk->size <= chunk_size
&& chunk->size > max_free_size) {
if (chunk->size > max_size) {
max_size = chunk->size;
max_chunk = chunk;
}
if (buf_chunk_all_free(chunk)) {
max_free_size = chunk->size;
max_free_chunk = chunk;
}
}
}
if (!max_free_size) {
ulint dirty = 0;
ulint nonfree = 0;
buf_block_t* block;
buf_block_t* bend;
/* Cannot shrink: try again later
(do not assign srv_buf_pool_old_size) */
if (!max_chunk) {
goto func_exit;
}
block = max_chunk->blocks;
bend = block + max_chunk->size;
/* Move the blocks of chunk to the end of the
LRU list and try to flush them. */
for (; block < bend; block++) {
switch (buf_block_get_state(block)) {
case BUF_BLOCK_NOT_USED:
continue;
case BUF_BLOCK_FILE_PAGE:
break;
default:
nonfree++;
continue;
}
mutex_enter(&block->mutex);
/* The following calls will temporarily
release block->mutex and buf_pool->mutex.
Therefore, we have to always retry,
even if !dirty && !nonfree. */
if (!buf_flush_ready_for_replace(&block->page)) {
buf_LRU_make_block_old(&block->page);
dirty++;
} else if (buf_LRU_free_block(&block->page, TRUE)
!= BUF_LRU_FREED) {
nonfree++;
}
mutex_exit(&block->mutex);
}
buf_pool_mutex_exit(buf_pool);
/* Request for a flush of the chunk if it helps.
Do not flush if there are non-free blocks, since
flushing will not make the chunk freeable. */
if (nonfree) {
/* Avoid busy-waiting. */
os_thread_sleep(100000);
} else if (dirty
&& buf_flush_LRU(buf_pool, dirty)
== ULINT_UNDEFINED) {
buf_flush_wait_batch_end(buf_pool, BUF_FLUSH_LRU);
}
goto try_again;
}
max_size = max_free_size;
max_chunk = max_free_chunk;
buf_pool->old_pool_size = buf_pool->curr_pool_size;
/* Rewrite buf_pool->chunks. Copy everything but max_chunk. */
chunks = mem_alloc((buf_pool->n_chunks - 1) * sizeof *chunks);
memcpy(chunks, buf_pool->chunks,
(max_chunk - buf_pool->chunks) * sizeof *chunks);
memcpy(chunks + (max_chunk - buf_pool->chunks),
max_chunk + 1,
buf_pool->chunks + buf_pool->n_chunks
- (max_chunk + 1));
ut_a(buf_pool->curr_size > max_chunk->size);
buf_pool->curr_size -= max_chunk->size;
buf_pool->curr_pool_size = buf_pool->curr_size * UNIV_PAGE_SIZE;
chunk_size -= max_chunk->size;
buf_chunk_free(buf_pool, max_chunk);
mem_free(buf_pool->chunks);
buf_pool->chunks = chunks;
buf_pool->n_chunks--;
/* Allow a slack of one megabyte. */
if (chunk_size > 1048576 / UNIV_PAGE_SIZE) {
goto shrink_again;
}
goto func_exit;
func_done:
buf_pool->old_pool_size = buf_pool->curr_pool_size;
func_exit:
buf_pool_mutex_exit(buf_pool);
btr_search_enable();
}
/********************************************************************//**
Shrinks the buffer pool. */
static
void
buf_pool_shrink(
/*============*/
ulint chunk_size) /*!< in: number of pages to remove */
{
ulint i;
for (i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_t* buf_pool;
ulint instance_chunk_size;
instance_chunk_size = chunk_size / srv_buf_pool_instances;
buf_pool = buf_pool_from_array(i);
buf_pool_shrink_instance(buf_pool, instance_chunk_size);
}
buf_pool_set_sizes();
}
/********************************************************************//**
Rebuild buf_pool->page_hash for a buffer pool instance. */
static
void
buf_pool_page_hash_rebuild_instance(
/*================================*/
buf_pool_t* buf_pool) /*!< in: buffer pool instance */
{
ulint i;
buf_page_t* b;
buf_chunk_t* chunk;
ulint n_chunks;
hash_table_t* zip_hash;
hash_table_t* page_hash;
buf_pool_mutex_enter(buf_pool);
/* Free, create, and populate the hash table. */
hash_table_free(buf_pool->page_hash);
buf_pool->page_hash = page_hash = hash_create(2 * buf_pool->curr_size);
zip_hash = hash_create(2 * buf_pool->curr_size);
HASH_MIGRATE(buf_pool->zip_hash, zip_hash, buf_page_t, hash,
BUF_POOL_ZIP_FOLD_BPAGE);
hash_table_free(buf_pool->zip_hash);
buf_pool->zip_hash = zip_hash;
/* Insert the uncompressed file pages to buf_pool->page_hash. */
chunk = buf_pool->chunks;
n_chunks = buf_pool->n_chunks;
for (i = 0; i < n_chunks; i++, chunk++) {
ulint j;
buf_block_t* block = chunk->blocks;
for (j = 0; j < chunk->size; j++, block++) {
if (buf_block_get_state(block)
== BUF_BLOCK_FILE_PAGE) {
ut_ad(!block->page.in_zip_hash);
ut_ad(block->page.in_page_hash);
HASH_INSERT(buf_page_t, hash, page_hash,
buf_page_address_fold(
block->page.space,
block->page.offset),
&block->page);
}
}
}
/* Insert the compressed-only pages to buf_pool->page_hash.
All such blocks are either in buf_pool->zip_clean or
in buf_pool->flush_list. */
for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
b = UT_LIST_GET_NEXT(list, b)) {
ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
ut_ad(!b->in_flush_list);
ut_ad(b->in_LRU_list);
ut_ad(b->in_page_hash);
ut_ad(!b->in_zip_hash);
HASH_INSERT(buf_page_t, hash, page_hash,
buf_page_address_fold(b->space, b->offset), b);
}
buf_flush_list_mutex_enter(buf_pool);
for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
b = UT_LIST_GET_NEXT(list, b)) {
ut_ad(b->in_flush_list);
ut_ad(b->in_LRU_list);
ut_ad(b->in_page_hash);
ut_ad(!b->in_zip_hash);
switch (buf_page_get_state(b)) {
case BUF_BLOCK_ZIP_DIRTY:
HASH_INSERT(buf_page_t, hash, page_hash,
buf_page_address_fold(b->space,
b->offset), b);
break;
case BUF_BLOCK_FILE_PAGE:
/* uncompressed page */
break;
case BUF_BLOCK_ZIP_FREE:
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
ut_error;
break;
}
}
buf_flush_list_mutex_exit(buf_pool);
buf_pool_mutex_exit(buf_pool);
}
/********************************************************************
Determine if a block is a sentinel for a buffer pool watch.
@return TRUE if a sentinel for a buffer pool watch, FALSE if not */
UNIV_INTERN
@ -1913,123 +1572,6 @@ buf_pool_watch_set(
return(NULL);
}
/********************************************************************//**
Rebuild buf_pool->page_hash. */
static
void
buf_pool_page_hash_rebuild(void)
/*============================*/
{
ulint i;
for (i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_page_hash_rebuild_instance(buf_pool_from_array(i));
}
}
/********************************************************************//**
Increase the buffer pool size of one buffer pool instance. */
static
void
buf_pool_increase_instance(
/*=======================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instane */
ulint change_size) /*!< in: new size of the pool */
{
buf_chunk_t* chunks;
buf_chunk_t* chunk;
buf_pool_mutex_enter(buf_pool);
chunks = mem_alloc((buf_pool->n_chunks + 1) * sizeof *chunks);
memcpy(chunks, buf_pool->chunks, buf_pool->n_chunks * sizeof *chunks);
chunk = &chunks[buf_pool->n_chunks];
if (!buf_chunk_init(buf_pool, chunk, change_size)) {
mem_free(chunks);
} else {
buf_pool->old_pool_size = buf_pool->curr_pool_size;
buf_pool->curr_size += chunk->size;
buf_pool->curr_pool_size = buf_pool->curr_size * UNIV_PAGE_SIZE;
mem_free(buf_pool->chunks);
buf_pool->chunks = chunks;
buf_pool->n_chunks++;
}
buf_pool_mutex_exit(buf_pool);
}
/********************************************************************//**
Increase the buffer pool size. */
static
void
buf_pool_increase(
/*==============*/
ulint change_size)
{
ulint i;
for (i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_increase_instance(
buf_pool_from_array(i),
change_size / srv_buf_pool_instances);
}
buf_pool_set_sizes();
}
/********************************************************************//**
Resizes the buffer pool. */
UNIV_INTERN
void
buf_pool_resize(void)
/*=================*/
{
ulint change_size;
ulint min_change_size = 1048576 * srv_buf_pool_instances;
buf_pool_mutex_enter_all();
if (srv_buf_pool_old_size == srv_buf_pool_size) {
buf_pool_mutex_exit_all();
return;
} else if (srv_buf_pool_curr_size + min_change_size
> srv_buf_pool_size) {
change_size = (srv_buf_pool_curr_size - srv_buf_pool_size)
/ UNIV_PAGE_SIZE;
buf_pool_mutex_exit_all();
/* Disable adaptive hash indexes and empty the index
in order to free up memory in the buffer pool chunks. */
buf_pool_shrink(change_size);
} else if (srv_buf_pool_curr_size + min_change_size
< srv_buf_pool_size) {
/* Enlarge the buffer pool by at least one megabyte */
change_size = srv_buf_pool_size - srv_buf_pool_curr_size;
buf_pool_mutex_exit_all();
buf_pool_increase(change_size);
} else {
srv_buf_pool_size = srv_buf_pool_old_size;
buf_pool_mutex_exit_all();
return;
}
buf_pool_page_hash_rebuild();
}
/****************************************************************//**
Remove the sentinel block for the watch before replacing it with a real block.
buf_page_watch_clear() or buf_page_watch_occurred() will notice that
@ -2365,7 +1907,7 @@ err_exit:
mutex_enter(block_mutex);
/* Discard the uncompressed page frame if possible. */
if (buf_LRU_free_block(bpage, FALSE) == BUF_LRU_FREED) {
if (buf_LRU_free_block(bpage, FALSE)) {
mutex_exit(block_mutex);
goto lookup;
@ -2768,12 +2310,8 @@ loop:
if (block) {
/* If the guess is a compressed page descriptor that
has been allocated by buf_buddy_alloc(), it may have
been invalidated by buf_buddy_relocate(). In that
case, block could point to something that happens to
contain the expected bits in block->page. Similarly,
the guess may be pointing to a buffer pool chunk that
has been released when resizing the buffer pool. */
has been allocated by buf_page_alloc_descriptor(),
it may have been freed by buf_relocate(). */
if (!buf_block_is_uncompressed(buf_pool, block)
|| offset != block->page.offset
@ -2951,8 +2489,10 @@ wait_until_unfixed:
if (buf_page_get_state(&block->page)
== BUF_BLOCK_ZIP_PAGE) {
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
UT_LIST_REMOVE(list, buf_pool->zip_clean,
&block->page);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
ut_ad(!block->page.in_flush_list);
} else {
/* Relocate buf_pool->flush_list. */
@ -2978,11 +2518,10 @@ wait_until_unfixed:
mutex_exit(&buf_pool->zip_mutex);
buf_pool->n_pend_unzip++;
bpage->state = BUF_BLOCK_ZIP_FREE;
buf_buddy_free(buf_pool, bpage, sizeof *bpage);
buf_pool_mutex_exit(buf_pool);
buf_page_free_descriptor(bpage);
/* Decompress the page and apply buffered operations
while not holding buf_pool->mutex or block->mutex. */
success = buf_zip_decompress(block, srv_use_checksums);
@ -3028,7 +2567,7 @@ wait_until_unfixed:
/* Try to evict the block from the buffer pool, to use the
insert buffer (change buffer) as much as possible. */
if (buf_LRU_free_block(&block->page, TRUE) == BUF_LRU_FREED) {
if (buf_LRU_free_block(&block->page, TRUE)) {
mutex_exit(&block->mutex);
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
/* Set the watch, as it would have
@ -3687,20 +3226,11 @@ err_exit:
mutex_exit(&block->mutex);
} else {
/* Defer buf_buddy_alloc() until after the block has
been found not to exist. The buf_buddy_alloc() and
buf_buddy_free() calls may be expensive because of
buf_buddy_relocate(). */
/* The compressed page must be allocated before the
control block (bpage), in order to avoid the
invocation of buf_buddy_relocate_block() on
uninitialized data. */
data = buf_buddy_alloc(buf_pool, zip_size, &lru);
bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru);
/* Initialize the buf_pool pointer. */
bpage->buf_pool_index = buf_pool_index(buf_pool);
/* If buf_buddy_alloc() allocated storage from the LRU list,
it released and reacquired buf_pool->mutex. Thus, we must
@ -3716,8 +3246,6 @@ err_exit:
/* The block was added by some other thread. */
watch_page = NULL;
bpage->state = BUF_BLOCK_ZIP_FREE;
buf_buddy_free(buf_pool, bpage, sizeof *bpage);
buf_buddy_free(buf_pool, data, zip_size);
bpage = NULL;
@ -3725,6 +3253,11 @@ err_exit:
}
}
bpage = buf_page_alloc_descriptor();
/* Initialize the buf_pool pointer. */
bpage->buf_pool_index = buf_pool_index(buf_pool);
page_zip_des_init(&bpage->zip);
page_zip_set_size(&bpage->zip, zip_size);
bpage->zip.data = data;
@ -3739,7 +3272,6 @@ err_exit:
bpage->space = space;
bpage->offset = offset;
#ifdef UNIV_DEBUG
bpage->in_page_hash = FALSE;
bpage->in_zip_hash = FALSE;
@ -3764,7 +3296,9 @@ err_exit:
/* The block must be put to the LRU list, to the old blocks */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
buf_page_set_io_fix(bpage, BUF_IO_READ);

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1995, 2011, Oracle and/or its affiliates. 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
@ -524,7 +524,9 @@ buf_flush_remove(
case BUF_BLOCK_ZIP_DIRTY:
buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
break;
case BUF_BLOCK_FILE_PAGE:
UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1995, 2011, Oracle and/or its affiliates. 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
@ -353,31 +353,34 @@ scan_again:
while (bpage != NULL) {
buf_page_t* prev_bpage;
ibool prev_bpage_buf_fix = FALSE;
mutex_t* block_mutex = NULL;
ut_a(buf_page_in_file(bpage));
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
/* bpage->space and bpage->io_fix are protected by
buf_pool->mutex and block_mutex. It is safe to check
them while holding buf_pool->mutex only. */
buf_pool_mutex and block_mutex. It is safe to check
them while holding buf_pool_mutex only. */
if (buf_page_get_space(bpage) != id) {
/* Skip this block, as it does not belong to
the space that is being invalidated. */
goto next_page;
} else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
/* We cannot remove this page during this scan
yet; maybe the system is currently reading it
in, or flushing the modifications to the file */
all_freed = FALSE;
goto next_page;
} else {
mutex_t* block_mutex = buf_page_get_mutex(bpage);
block_mutex = buf_page_get_mutex(bpage);
mutex_enter(block_mutex);
if (bpage->buf_fix_count > 0) {
mutex_exit(block_mutex);
/* We cannot remove this page during
this scan yet; maybe the system is
currently reading it in, or flushing
@ -387,106 +390,59 @@ scan_again:
goto next_page;
}
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr,
"Dropping space %lu page %lu\n",
(ulong) buf_page_get_space(bpage),
(ulong) buf_page_get_page_no(bpage));
}
#endif
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
/* This is a compressed-only block
descriptor. Ensure that prev_bpage
cannot be relocated when bpage is freed. */
if (UNIV_LIKELY(prev_bpage != NULL)) {
switch (buf_page_get_state(
prev_bpage)) {
case BUF_BLOCK_FILE_PAGE:
/* Descriptors of uncompressed
blocks will not be relocated,
because we are holding the
buf_pool->mutex. */
break;
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
/* Descriptors of compressed-
only blocks can be relocated,
unless they are buffer-fixed.
Because both bpage and
prev_bpage are protected by
buf_pool_zip_mutex, it is
not necessary to acquire
further mutexes. */
ut_ad(&buf_pool->zip_mutex
== block_mutex);
ut_ad(mutex_own(block_mutex));
prev_bpage_buf_fix = TRUE;
prev_bpage->buf_fix_count++;
break;
default:
ut_error;
}
}
} else if (((buf_block_t*) bpage)->is_hashed) {
ulint page_no;
ulint zip_size;
buf_pool_mutex_exit(buf_pool);
zip_size = buf_page_get_zip_size(bpage);
page_no = buf_page_get_page_no(bpage);
mutex_exit(block_mutex);
/* Note that the following call will acquire
an S-latch on the page */
btr_search_drop_page_hash_when_freed(
id, zip_size, page_no);
goto scan_again;
}
if (bpage->oldest_modification != 0) {
buf_flush_remove(bpage);
}
/* Remove from the LRU list. */
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
!= BUF_BLOCK_ZIP_FREE) {
buf_LRU_block_free_hashed_page((buf_block_t*)
bpage);
} else {
/* The block_mutex should have been
released by buf_LRU_block_remove_hashed_page()
when it returns BUF_BLOCK_ZIP_FREE. */
ut_ad(block_mutex == &buf_pool->zip_mutex);
ut_ad(!mutex_own(block_mutex));
if (prev_bpage_buf_fix) {
/* We temporarily buffer-fixed
prev_bpage, so that
buf_buddy_free() could not
relocate it, in case it was a
compressed-only block
descriptor. */
mutex_enter(block_mutex);
ut_ad(prev_bpage->buf_fix_count > 0);
prev_bpage->buf_fix_count--;
mutex_exit(block_mutex);
}
goto next_page_no_mutex;
}
next_page:
mutex_exit(block_mutex);
}
next_page_no_mutex:
ut_ad(mutex_own(block_mutex));
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr,
"Dropping space %lu page %lu\n",
(ulong) buf_page_get_space(bpage),
(ulong) buf_page_get_page_no(bpage));
}
#endif
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
/* This is a compressed-only block
descriptor. Do nothing. */
} else if (((buf_block_t*) bpage)->is_hashed) {
ulint page_no;
ulint zip_size;
buf_pool_mutex_exit(buf_pool);
zip_size = buf_page_get_zip_size(bpage);
page_no = buf_page_get_page_no(bpage);
mutex_exit(block_mutex);
/* Note that the following call will acquire
an S-latch on the page */
btr_search_drop_page_hash_when_freed(
id, zip_size, page_no);
goto scan_again;
}
if (bpage->oldest_modification != 0) {
buf_flush_remove(bpage);
}
/* Remove from the LRU list. */
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
!= BUF_BLOCK_ZIP_FREE) {
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
mutex_exit(block_mutex);
} else {
/* The block_mutex should have been released
by buf_LRU_block_remove_hashed_page() when it
returns BUF_BLOCK_ZIP_FREE. */
ut_ad(block_mutex == &buf_pool->zip_mutex);
ut_ad(!mutex_own(block_mutex));
}
next_page:
bpage = prev_bpage;
}
@ -525,6 +481,7 @@ buf_LRU_invalidate_tablespace(
}
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
@ -557,6 +514,7 @@ buf_LRU_insert_zip_clean(
UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, bpage);
}
}
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
/******************************************************************//**
Try to free an uncompressed page of a compressed block from the unzip
@ -600,7 +558,7 @@ buf_LRU_free_from_unzip_LRU_list(
UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
enum buf_lru_free_block_status freed;
ibool freed;
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(block->in_unzip_LRU_list);
@ -610,24 +568,9 @@ buf_LRU_free_from_unzip_LRU_list(
freed = buf_LRU_free_block(&block->page, FALSE);
mutex_exit(&block->mutex);
switch (freed) {
case BUF_LRU_FREED:
if (freed) {
return(TRUE);
case BUF_LRU_CANNOT_RELOCATE:
/* If we failed to relocate, try
regular LRU eviction. */
return(FALSE);
case BUF_LRU_NOT_FREED:
/* The block was buffer-fixed or I/O-fixed.
Keep looking. */
continue;
}
/* inappropriate return value from
buf_LRU_free_block() */
ut_error;
}
return(FALSE);
@ -660,10 +603,9 @@ buf_LRU_free_from_common_LRU_list(
UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
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(bpage);
ibool freed;
unsigned accessed;
mutex_t* block_mutex = buf_page_get_mutex(bpage);
ut_ad(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
@ -673,8 +615,7 @@ buf_LRU_free_from_common_LRU_list(
freed = buf_LRU_free_block(bpage, TRUE);
mutex_exit(block_mutex);
switch (freed) {
case BUF_LRU_FREED:
if (freed) {
/* Keep track of pages that are evicted without
ever being accessed. This gives us a measure of
the effectiveness of readahead */
@ -682,21 +623,7 @@ buf_LRU_free_from_common_LRU_list(
++buf_pool->stat.n_ra_pages_evicted;
}
return(TRUE);
case BUF_LRU_NOT_FREED:
/* The block was dirty, buffer-fixed, or I/O-fixed.
Keep looking. */
continue;
case BUF_LRU_CANNOT_RELOCATE:
/* This should never occur, because we
want to discard the compressed page too. */
break;
}
/* inappropriate return value from
buf_LRU_free_block() */
ut_error;
}
return(FALSE);
@ -1422,17 +1349,16 @@ buf_LRU_make_block_old(
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
NOTE: If this function returns BUF_LRU_FREED, it will temporarily
NOTE: If this function returns TRUE, it will temporarily
release buf_pool->mutex. Furthermore, the page frame will no longer be
accessible via bpage.
The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
buf_page_get_mutex() may be held when calling this function.
@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
BUF_LRU_NOT_FREED otherwise. */
@return TRUE if freed, FALSE otherwise. */
UNIV_INTERN
enum buf_lru_free_block_status
ibool
buf_LRU_free_block(
/*===============*/
buf_page_t* bpage, /*!< in: block to be freed */
@ -1458,7 +1384,7 @@ buf_LRU_free_block(
if (!buf_page_can_relocate(bpage)) {
/* Do not free buffer-fixed or I/O-fixed blocks. */
return(BUF_LRU_NOT_FREED);
return(FALSE);
}
#ifdef UNIV_IBUF_COUNT_DEBUG
@ -1470,7 +1396,7 @@ buf_LRU_free_block(
/* Do not completely free dirty blocks. */
if (bpage->oldest_modification) {
return(BUF_LRU_NOT_FREED);
return(FALSE);
}
} else if (bpage->oldest_modification) {
/* Do not completely free dirty blocks. */
@ -1478,7 +1404,7 @@ buf_LRU_free_block(
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
ut_ad(buf_page_get_state(bpage)
== BUF_BLOCK_ZIP_DIRTY);
return(BUF_LRU_NOT_FREED);
return(FALSE);
}
goto alloc;
@ -1487,14 +1413,8 @@ buf_LRU_free_block(
If it cannot be allocated (without freeing a block
from the LRU list), refuse to free bpage. */
alloc:
buf_pool_mutex_exit_forbid(buf_pool);
b = buf_buddy_alloc(buf_pool, sizeof *b, NULL);
buf_pool_mutex_exit_allow(buf_pool);
if (UNIV_UNLIKELY(!b)) {
return(BUF_LRU_CANNOT_RELOCATE);
}
b = buf_page_alloc_descriptor();
ut_a(b);
memcpy(b, bpage, sizeof *b);
}
@ -1598,7 +1518,9 @@ alloc:
}
if (b->state == BUF_BLOCK_ZIP_PAGE) {
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(b);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
} else {
/* Relocate on buf_pool->flush_list. */
buf_flush_relocate_on_flush_list(bpage, b);
@ -1665,7 +1587,7 @@ alloc:
mutex_enter(block_mutex);
}
return(BUF_LRU_FREED);
return(TRUE);
}
/******************************************************************//**
@ -1884,7 +1806,9 @@ buf_LRU_block_remove_hashed_page(
ut_a(bpage->zip.data);
ut_a(buf_page_get_zip_size(bpage));
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
mutex_exit(&buf_pool->zip_mutex);
buf_pool_mutex_exit_forbid(buf_pool);
@ -1893,11 +1817,8 @@ buf_LRU_block_remove_hashed_page(
buf_pool, bpage->zip.data,
page_zip_get_size(&bpage->zip));
bpage->state = BUF_BLOCK_ZIP_FREE;
buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
buf_pool_mutex_exit_allow(buf_pool);
UNIV_MEM_UNDESC(bpage);
buf_page_free_descriptor(bpage);
return(BUF_BLOCK_ZIP_FREE);
case BUF_BLOCK_FILE_PAGE:

View file

@ -990,7 +990,6 @@ convert_error_code_to_mysql(
misleading, a new MySQL error
code should be introduced */
case DB_COL_APPEARS_TWICE_IN_INDEX:
case DB_CORRUPTION:
return(HA_ERR_CRASHED);

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1994, 2011, Oracle and/or its affiliates. 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
@ -481,11 +481,14 @@ UNIV_INTERN
ibool
btr_compress(
/*=========*/
btr_cur_t* cursor, /*!< in: cursor on the page to merge or lift;
the page must not be empty: in record delete
use btr_discard_page if the page would become
empty */
mtr_t* mtr); /*!< in: mtr */
btr_cur_t* cursor, /*!< in/out: cursor on the page to merge
or lift; the page must not be empty:
when deleting records, use btr_discard_page()
if the page would become empty */
ibool adjust, /*!< in: TRUE if should adjust the
cursor position even if compression occurs */
mtr_t* mtr) /*!< in/out: mini-transaction */
__attribute__((nonnull));
/*************************************************************//**
Discards a page from a B-tree. This is used to remove the last record from
a B-tree page: the whole page must be removed at the same time. This cannot

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1994, 2011, Oracle and/or its affiliates. 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
@ -36,6 +36,9 @@ Created 10/16/1994 Heikki Tuuri
#define BTR_NO_LOCKING_FLAG 2 /* do no record lock checking */
#define BTR_KEEP_SYS_FLAG 4 /* sys fields will be found from the
update vector or inserted entry */
#define BTR_KEEP_POS_FLAG 8 /* btr_cur_pessimistic_update()
must keep cursor position when
moving columns to big_rec */
#ifndef UNIV_HOTBACKUP
#include "que0types.h"
@ -310,7 +313,9 @@ btr_cur_pessimistic_update(
/*=======================*/
ulint flags, /*!< in: undo logging, locking, and rollback
flags */
btr_cur_t* cursor, /*!< in: cursor on the record to update */
btr_cur_t* cursor, /*!< in/out: cursor on the record to update;
cursor may become invalid if *big_rec == NULL
|| !(flags & BTR_KEEP_POS_FLAG) */
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or NULL */
@ -322,6 +327,16 @@ btr_cur_pessimistic_update(
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr); /*!< in: mtr; must be committed before
latching any further pages */
/*****************************************************************
Commits and restarts a mini-transaction so that it will retain an
x-lock on index->lock and the cursor page. */
UNIV_INTERN
void
btr_cur_mtr_commit_and_start(
/*=========================*/
btr_cur_t* cursor, /*!< in: cursor */
mtr_t* mtr) /*!< in/out: mini-transaction */
UNIV_COLD __attribute__((nonnull));
/***********************************************************//**
Marks a clustered index record deleted. Writes an undo log record to
undo log on this delete marking. Writes in the trx id field the id
@ -364,10 +379,13 @@ UNIV_INTERN
ibool
btr_cur_compress_if_useful(
/*=======================*/
btr_cur_t* cursor, /*!< in: cursor on the page to compress;
btr_cur_t* cursor, /*!< in/out: cursor on the page to compress;
cursor does not stay valid if compression
occurs */
mtr_t* mtr); /*!< in: mtr */
ibool adjust, /*!< in: TRUE if should adjust the
cursor position even if compression occurs */
mtr_t* mtr) /*!< in/out: mini-transaction */
__attribute__((nonnull));
/*******************************************************//**
Removes the record on which the tree cursor is positioned. It is assumed
that the mtr has an x-latch on the page where the cursor is positioned,

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1994, 2011, Oracle and/or its affiliates. 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
@ -139,7 +139,7 @@ btr_cur_compress_recommendation(
btr_cur_t* cursor, /*!< in: btr cursor */
mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
const page_t* page;
ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
MTR_MEMO_PAGE_X_FIX));

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 2006, 2011, Oracle and/or its affiliates. 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
@ -37,37 +37,37 @@ Created December 2006 by Marko Makela
/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool->mutex and must not hold buf_pool->zip_mutex or any
block->mutex. The buf_pool->mutex may only be released and reacquired
if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
buf_pool->mutex.
@return allocated block, possibly NULL if lru == NULL */
block->mutex. The buf_pool->mutex may be released and reacquired.
This function should only be used for allocating compressed page frames.
@return allocated block, never NULL */
UNIV_INLINE
void*
byte*
buf_buddy_alloc(
/*============*/
buf_pool_t* buf_pool,
/*!< buffer pool in which the block resides */
ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool* lru) /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool->mutex was temporarily released,
or NULL if the LRU list should not be used */
__attribute__((malloc));
buf_pool_t* buf_pool, /*!< in/out: buffer pool in which
the page resides */
ulint size, /*!< in: compressed page size
(between PAGE_ZIP_MIN_SIZE and
UNIV_PAGE_SIZE) */
ibool* lru) /*!< in: pointer to a variable
that will be assigned TRUE if
storage was allocated from the
LRU list and buf_pool->mutex was
temporarily released */
__attribute__((malloc, nonnull));
/**********************************************************************//**
Release a block. */
Deallocate a block. */
UNIV_INLINE
void
buf_buddy_free(
/*===========*/
buf_pool_t* buf_pool,
/*!< buffer pool in which the block resides */
void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
ulint size) /*!< in: block size, up to UNIV_PAGE_SIZE */
buf_pool_t* buf_pool, /*!< in/out: buffer pool in which
the block resides */
void* buf, /*!< in: block to be freed, must not
be pointed to by the buffer pool */
ulint size) /*!< in: block size,
up to UNIV_PAGE_SIZE */
__attribute__((nonnull));
#ifndef UNIV_NONINL

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 2006, 2011, Oracle and/or its affiliates. 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
@ -36,21 +36,21 @@ Created December 2006 by Marko Makela
/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex.
The buf_pool->mutex may only be released and reacquired if lru != NULL.
@return allocated block, possibly NULL if lru==NULL */
The buf_pool_mutex may be released and reacquired.
@return allocated block, never NULL */
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
buf_pool_t* buf_pool,
/*!< in: buffer pool in which the page resides */
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool* lru) /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool->mutex was temporarily released,
or NULL if the LRU list should not be used */
__attribute__((malloc));
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool* lru) /*!< in: pointer to a variable that
will be assigned TRUE if storage was
allocated from the LRU list and
buf_pool->mutex was temporarily
released */
__attribute__((malloc, nonnull));
/**********************************************************************//**
Deallocate a block. */
@ -77,6 +77,8 @@ buf_buddy_get_slot(
ulint i;
ulint s;
ut_ad(size >= PAGE_ZIP_MIN_SIZE);
for (i = 0, s = BUF_BUDDY_LOW; s < size; i++, s <<= 1) {
}
@ -87,31 +89,31 @@ buf_buddy_get_slot(
/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool->mutex and must not hold buf_pool->zip_mutex or any
block->mutex. The buf_pool->mutex may only be released and reacquired
if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
buf_pool->mutex.
@return allocated block, possibly NULL if lru == NULL */
block->mutex. The buf_pool->mutex may be released and reacquired.
This function should only be used for allocating compressed page frames.
@return allocated block, never NULL */
UNIV_INLINE
void*
byte*
buf_buddy_alloc(
/*============*/
buf_pool_t* buf_pool, /*!< in: buffer pool in which
buf_pool_t* buf_pool, /*!< in/out: buffer pool in which
the page resides */
ulint size, /*!< in: block size, up to
UNIV_PAGE_SIZE */
ulint size, /*!< in: compressed page size
(between PAGE_ZIP_MIN_SIZE and
UNIV_PAGE_SIZE) */
ibool* lru) /*!< in: pointer to a variable
that will be assigned TRUE if
storage was allocated from the
LRU list and buf_pool->mutex was
temporarily released, or NULL if
the LRU list should not be used */
temporarily released */
{
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(ut_is_2pow(size));
ut_ad(size >= PAGE_ZIP_MIN_SIZE);
ut_ad(size <= UNIV_PAGE_SIZE);
return(buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size), lru));
return((byte*) buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size),
lru));
}
/**********************************************************************//**
@ -120,13 +122,17 @@ UNIV_INLINE
void
buf_buddy_free(
/*===========*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
ulint size) /*!< in: block size, up to
UNIV_PAGE_SIZE */
buf_pool_t* buf_pool, /*!< in/out: buffer pool in which
the block resides */
void* buf, /*!< in: block to be freed, must not
be pointed to by the buffer pool */
ulint size) /*!< in: block size,
up to UNIV_PAGE_SIZE */
{
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(ut_is_2pow(size));
ut_ad(size >= PAGE_ZIP_MIN_SIZE);
ut_ad(size <= UNIV_PAGE_SIZE);
buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
}

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