Merge 10.1 into 10.2
This commit is contained in:
commit
843e4508c0
@ -1094,7 +1094,7 @@ inline bool is_delimiter_command(char *name, ulong len)
|
|||||||
only name(first DELIMITER_NAME_LEN bytes) is checked.
|
only name(first DELIMITER_NAME_LEN bytes) is checked.
|
||||||
*/
|
*/
|
||||||
return (len >= DELIMITER_NAME_LEN &&
|
return (len >= DELIMITER_NAME_LEN &&
|
||||||
!my_strnncoll(charset_info, (uchar*) name, DELIMITER_NAME_LEN,
|
!my_strnncoll(&my_charset_latin1, (uchar*) name, DELIMITER_NAME_LEN,
|
||||||
(uchar *) DELIMITER_NAME, DELIMITER_NAME_LEN));
|
(uchar *) DELIMITER_NAME, DELIMITER_NAME_LEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <ut0mem.h>
|
#include <ut0mem.h>
|
||||||
#include <srv0start.h>
|
#include <srv0start.h>
|
||||||
#include <fil0fil.h>
|
#include <fil0fil.h>
|
||||||
|
#include <trx0sys.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <mysqld.h>
|
#include <mysqld.h>
|
||||||
@ -1680,26 +1681,30 @@ copy_back()
|
|||||||
ut_crc32_init();
|
ut_crc32_init();
|
||||||
|
|
||||||
/* copy undo tablespaces */
|
/* copy undo tablespaces */
|
||||||
if (srv_undo_tablespaces > 0) {
|
|
||||||
|
|
||||||
dst_dir = (srv_undo_dir && *srv_undo_dir)
|
|
||||||
? srv_undo_dir : mysql_data_home;
|
|
||||||
|
|
||||||
ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
|
dst_dir = (srv_undo_dir && *srv_undo_dir)
|
||||||
|
? srv_undo_dir : mysql_data_home;
|
||||||
|
|
||||||
for (ulong i = 1; i <= srv_undo_tablespaces; i++) {
|
ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
|
||||||
char filename[20];
|
|
||||||
sprintf(filename, "undo%03lu", i);
|
for (uint i = 1; i <= TRX_SYS_MAX_UNDO_SPACES; i++) {
|
||||||
if (!(ret = copy_or_move_file(filename, filename,
|
char filename[20];
|
||||||
dst_dir, 1))) {
|
sprintf(filename, "undo%03u", i);
|
||||||
goto cleanup;
|
if (!file_exists(filename)) {
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
if (!(ret = copy_or_move_file(filename, filename,
|
||||||
|
dst_dir, 1))) {
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_destroy(ds_data);
|
|
||||||
ds_data = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ds_destroy(ds_data);
|
||||||
|
ds_data = NULL;
|
||||||
|
|
||||||
|
/* copy redo logs */
|
||||||
|
|
||||||
dst_dir = (srv_log_group_home_dir && *srv_log_group_home_dir)
|
dst_dir = (srv_log_group_home_dir && *srv_log_group_home_dir)
|
||||||
? srv_log_group_home_dir : mysql_data_home;
|
? srv_log_group_home_dir : mysql_data_home;
|
||||||
|
|
||||||
@ -1825,7 +1830,7 @@ copy_back()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy buufer pool dump */
|
/* copy buffer pool dump */
|
||||||
|
|
||||||
if (innobase_buffer_pool_filename) {
|
if (innobase_buffer_pool_filename) {
|
||||||
const char *src_name;
|
const char *src_name;
|
||||||
|
@ -82,6 +82,8 @@ call mtr.check_testcase();
|
|||||||
|
|
||||||
let $datadir=`select @@datadir`;
|
let $datadir=`select @@datadir`;
|
||||||
list_files $datadir mysql_upgrade_info;
|
list_files $datadir mysql_upgrade_info;
|
||||||
|
list_files $datadir/test #sql*;
|
||||||
|
list_files $datadir/mysql #sql*;
|
||||||
|
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
|
||||||
|
2
mysql-test/r/delimiter_command_case_sensitivity.result
Normal file
2
mysql-test/r/delimiter_command_case_sensitivity.result
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
1
|
||||||
|
1
|
@ -843,5 +843,16 @@ Warning 1292 Incorrect datetime value: '1'
|
|||||||
Warning 1292 Incorrect datetime value: '1'
|
Warning 1292 Incorrect datetime value: '1'
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (d DATE);
|
||||||
|
INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24');
|
||||||
|
SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END;
|
||||||
|
d COUNT(*)
|
||||||
|
1985-05-13 1
|
||||||
|
1989-12-24 1
|
||||||
|
NULL 2
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
|
@ -52,6 +52,7 @@ alter table t1 rename renamed_t1;
|
|||||||
set global server_audit_events='connect,query';
|
set global server_audit_events='connect,query';
|
||||||
select 1,
|
select 1,
|
||||||
2,
|
2,
|
||||||
|
# comment
|
||||||
3;
|
3;
|
||||||
1 2 3
|
1 2 3
|
||||||
1 2 3
|
1 2 3
|
||||||
@ -170,7 +171,9 @@ id
|
|||||||
2
|
2
|
||||||
CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
||||||
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
||||||
SET PASSWORD FOR u1 = PASSWORD('pwd 098');
|
SET PASSWORD
|
||||||
|
# comment
|
||||||
|
FOR u1 = PASSWORD('pwd 098');
|
||||||
SET PASSWORD FOR u1=<secret>;
|
SET PASSWORD FOR u1=<secret>;
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '<secret>' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '<secret>' at line 1
|
||||||
CREATE USER u3 IDENTIFIED BY '';
|
CREATE USER u3 IDENTIFIED BY '';
|
||||||
@ -262,7 +265,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats,
|
|||||||
TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1,
|
TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID
|
||||||
@ -345,7 +348,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0
|
|||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1 = PASSWORD(*****)',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
|
||||||
|
@ -52,6 +52,7 @@ alter table t1 rename renamed_t1;
|
|||||||
set global server_audit_events='connect,query';
|
set global server_audit_events='connect,query';
|
||||||
select 1,
|
select 1,
|
||||||
2,
|
2,
|
||||||
|
# comment
|
||||||
3;
|
3;
|
||||||
1 2 3
|
1 2 3
|
||||||
1 2 3
|
1 2 3
|
||||||
@ -170,7 +171,9 @@ id
|
|||||||
2
|
2
|
||||||
CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
||||||
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
||||||
SET PASSWORD FOR u1 = PASSWORD('pwd 098');
|
SET PASSWORD
|
||||||
|
# comment
|
||||||
|
FOR u1 = PASSWORD('pwd 098');
|
||||||
SET PASSWORD FOR u1=<secret>;
|
SET PASSWORD FOR u1=<secret>;
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '<secret>' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '<secret>' at line 1
|
||||||
CREATE USER u3 IDENTIFIED BY '';
|
CREATE USER u3 IDENTIFIED BY '';
|
||||||
@ -262,7 +265,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats,
|
|||||||
TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1,
|
TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID
|
||||||
@ -345,7 +348,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0
|
|||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD\n# comment\nFOR u1 = PASSWORD(*****)',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
|
||||||
|
@ -38,6 +38,7 @@ alter table t1 rename renamed_t1;
|
|||||||
set global server_audit_events='connect,query';
|
set global server_audit_events='connect,query';
|
||||||
select 1,
|
select 1,
|
||||||
2,
|
2,
|
||||||
|
# comment
|
||||||
3;
|
3;
|
||||||
insert into t2 values (1), (2);
|
insert into t2 values (1), (2);
|
||||||
select * from t2;
|
select * from t2;
|
||||||
@ -106,7 +107,9 @@ insert into t1 values (1), (2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
||||||
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
||||||
SET PASSWORD FOR u1 = PASSWORD('pwd 098');
|
SET PASSWORD
|
||||||
|
# comment
|
||||||
|
FOR u1 = PASSWORD('pwd 098');
|
||||||
--error 1064
|
--error 1064
|
||||||
SET PASSWORD FOR u1=<secret>;
|
SET PASSWORD FOR u1=<secret>;
|
||||||
CREATE USER u3 IDENTIFIED BY '';
|
CREATE USER u3 IDENTIFIED BY '';
|
||||||
|
@ -38,6 +38,7 @@ alter table t1 rename renamed_t1;
|
|||||||
set global server_audit_events='connect,query';
|
set global server_audit_events='connect,query';
|
||||||
select 1,
|
select 1,
|
||||||
2,
|
2,
|
||||||
|
# comment
|
||||||
3;
|
3;
|
||||||
insert into t2 values (1), (2);
|
insert into t2 values (1), (2);
|
||||||
select * from t2;
|
select * from t2;
|
||||||
@ -106,7 +107,9 @@ insert into t1 values (1), (2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
CREATE USER u1 IDENTIFIED BY 'pwd-123';
|
||||||
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
|
||||||
SET PASSWORD FOR u1 = PASSWORD('pwd 098');
|
SET PASSWORD
|
||||||
|
# comment
|
||||||
|
FOR u1 = PASSWORD('pwd 098');
|
||||||
--error 1064
|
--error 1064
|
||||||
SET PASSWORD FOR u1=<secret>;
|
SET PASSWORD FOR u1=<secret>;
|
||||||
CREATE USER u3 IDENTIFIED BY '';
|
CREATE USER u3 IDENTIFIED BY '';
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
SET @orig = @@global.innodb_buffer_pool_dump_now;
|
SELECT @@global.innodb_buffer_pool_dump_now;
|
||||||
SELECT @orig;
|
@@global.innodb_buffer_pool_dump_now
|
||||||
@orig
|
|
||||||
0
|
0
|
||||||
|
SELECT variable_value INTO @old_dump_status FROM information_schema.global_status
|
||||||
|
WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
|
||||||
SET GLOBAL innodb_buffer_pool_dump_now = ON;
|
SET GLOBAL innodb_buffer_pool_dump_now = ON;
|
||||||
SELECT @@global.innodb_buffer_pool_dump_now;
|
SELECT @@global.innodb_buffer_pool_dump_now;
|
||||||
@@global.innodb_buffer_pool_dump_now
|
@@global.innodb_buffer_pool_dump_now
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
SET @orig = @@global.innodb_buffer_pool_dump_pct;
|
SET @orig = @@global.innodb_buffer_pool_dump_pct;
|
||||||
SELECT @@global.innodb_buffer_pool_dump_pct;
|
SELECT @orig;
|
||||||
@@global.innodb_buffer_pool_dump_pct
|
@orig
|
||||||
25
|
25
|
||||||
|
SET GLOBAL innodb_buffer_pool_dump_pct=3;
|
||||||
|
# Do the dump
|
||||||
SET GLOBAL innodb_buffer_pool_dump_pct=20;
|
SET GLOBAL innodb_buffer_pool_dump_pct=20;
|
||||||
SELECT @@global.innodb_buffer_pool_dump_pct;
|
SELECT @@global.innodb_buffer_pool_dump_pct;
|
||||||
@@global.innodb_buffer_pool_dump_pct
|
@@global.innodb_buffer_pool_dump_pct
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
SET @orig = @@global.innodb_buffer_pool_load_now;
|
SELECT @@global.innodb_buffer_pool_load_now;
|
||||||
SELECT @orig;
|
@@global.innodb_buffer_pool_load_now
|
||||||
@orig
|
|
||||||
0
|
0
|
||||||
SET GLOBAL innodb_buffer_pool_dump_now = ON;
|
|
||||||
SET GLOBAL innodb_buffer_pool_load_now = ON;
|
SET GLOBAL innodb_buffer_pool_load_now = ON;
|
||||||
SELECT variable_value
|
SELECT variable_value
|
||||||
FROM information_schema.global_status
|
FROM information_schema.global_status
|
||||||
|
@ -5,8 +5,31 @@
|
|||||||
-- source include/have_innodb.inc
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
# Check the default value
|
# Check the default value
|
||||||
SET @orig = @@global.innodb_buffer_pool_dump_now;
|
SELECT @@global.innodb_buffer_pool_dump_now;
|
||||||
SELECT @orig;
|
|
||||||
|
-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
|
||||||
|
-- error 0,1
|
||||||
|
-- remove_file $file
|
||||||
|
|
||||||
|
SELECT variable_value INTO @old_dump_status FROM information_schema.global_status
|
||||||
|
WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
|
||||||
|
|
||||||
|
# A previous test could have run buffer pool dump already;
|
||||||
|
# in this case we want to make sure that the current time is different
|
||||||
|
# from the timestamp in the status variable.
|
||||||
|
# We should have had a smart wait condition here, like the commented one below,
|
||||||
|
# let $wait_condition =
|
||||||
|
# SELECT TRIM(SUBSTR('$old_status', -8)) != DATE_FORMAT(CURTIME(), '%k:%i:%s');
|
||||||
|
# -- source include/wait_condition.inc
|
||||||
|
|
||||||
|
# ... but we can't because of MDEV-9867, so there will be just sleep instead.
|
||||||
|
# And it might be not enough to sleep one second, so we'll have to sleep two.
|
||||||
|
|
||||||
|
if (`SELECT variable_value LIKE '%completed at%' FROM information_schema.global_status
|
||||||
|
WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`)
|
||||||
|
{
|
||||||
|
-- sleep 2
|
||||||
|
}
|
||||||
|
|
||||||
# Do the dump
|
# Do the dump
|
||||||
SET GLOBAL innodb_buffer_pool_dump_now = ON;
|
SET GLOBAL innodb_buffer_pool_dump_now = ON;
|
||||||
@ -15,11 +38,11 @@ SELECT @@global.innodb_buffer_pool_dump_now;
|
|||||||
|
|
||||||
# Wait for the dump to complete
|
# Wait for the dump to complete
|
||||||
let $wait_condition =
|
let $wait_condition =
|
||||||
SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
|
SELECT variable_value != @old_dump_status
|
||||||
|
AND SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
|
||||||
FROM information_schema.global_status
|
FROM information_schema.global_status
|
||||||
WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
|
WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
|
||||||
-- source include/wait_condition.inc
|
-- source include/wait_condition.inc
|
||||||
|
|
||||||
# Confirm that the dump file has been created
|
# Confirm that the dump file has been created
|
||||||
-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
|
|
||||||
-- file_exists $file
|
-- file_exists $file
|
||||||
|
@ -11,9 +11,17 @@
|
|||||||
|
|
||||||
# Save the default value
|
# Save the default value
|
||||||
SET @orig = @@global.innodb_buffer_pool_dump_pct;
|
SET @orig = @@global.innodb_buffer_pool_dump_pct;
|
||||||
|
SELECT @orig;
|
||||||
|
|
||||||
# Check the default value
|
SET GLOBAL innodb_buffer_pool_dump_pct=3;
|
||||||
SELECT @@global.innodb_buffer_pool_dump_pct;
|
|
||||||
|
--echo # Do the dump
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--disable_result_log
|
||||||
|
--source innodb_buffer_pool_dump_now_basic.test
|
||||||
|
--enable_result_log
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
# Set the valid value
|
# Set the valid value
|
||||||
SET GLOBAL innodb_buffer_pool_dump_pct=20;
|
SET GLOBAL innodb_buffer_pool_dump_pct=20;
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
--innodb-buffer-pool-load-at-startup=off
|
@ -5,44 +5,22 @@
|
|||||||
-- source include/have_innodb.inc
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
# Check the default value
|
# Check the default value
|
||||||
SET @orig = @@global.innodb_buffer_pool_load_now;
|
SELECT @@global.innodb_buffer_pool_load_now;
|
||||||
SELECT @orig;
|
|
||||||
|
|
||||||
let $old_status= `SELECT variable_value FROM information_schema.global_status
|
# Make sure there is a dump file to load
|
||||||
WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`;
|
|
||||||
|
|
||||||
# A previous test could have run buffer pool dump already;
|
|
||||||
# in this case we want to make sure that the current time is different
|
|
||||||
# from the timestamp in the status variable.
|
|
||||||
# We should have had a smart wait condition here, like the commented one below,
|
|
||||||
# but we can't because of MDEV-9867, so there will be just sleep instead.
|
|
||||||
# And it might be not enough to sleep one second, so we'll have to sleep two.
|
|
||||||
# let $wait_condition =
|
|
||||||
# SELECT TRIM(SUBSTR('$old_status', -8)) != DATE_FORMAT(CURTIME(), '%k:%i:%s');
|
|
||||||
# -- source include/wait_condition.inc
|
|
||||||
if (`SELECT count(*) > 0 FROM information_schema.global_status
|
|
||||||
WHERE (LOWER(variable_name) = 'innodb_buffer_pool_dump_status' or
|
|
||||||
LOWER(variable_name) = 'innodb_buffer_pool_load_status')
|
|
||||||
and variable_value LIKE '%completed at%'`)
|
|
||||||
{
|
|
||||||
-- sleep 2
|
|
||||||
}
|
|
||||||
# Do the dump
|
|
||||||
SET GLOBAL innodb_buffer_pool_dump_now = ON;
|
|
||||||
|
|
||||||
# Wait for the dump to complete
|
|
||||||
let $wait_condition =
|
|
||||||
SELECT variable_value != '$old_status'
|
|
||||||
AND SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
|
|
||||||
FROM information_schema.global_status
|
|
||||||
WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
|
|
||||||
--disable_warnings
|
|
||||||
-- source include/wait_condition.inc
|
|
||||||
--enable_warnings
|
|
||||||
|
|
||||||
# Confirm the file is really created
|
|
||||||
-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
|
-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
|
||||||
|
-- error 0,1
|
||||||
-- file_exists $file
|
-- file_exists $file
|
||||||
|
if ($errno)
|
||||||
|
{
|
||||||
|
# Dump file does not exist, get it created
|
||||||
|
--disable_query_log
|
||||||
|
--disable_result_log
|
||||||
|
--source innodb_buffer_pool_dump_now_basic.test
|
||||||
|
--enable_result_log
|
||||||
|
--enable_query_log
|
||||||
|
}
|
||||||
|
|
||||||
let $old_load_status=
|
let $old_load_status=
|
||||||
`SELECT variable_value FROM information_schema.global_status
|
`SELECT variable_value FROM information_schema.global_status
|
||||||
|
3
mysql-test/t/delimiter_case_mdev_10728.sql
Normal file
3
mysql-test/t/delimiter_case_mdev_10728.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
DeLiMiTeR A;
|
||||||
|
SELECT 1 A;
|
||||||
|
delimiter ;
|
2
mysql-test/t/delimiter_command_case_sensitivity.test
Normal file
2
mysql-test/t/delimiter_command_case_sensitivity.test
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# MDEV-10728
|
||||||
|
--exec $MYSQL --default-character-set=binary < "t/delimiter_case_mdev_10728.sql"
|
@ -576,6 +576,15 @@ SELECT DATE(a), DATE(b), DATE(c) FROM t1;
|
|||||||
SELECT DATE(COALESCE(a)), DATE(COALESCE(b)), DATE(COALESCE(c)) FROM t1;
|
SELECT DATE(COALESCE(a)), DATE(COALESCE(b)), DATE(COALESCE(c)) FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (d DATE);
|
||||||
|
INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24');
|
||||||
|
SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
--source include/have_partition.inc
|
||||||
# Save the initial number of concurrent sessions.
|
# Save the initial number of concurrent sessions.
|
||||||
--source include/count_sessions.inc
|
--source include/count_sessions.inc
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define PLUGIN_VERSION 0x104
|
#define PLUGIN_VERSION 0x104
|
||||||
#define PLUGIN_STR_VERSION "1.4.2"
|
#define PLUGIN_STR_VERSION "1.4.3"
|
||||||
|
|
||||||
#define _my_thread_var loc_thread_var
|
#define _my_thread_var loc_thread_var
|
||||||
|
|
||||||
@ -1118,6 +1118,21 @@ do { \
|
|||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define ESC_MAP_SIZE 0x60
|
||||||
|
static const char esc_map[ESC_MAP_SIZE]=
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '\'', 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\\', 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static char escaped_char(char c)
|
||||||
|
{
|
||||||
|
return ((unsigned char ) c) >= ESC_MAP_SIZE ? 0 : esc_map[(unsigned char) c];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setup_connection_initdb(struct connection_info *cn,
|
static void setup_connection_initdb(struct connection_info *cn,
|
||||||
@ -1324,21 +1339,16 @@ static size_t escape_string(const char *str, unsigned int len,
|
|||||||
const char *res_end= result + result_len - 2;
|
const char *res_end= result + result_len - 2;
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
|
char esc_c;
|
||||||
|
|
||||||
if (result >= res_end)
|
if (result >= res_end)
|
||||||
break;
|
break;
|
||||||
if (*str == '\'')
|
if ((esc_c= escaped_char(*str)))
|
||||||
{
|
{
|
||||||
if (result+1 >= res_end)
|
if (result+1 >= res_end)
|
||||||
break;
|
break;
|
||||||
*(result++)= '\\';
|
*(result++)= '\\';
|
||||||
*(result++)= '\'';
|
*(result++)= esc_c;
|
||||||
}
|
|
||||||
else if (*str == '\\')
|
|
||||||
{
|
|
||||||
if (result+1 >= res_end)
|
|
||||||
break;
|
|
||||||
*(result++)= '\\';
|
|
||||||
*(result++)= '\\';
|
|
||||||
}
|
}
|
||||||
else if (is_space(*str))
|
else if (is_space(*str))
|
||||||
*(result++)= ' ';
|
*(result++)= ' ';
|
||||||
@ -1427,19 +1437,12 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len,
|
|||||||
no_password:
|
no_password:
|
||||||
if (result >= res_end)
|
if (result >= res_end)
|
||||||
break;
|
break;
|
||||||
if (*str == '\'')
|
if ((b_char= escaped_char(*str)))
|
||||||
{
|
{
|
||||||
if (result+1 >= res_end)
|
if (result+1 >= res_end)
|
||||||
break;
|
break;
|
||||||
*(result++)= '\\';
|
*(result++)= '\\';
|
||||||
*(result++)= '\'';
|
*(result++)= b_char;
|
||||||
}
|
|
||||||
else if (*str == '\\')
|
|
||||||
{
|
|
||||||
if (result+1 >= res_end)
|
|
||||||
break;
|
|
||||||
*(result++)= '\\';
|
|
||||||
*(result++)= '\\';
|
|
||||||
}
|
}
|
||||||
else if (is_space(*str))
|
else if (is_space(*str))
|
||||||
*(result++)= ' ';
|
*(result++)= ' ';
|
||||||
|
@ -45,6 +45,8 @@ static int read_string(File file, uchar**to, size_t length)
|
|||||||
|
|
||||||
engine_name is a LEX_STRING, where engine_name->str must point to
|
engine_name is a LEX_STRING, where engine_name->str must point to
|
||||||
a buffer of at least NAME_CHAR_LEN+1 bytes.
|
a buffer of at least NAME_CHAR_LEN+1 bytes.
|
||||||
|
If engine_name is 0, then the function will only test if the file is a
|
||||||
|
view or not
|
||||||
|
|
||||||
@retval FRMTYPE_ERROR error
|
@retval FRMTYPE_ERROR error
|
||||||
@retval FRMTYPE_TABLE table
|
@retval FRMTYPE_TABLE table
|
||||||
@ -72,12 +74,23 @@ frm_type_enum dd_frm_type(THD *thd, char *path, LEX_STRING *engine_name)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We return FRMTYPE_TABLE if we can read the .frm file. This allows us
|
||||||
|
to drop a bad .frm file with DROP TABLE
|
||||||
|
*/
|
||||||
type= FRMTYPE_TABLE;
|
type= FRMTYPE_TABLE;
|
||||||
|
|
||||||
if (!is_binary_frm_header(header) || !engine_name)
|
/* engine_name is 0 if we only want to know if table is view or not */
|
||||||
|
if (!engine_name)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
/* Initialize engine name in case we are not able to find it out */
|
||||||
engine_name->length= 0;
|
engine_name->length= 0;
|
||||||
|
engine_name->str[0]= 0;
|
||||||
|
|
||||||
|
if (!is_binary_frm_header(header))
|
||||||
|
goto err;
|
||||||
|
|
||||||
dbt= header[3];
|
dbt= header[3];
|
||||||
|
|
||||||
/* cannot use ha_resolve_by_legacy_type without a THD */
|
/* cannot use ha_resolve_by_legacy_type without a THD */
|
||||||
|
@ -5072,10 +5072,15 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name,
|
|||||||
{
|
{
|
||||||
char engine_buf[NAME_CHAR_LEN + 1];
|
char engine_buf[NAME_CHAR_LEN + 1];
|
||||||
LEX_STRING engine= { engine_buf, 0 };
|
LEX_STRING engine= { engine_buf, 0 };
|
||||||
|
frm_type_enum type;
|
||||||
|
|
||||||
if (dd_frm_type(thd, path, &engine) != FRMTYPE_VIEW)
|
if ((type= dd_frm_type(thd, path, &engine)) == FRMTYPE_ERROR)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
if (type != FRMTYPE_VIEW)
|
||||||
{
|
{
|
||||||
plugin_ref p= plugin_lock_by_name(thd, &engine, MYSQL_STORAGE_ENGINE_PLUGIN);
|
plugin_ref p= plugin_lock_by_name(thd, &engine,
|
||||||
|
MYSQL_STORAGE_ENGINE_PLUGIN);
|
||||||
*hton= p ? plugin_hton(p) : NULL;
|
*hton= p ? plugin_hton(p) : NULL;
|
||||||
if (*hton)
|
if (*hton)
|
||||||
// verify that the table really exists
|
// verify that the table really exists
|
||||||
|
11
sql/item.h
11
sql/item.h
@ -2768,6 +2768,17 @@ public:
|
|||||||
Field *result_field;
|
Field *result_field;
|
||||||
Item_null_result(THD *thd): Item_null(thd), result_field(0) {}
|
Item_null_result(THD *thd): Item_null(thd), result_field(0) {}
|
||||||
bool is_result_field() { return result_field != 0; }
|
bool is_result_field() { return result_field != 0; }
|
||||||
|
#if MARIADB_VERSION_ID < 100300
|
||||||
|
enum_field_types field_type() const
|
||||||
|
{
|
||||||
|
return result_field->type();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const Type_handler *type_handler() const
|
||||||
|
{
|
||||||
|
return result_field->type_handler();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
void save_in_result_field(bool no_conversions)
|
void save_in_result_field(bool no_conversions)
|
||||||
{
|
{
|
||||||
save_in_field(result_field, no_conversions);
|
save_in_field(result_field, no_conversions);
|
||||||
|
@ -4168,7 +4168,8 @@ buf_page_get_gen(
|
|||||||
ulint retries = 0;
|
ulint retries = 0;
|
||||||
buf_pool_t* buf_pool = buf_pool_get(page_id);
|
buf_pool_t* buf_pool = buf_pool_get(page_id);
|
||||||
|
|
||||||
ut_ad(mtr->is_active());
|
ut_ad((mtr == NULL) == (mode == BUF_EVICT_IF_IN_POOL));
|
||||||
|
ut_ad(!mtr || mtr->is_active());
|
||||||
ut_ad((rw_latch == RW_S_LATCH)
|
ut_ad((rw_latch == RW_S_LATCH)
|
||||||
|| (rw_latch == RW_X_LATCH)
|
|| (rw_latch == RW_X_LATCH)
|
||||||
|| (rw_latch == RW_SX_LATCH)
|
|| (rw_latch == RW_SX_LATCH)
|
||||||
@ -4180,29 +4181,31 @@ buf_page_get_gen(
|
|||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
case BUF_EVICT_IF_IN_POOL:
|
||||||
|
/* After DISCARD TABLESPACE, the tablespace would not exist,
|
||||||
|
but in IMPORT TABLESPACE, PageConverter::operator() must
|
||||||
|
replace any old pages, which were not evicted during DISCARD.
|
||||||
|
Skip the assertion on space_page_size. */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ut_error;
|
||||||
case BUF_GET_NO_LATCH:
|
case BUF_GET_NO_LATCH:
|
||||||
ut_ad(rw_latch == RW_NO_LATCH);
|
ut_ad(rw_latch == RW_NO_LATCH);
|
||||||
break;
|
/* fall through */
|
||||||
case BUF_GET:
|
case BUF_GET:
|
||||||
case BUF_GET_IF_IN_POOL:
|
case BUF_GET_IF_IN_POOL:
|
||||||
case BUF_PEEK_IF_IN_POOL:
|
case BUF_PEEK_IF_IN_POOL:
|
||||||
case BUF_GET_IF_IN_POOL_OR_WATCH:
|
case BUF_GET_IF_IN_POOL_OR_WATCH:
|
||||||
case BUF_GET_POSSIBLY_FREED:
|
case BUF_GET_POSSIBLY_FREED:
|
||||||
break;
|
bool found;
|
||||||
default:
|
const page_size_t& space_page_size
|
||||||
ut_error;
|
= fil_space_get_page_size(page_id.space(), &found);
|
||||||
|
ut_ad(found);
|
||||||
|
ut_ad(page_size.equals_to(space_page_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found;
|
|
||||||
const page_size_t& space_page_size
|
|
||||||
= fil_space_get_page_size(page_id.space(), &found);
|
|
||||||
|
|
||||||
ut_ad(found);
|
|
||||||
|
|
||||||
ut_ad(page_size.equals_to(space_page_size));
|
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
|
|
||||||
ut_ad(!ibuf_inside(mtr)
|
ut_ad(!mtr || !ibuf_inside(mtr)
|
||||||
|| ibuf_page_low(page_id, page_size, FALSE, file, line, NULL));
|
|| ibuf_page_low(page_id, page_size, FALSE, file, line, NULL));
|
||||||
|
|
||||||
buf_pool->stat.n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
@ -4263,7 +4266,24 @@ loop:
|
|||||||
sure that no state change takes place. */
|
sure that no state change takes place. */
|
||||||
fix_block = block;
|
fix_block = block;
|
||||||
|
|
||||||
buf_block_fix(fix_block);
|
if (fsp_is_system_temporary(page_id.space())) {
|
||||||
|
/* For temporary tablespace,
|
||||||
|
the mutex is being used for
|
||||||
|
synchronization between user
|
||||||
|
thread and flush thread,
|
||||||
|
instead of block->lock. See
|
||||||
|
buf_flush_page() for the flush
|
||||||
|
thread counterpart. */
|
||||||
|
|
||||||
|
BPageMutex* fix_mutex
|
||||||
|
= buf_page_get_mutex(
|
||||||
|
&fix_block->page);
|
||||||
|
mutex_enter(fix_mutex);
|
||||||
|
buf_block_fix(fix_block);
|
||||||
|
mutex_exit(fix_mutex);
|
||||||
|
} else {
|
||||||
|
buf_block_fix(fix_block);
|
||||||
|
}
|
||||||
|
|
||||||
/* Now safe to release page_hash mutex */
|
/* Now safe to release page_hash mutex */
|
||||||
rw_lock_x_unlock(hash_lock);
|
rw_lock_x_unlock(hash_lock);
|
||||||
@ -4273,13 +4293,15 @@ loop:
|
|||||||
rw_lock_x_unlock(hash_lock);
|
rw_lock_x_unlock(hash_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == BUF_GET_IF_IN_POOL
|
switch (mode) {
|
||||||
|| mode == BUF_PEEK_IF_IN_POOL
|
case BUF_GET_IF_IN_POOL:
|
||||||
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
|
case BUF_GET_IF_IN_POOL_OR_WATCH:
|
||||||
|
case BUF_PEEK_IF_IN_POOL:
|
||||||
|
case BUF_EVICT_IF_IN_POOL:
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_X));
|
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_X));
|
||||||
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_S));
|
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_S));
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4354,15 +4376,29 @@ loop:
|
|||||||
fix_block = block;
|
fix_block = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_block_fix(fix_block);
|
if (fsp_is_system_temporary(page_id.space())) {
|
||||||
|
/* For temporary tablespace, the mutex is being used
|
||||||
|
for synchronization between user thread and flush
|
||||||
|
thread, instead of block->lock. See buf_flush_page()
|
||||||
|
for the flush thread counterpart. */
|
||||||
|
BPageMutex* fix_mutex = buf_page_get_mutex(
|
||||||
|
&fix_block->page);
|
||||||
|
mutex_enter(fix_mutex);
|
||||||
|
buf_block_fix(fix_block);
|
||||||
|
mutex_exit(fix_mutex);
|
||||||
|
} else {
|
||||||
|
buf_block_fix(fix_block);
|
||||||
|
}
|
||||||
|
|
||||||
/* Now safe to release page_hash mutex */
|
/* Now safe to release page_hash mutex */
|
||||||
rw_lock_s_unlock(hash_lock);
|
rw_lock_s_unlock(hash_lock);
|
||||||
|
|
||||||
got_block:
|
got_block:
|
||||||
|
|
||||||
if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL) {
|
switch (mode) {
|
||||||
|
case BUF_GET_IF_IN_POOL:
|
||||||
|
case BUF_PEEK_IF_IN_POOL:
|
||||||
|
case BUF_EVICT_IF_IN_POOL:
|
||||||
buf_page_t* fix_page = &fix_block->page;
|
buf_page_t* fix_page = &fix_block->page;
|
||||||
BPageMutex* fix_mutex = buf_page_get_mutex(fix_page);
|
BPageMutex* fix_mutex = buf_page_get_mutex(fix_page);
|
||||||
mutex_enter(fix_mutex);
|
mutex_enter(fix_mutex);
|
||||||
@ -4394,6 +4430,20 @@ got_block:
|
|||||||
os_thread_sleep(WAIT_FOR_WRITE);
|
os_thread_sleep(WAIT_FOR_WRITE);
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
|
||||||
|
evict_from_pool:
|
||||||
|
ut_ad(!fix_block->page.oldest_modification);
|
||||||
|
buf_pool_mutex_enter(buf_pool);
|
||||||
|
buf_block_unfix(fix_block);
|
||||||
|
|
||||||
|
if (!buf_LRU_free_page(&fix_block->page, true)) {
|
||||||
|
ut_ad(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_pool_mutex_exit(buf_pool);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUF_BLOCK_ZIP_PAGE:
|
case BUF_BLOCK_ZIP_PAGE:
|
||||||
@ -4426,6 +4476,10 @@ got_block:
|
|||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
|
||||||
|
goto evict_from_pool;
|
||||||
|
}
|
||||||
|
|
||||||
/* Buffer-fix the block so that it cannot be evicted
|
/* Buffer-fix the block so that it cannot be evicted
|
||||||
or relocated while we are attempting to allocate an
|
or relocated while we are attempting to allocate an
|
||||||
uncompressed page. */
|
uncompressed page. */
|
||||||
|
@ -3830,8 +3830,7 @@ FlushObserver::flush()
|
|||||||
that will be freed by the clean-up of the ALTER operation.
|
that will be freed by the clean-up of the ALTER operation.
|
||||||
(Maybe, instead of buf_pool->flush_list, use a dedicated list
|
(Maybe, instead of buf_pool->flush_list, use a dedicated list
|
||||||
for pages on which redo logging has been disabled.) */
|
for pages on which redo logging has been disabled.) */
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(m_space_id, m_trx);
|
||||||
m_space_id, BUF_REMOVE_FLUSH_WRITE, m_trx);
|
|
||||||
|
|
||||||
/* Wait for all dirty pages were flushed. */
|
/* Wait for all dirty pages were flushed. */
|
||||||
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
|
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
|
||||||
|
@ -586,8 +586,8 @@ rescan:
|
|||||||
|
|
||||||
/* If flush observer is NULL, flush page for space id,
|
/* If flush observer is NULL, flush page for space id,
|
||||||
or flush page for flush observer. */
|
or flush page for flush observer. */
|
||||||
if ((observer != NULL && observer != bpage->flush_observer)
|
if (observer ? (observer != bpage->flush_observer)
|
||||||
|| (observer == NULL && id != bpage->id.space())) {
|
: (id != bpage->id.space())) {
|
||||||
|
|
||||||
/* Skip this block, as it does not belong to
|
/* Skip this block, as it does not belong to
|
||||||
the target space. */
|
the target space. */
|
||||||
@ -657,24 +657,27 @@ rescan:
|
|||||||
return(all_freed ? DB_SUCCESS : DB_FAIL);
|
return(all_freed ? DB_SUCCESS : DB_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Remove or flush all the dirty pages that belong to a given tablespace
|
||||||
Remove or flush all the dirty pages that belong to a given tablespace
|
|
||||||
inside a specific buffer pool instance. The pages will remain in the LRU
|
inside a specific buffer pool instance. The pages will remain in the LRU
|
||||||
list and will be evicted from the LRU list as they age and move towards
|
list and will be evicted from the LRU list as they age and move towards
|
||||||
the tail of the LRU list. */
|
the tail of the LRU list.
|
||||||
|
@param[in,out] buf_pool buffer pool
|
||||||
|
@param[in] id tablespace identifier
|
||||||
|
@param[in] observer flush observer,
|
||||||
|
or NULL if the files should not be written to
|
||||||
|
@param[in] trx transaction (to check for interrupt),
|
||||||
|
or NULL if the files should not be written to
|
||||||
|
*/
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
buf_flush_dirty_pages(
|
buf_flush_dirty_pages(
|
||||||
/*==================*/
|
buf_pool_t* buf_pool,
|
||||||
buf_pool_t* buf_pool, /*!< buffer pool instance */
|
ulint id,
|
||||||
ulint id, /*!< in: space id */
|
FlushObserver* observer,
|
||||||
FlushObserver* observer, /*!< in: flush observer */
|
const trx_t* trx)
|
||||||
bool flush, /*!< in: flush to disk if true otherwise
|
|
||||||
remove the pages without flushing */
|
|
||||||
const trx_t* trx) /*!< to check if the operation must
|
|
||||||
be interrupted */
|
|
||||||
{
|
{
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
|
bool flush = trx != NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
buf_pool_mutex_enter(buf_pool);
|
buf_pool_mutex_enter(buf_pool);
|
||||||
@ -708,238 +711,30 @@ buf_flush_dirty_pages(
|
|||||||
|| buf_pool_get_dirty_pages_count(buf_pool, id, observer) == 0);
|
|| buf_pool_get_dirty_pages_count(buf_pool, id, observer) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Empty the flush list for all pages belonging to a tablespace.
|
||||||
Remove all pages that belong to a given tablespace inside a specific
|
@param[in] id tablespace identifier
|
||||||
buffer pool instance when we are DISCARDing the tablespace. */
|
@param[in] trx transaction, for checking for user interrupt;
|
||||||
static
|
or NULL if nothing is to be written
|
||||||
|
@param[in] drop_ahi whether to drop the adaptive hash index */
|
||||||
void
|
void
|
||||||
buf_LRU_remove_all_pages(
|
buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi)
|
||||||
/*=====================*/
|
|
||||||
buf_pool_t* buf_pool, /*!< buffer pool instance */
|
|
||||||
ulint id) /*!< in: space id */
|
|
||||||
{
|
|
||||||
buf_page_t* bpage;
|
|
||||||
ibool all_freed;
|
|
||||||
|
|
||||||
scan_again:
|
|
||||||
buf_pool_mutex_enter(buf_pool);
|
|
||||||
|
|
||||||
all_freed = TRUE;
|
|
||||||
|
|
||||||
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
|
||||||
bpage != NULL;
|
|
||||||
/* No op */) {
|
|
||||||
|
|
||||||
rw_lock_t* hash_lock;
|
|
||||||
buf_page_t* prev_bpage;
|
|
||||||
BPageMutex* block_mutex;
|
|
||||||
|
|
||||||
ut_a(buf_page_in_file(bpage));
|
|
||||||
ut_ad(bpage->in_LRU_list);
|
|
||||||
|
|
||||||
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
|
||||||
|
|
||||||
/* bpage->id.space() and bpage->io_fix are protected by
|
|
||||||
buf_pool->mutex and the block_mutex. It is safe to check
|
|
||||||
them while holding buf_pool->mutex only. */
|
|
||||||
|
|
||||||
if (bpage->id.space() != 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 {
|
|
||||||
hash_lock = buf_page_hash_lock_get(buf_pool, bpage->id);
|
|
||||||
|
|
||||||
rw_lock_x_lock(hash_lock);
|
|
||||||
|
|
||||||
block_mutex = buf_page_get_mutex(bpage);
|
|
||||||
|
|
||||||
mutex_enter(block_mutex);
|
|
||||||
|
|
||||||
if (bpage->buf_fix_count > 0) {
|
|
||||||
|
|
||||||
mutex_exit(block_mutex);
|
|
||||||
|
|
||||||
rw_lock_x_unlock(hash_lock);
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(mutex_own(block_mutex));
|
|
||||||
|
|
||||||
DBUG_PRINT("ib_buf", ("evict page %u:%u"
|
|
||||||
" state %u",
|
|
||||||
bpage->id.space(),
|
|
||||||
bpage->id.page_no(),
|
|
||||||
bpage->state));
|
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
|
||||||
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
|
|
||||||
/* Do nothing, because the adaptive hash index
|
|
||||||
covers uncompressed pages only. */
|
|
||||||
} else if (((buf_block_t*) bpage)->index) {
|
|
||||||
buf_pool_mutex_exit(buf_pool);
|
|
||||||
|
|
||||||
rw_lock_x_unlock(hash_lock);
|
|
||||||
|
|
||||||
mutex_exit(block_mutex);
|
|
||||||
|
|
||||||
/* Note that the following call will acquire
|
|
||||||
and release block->lock X-latch.
|
|
||||||
Note that the table cannot be evicted during
|
|
||||||
the execution of ALTER TABLE...DISCARD TABLESPACE
|
|
||||||
because MySQL is keeping the table handle open. */
|
|
||||||
|
|
||||||
btr_search_drop_page_hash_when_freed(
|
|
||||||
bpage->id, bpage->size);
|
|
||||||
|
|
||||||
goto scan_again;
|
|
||||||
} else {
|
|
||||||
/* This debug check uses a dirty read that could
|
|
||||||
theoretically cause false positives while
|
|
||||||
buf_pool_clear_hash_index() is executing,
|
|
||||||
if the writes to block->index=NULL and
|
|
||||||
block->n_pointers=0 are reordered.
|
|
||||||
(Other conflicting access paths to the adaptive hash
|
|
||||||
index should not be possible, because when a
|
|
||||||
tablespace is being discarded or dropped, there must
|
|
||||||
be no concurrect access to the contained tables.) */
|
|
||||||
assert_block_ahi_empty((buf_block_t*) bpage);
|
|
||||||
}
|
|
||||||
#endif /* BTR_CUR_HASH_ADAPT */
|
|
||||||
|
|
||||||
if (bpage->oldest_modification != 0) {
|
|
||||||
|
|
||||||
buf_flush_remove(bpage);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(!bpage->in_flush_list);
|
|
||||||
|
|
||||||
/* Remove from the LRU list. */
|
|
||||||
|
|
||||||
if (buf_LRU_block_remove_hashed(bpage, true)) {
|
|
||||||
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
|
|
||||||
} else {
|
|
||||||
ut_ad(block_mutex == &buf_pool->zip_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(!mutex_own(block_mutex));
|
|
||||||
|
|
||||||
/* buf_LRU_block_remove_hashed() releases the hash_lock */
|
|
||||||
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_X));
|
|
||||||
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_S));
|
|
||||||
|
|
||||||
next_page:
|
|
||||||
bpage = prev_bpage;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf_pool_mutex_exit(buf_pool);
|
|
||||||
|
|
||||||
if (!all_freed) {
|
|
||||||
os_thread_sleep(20000);
|
|
||||||
|
|
||||||
goto scan_again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************//**
|
|
||||||
Remove pages belonging to a given tablespace inside a specific
|
|
||||||
buffer pool instance when we are deleting the data file(s) of that
|
|
||||||
tablespace. The pages still remain a part of LRU and are evicted from
|
|
||||||
the list as they age towards the tail of the LRU only if buf_remove
|
|
||||||
is BUF_REMOVE_FLUSH_NO_WRITE. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
buf_LRU_remove_pages(
|
|
||||||
/*=================*/
|
|
||||||
buf_pool_t* buf_pool, /*!< buffer pool instance */
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
buf_remove_t buf_remove, /*!< in: remove or flush strategy */
|
|
||||||
const trx_t* trx) /*!< to check if the operation must
|
|
||||||
be interrupted */
|
|
||||||
{
|
{
|
||||||
FlushObserver* observer = (trx == NULL) ? NULL : trx->flush_observer;
|
FlushObserver* observer = (trx == NULL) ? NULL : trx->flush_observer;
|
||||||
|
/* Pages in the system tablespace must never be discarded. */
|
||||||
|
ut_ad(id || trx);
|
||||||
|
|
||||||
switch (buf_remove) {
|
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
|
||||||
case BUF_REMOVE_ALL_NO_WRITE:
|
buf_pool_t* buf_pool = buf_pool_from_array(i);
|
||||||
buf_LRU_remove_all_pages(buf_pool, id);
|
if (drop_ahi) {
|
||||||
break;
|
|
||||||
|
|
||||||
case BUF_REMOVE_FLUSH_NO_WRITE:
|
|
||||||
/* Pass trx as NULL to avoid interruption check. */
|
|
||||||
buf_flush_dirty_pages(buf_pool, id, observer, false, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BUF_REMOVE_FLUSH_WRITE:
|
|
||||||
buf_flush_dirty_pages(buf_pool, id, observer, true, trx);
|
|
||||||
|
|
||||||
if (observer == NULL) {
|
|
||||||
/* Ensure that all asynchronous IO is completed. */
|
|
||||||
os_aio_wait_until_no_pending_writes();
|
|
||||||
fil_flush(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************//**
|
|
||||||
Flushes all dirty pages or removes all pages belonging
|
|
||||||
to a given tablespace. A PROBLEM: if readahead is being started, what
|
|
||||||
guarantees that it will not try to read in pages after this operation
|
|
||||||
has completed? */
|
|
||||||
void
|
|
||||||
buf_LRU_flush_or_remove_pages(
|
|
||||||
/*==========================*/
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
buf_remove_t buf_remove, /*!< in: remove or flush strategy */
|
|
||||||
const trx_t* trx) /*!< to check if the operation must
|
|
||||||
be interrupted */
|
|
||||||
{
|
|
||||||
ulint i;
|
|
||||||
|
|
||||||
/* Before we attempt to drop pages one by one we first
|
|
||||||
attempt to drop page hash index entries in batches to make
|
|
||||||
it more efficient. The batching attempt is a best effort
|
|
||||||
attempt and does not guarantee that all pages hash entries
|
|
||||||
will be dropped. We get rid of remaining page hash entries
|
|
||||||
one by one below. */
|
|
||||||
for (i = 0; i < srv_buf_pool_instances; i++) {
|
|
||||||
buf_pool_t* buf_pool;
|
|
||||||
|
|
||||||
buf_pool = buf_pool_from_array(i);
|
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
|
||||||
switch (buf_remove) {
|
|
||||||
case BUF_REMOVE_ALL_NO_WRITE:
|
|
||||||
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
|
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
|
||||||
break;
|
|
||||||
|
|
||||||
case BUF_REMOVE_FLUSH_NO_WRITE:
|
|
||||||
/* It is a DROP TABLE for a single table
|
|
||||||
tablespace. No AHI entries exist because
|
|
||||||
we already dealt with them when freeing up
|
|
||||||
extents. */
|
|
||||||
case BUF_REMOVE_FLUSH_WRITE:
|
|
||||||
/* We allow read-only queries against the
|
|
||||||
table, there is no need to drop the AHI entries. */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif /* BTR_CUR_HASH_ADAPT */
|
buf_flush_dirty_pages(buf_pool, id, observer, trx);
|
||||||
buf_LRU_remove_pages(buf_pool, id, buf_remove, trx);
|
}
|
||||||
|
|
||||||
|
if (trx && !observer && !trx_is_interrupted(trx)) {
|
||||||
|
/* Ensure that all asynchronous IO is completed. */
|
||||||
|
os_aio_wait_until_no_pending_writes();
|
||||||
|
fil_flush(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1641,7 +1641,7 @@ dict_table_rename_in_cache(
|
|||||||
return(DB_OUT_OF_MEMORY);
|
return(DB_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE);
|
fil_delete_tablespace(table->space, true);
|
||||||
|
|
||||||
/* Delete any temp file hanging around. */
|
/* Delete any temp file hanging around. */
|
||||||
if (os_file_status(filepath, &exists, &ftype)
|
if (os_file_status(filepath, &exists, &ftype)
|
||||||
|
@ -2449,7 +2449,7 @@ fil_recreate_tablespace(
|
|||||||
|
|
||||||
/* Step-1: Invalidate buffer pool pages belonging to the tablespace
|
/* Step-1: Invalidate buffer pool pages belonging to the tablespace
|
||||||
to re-create. */
|
to re-create. */
|
||||||
buf_LRU_flush_or_remove_pages(space_id, BUF_REMOVE_ALL_NO_WRITE, 0);
|
buf_LRU_flush_or_remove_pages(space_id, NULL);
|
||||||
|
|
||||||
/* Remove all insert buffer entries for the tablespace */
|
/* Remove all insert buffer entries for the tablespace */
|
||||||
ibuf_delete_for_discarded_space(space_id);
|
ibuf_delete_for_discarded_space(space_id);
|
||||||
@ -2907,7 +2907,7 @@ fil_close_tablespace(
|
|||||||
completely and permanently. The flag stop_new_ops also prevents
|
completely and permanently. The flag stop_new_ops also prevents
|
||||||
fil_flush() from being applied to this tablespace. */
|
fil_flush() from being applied to this tablespace. */
|
||||||
|
|
||||||
buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_FLUSH_WRITE, trx);
|
buf_LRU_flush_or_remove_pages(id, trx);
|
||||||
|
|
||||||
/* If the free is successful, the X lock will be released before
|
/* If the free is successful, the X lock will be released before
|
||||||
the space memory data structure is freed. */
|
the space memory data structure is freed. */
|
||||||
@ -2959,17 +2959,12 @@ fil_table_accessible(const dict_table_t* table)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Deletes an IBD tablespace, either general or single-table.
|
/** Delete a tablespace and associated .ibd file.
|
||||||
The tablespace must be cached in the memory cache. This will delete the
|
@param[in] id tablespace identifier
|
||||||
datafile, fil_space_t & fil_node_t entries from the file_system_t cache.
|
@param[in] drop_ahi whether to drop the adaptive hash index
|
||||||
@param[in] space_id Tablespace id
|
@return DB_SUCCESS or error */
|
||||||
@param[in] buf_remove Specify the action to take on the pages
|
|
||||||
for this table in the buffer pool.
|
|
||||||
@return DB_SUCCESS or error */
|
|
||||||
dberr_t
|
dberr_t
|
||||||
fil_delete_tablespace(
|
fil_delete_tablespace(ulint id, bool drop_ahi)
|
||||||
ulint id,
|
|
||||||
buf_remove_t buf_remove)
|
|
||||||
{
|
{
|
||||||
char* path = 0;
|
char* path = 0;
|
||||||
fil_space_t* space = 0;
|
fil_space_t* space = 0;
|
||||||
@ -3012,7 +3007,7 @@ fil_delete_tablespace(
|
|||||||
To deal with potential read requests, we will check the
|
To deal with potential read requests, we will check the
|
||||||
::stop_new_ops flag in fil_io(). */
|
::stop_new_ops flag in fil_io(). */
|
||||||
|
|
||||||
buf_LRU_flush_or_remove_pages(id, buf_remove, 0);
|
buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi);
|
||||||
|
|
||||||
/* If it is a delete then also delete any generated files, otherwise
|
/* If it is a delete then also delete any generated files, otherwise
|
||||||
when we drop the database the remove directory will fail. */
|
when we drop the database the remove directory will fail. */
|
||||||
@ -3103,7 +3098,7 @@ fil_truncate_tablespace(
|
|||||||
|
|
||||||
/* Step-2: Invalidate buffer pool pages belonging to the tablespace
|
/* Step-2: Invalidate buffer pool pages belonging to the tablespace
|
||||||
to re-create. Remove all insert buffer entries for the tablespace */
|
to re-create. Remove all insert buffer entries for the tablespace */
|
||||||
buf_LRU_flush_or_remove_pages(space_id, BUF_REMOVE_ALL_NO_WRITE, 0);
|
buf_LRU_flush_or_remove_pages(space_id, NULL);
|
||||||
|
|
||||||
/* Step-3: Truncate the tablespace and accordingly update
|
/* Step-3: Truncate the tablespace and accordingly update
|
||||||
the fil_space_t handler that is used to access this tablespace. */
|
the fil_space_t handler that is used to access this tablespace. */
|
||||||
@ -3199,7 +3194,7 @@ fil_reinit_space_header_for_table(
|
|||||||
from disabling AHI during the scan */
|
from disabling AHI during the scan */
|
||||||
btr_search_s_lock_all();
|
btr_search_s_lock_all();
|
||||||
DEBUG_SYNC_C("buffer_pool_scan");
|
DEBUG_SYNC_C("buffer_pool_scan");
|
||||||
buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_ALL_NO_WRITE, 0);
|
buf_LRU_flush_or_remove_pages(id, NULL);
|
||||||
btr_search_s_unlock_all();
|
btr_search_s_unlock_all();
|
||||||
|
|
||||||
row_mysql_lock_data_dictionary(trx);
|
row_mysql_lock_data_dictionary(trx);
|
||||||
@ -3292,7 +3287,7 @@ fil_discard_tablespace(
|
|||||||
{
|
{
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
|
|
||||||
switch (err = fil_delete_tablespace(id, BUF_REMOVE_ALL_NO_WRITE)) {
|
switch (err = fil_delete_tablespace(id, true)) {
|
||||||
case DB_SUCCESS:
|
case DB_SUCCESS:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -4962,21 +4962,36 @@ ibuf_check_bitmap_on_import(
|
|||||||
const trx_t* trx, /*!< in: transaction */
|
const trx_t* trx, /*!< in: transaction */
|
||||||
ulint space_id) /*!< in: tablespace identifier */
|
ulint space_id) /*!< in: tablespace identifier */
|
||||||
{
|
{
|
||||||
ulint size;
|
|
||||||
ulint page_no;
|
ulint page_no;
|
||||||
|
|
||||||
ut_ad(space_id);
|
ut_ad(space_id);
|
||||||
ut_ad(trx->mysql_thd);
|
ut_ad(trx->mysql_thd);
|
||||||
|
|
||||||
bool found;
|
FilSpace space(space_id);
|
||||||
const page_size_t& page_size
|
if (!space()) {
|
||||||
= fil_space_get_page_size(space_id, &found);
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
return(DB_TABLE_NOT_FOUND);
|
return(DB_TABLE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
size = fil_space_get_size(space_id);
|
const page_size_t page_size(space->flags);
|
||||||
|
/* fil_space_t::size and fil_space_t::free_limit would still be 0
|
||||||
|
at this point. So, we will have to read page 0. */
|
||||||
|
ut_ad(!space->free_limit);
|
||||||
|
ut_ad(!space->size);
|
||||||
|
|
||||||
|
mtr_t mtr;
|
||||||
|
ulint size;
|
||||||
|
mtr.start();
|
||||||
|
if (buf_block_t* sp = buf_page_get(page_id_t(space_id, 0), page_size,
|
||||||
|
RW_S_LATCH, &mtr)) {
|
||||||
|
size = std::min(
|
||||||
|
mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
|
||||||
|
+ sp->frame),
|
||||||
|
mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
|
||||||
|
+ sp->frame));
|
||||||
|
} else {
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
mtr.commit();
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return(DB_TABLE_NOT_FOUND);
|
return(DB_TABLE_NOT_FOUND);
|
||||||
@ -4991,7 +5006,6 @@ ibuf_check_bitmap_on_import(
|
|||||||
the space, as usual. */
|
the space, as usual. */
|
||||||
|
|
||||||
for (page_no = 0; page_no < size; page_no += page_size.physical()) {
|
for (page_no = 0; page_no < size; page_no += page_size.physical()) {
|
||||||
mtr_t mtr;
|
|
||||||
page_t* bitmap_page;
|
page_t* bitmap_page;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ struct fil_addr_t;
|
|||||||
#define BUF_GET_POSSIBLY_FREED 16
|
#define BUF_GET_POSSIBLY_FREED 16
|
||||||
/*!< Like BUF_GET, but do not mind
|
/*!< Like BUF_GET, but do not mind
|
||||||
if the file page has been freed. */
|
if the file page has been freed. */
|
||||||
|
#define BUF_EVICT_IF_IN_POOL 20 /*!< evict a clean block if found */
|
||||||
/* @} */
|
/* @} */
|
||||||
/** @name Modes for buf_page_get_known_nowait */
|
/** @name Modes for buf_page_get_known_nowait */
|
||||||
/* @{ */
|
/* @{ */
|
||||||
|
@ -50,18 +50,14 @@ These are low-level functions
|
|||||||
/** Minimum LRU list length for which the LRU_old pointer is defined */
|
/** Minimum LRU list length for which the LRU_old pointer is defined */
|
||||||
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
|
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Empty the flush list for all pages belonging to a tablespace.
|
||||||
Flushes all dirty pages or removes all pages belonging
|
@param[in] id tablespace identifier
|
||||||
to a given tablespace. A PROBLEM: if readahead is being started, what
|
@param[in] trx transaction, for checking for user interrupt;
|
||||||
guarantees that it will not try to read in pages after this operation
|
or NULL if nothing is to be written
|
||||||
has completed? */
|
@param[in] drop_ahi whether to drop the adaptive hash index */
|
||||||
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false);
|
||||||
/*==========================*/
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
buf_remove_t buf_remove, /*!< in: remove or flush strategy */
|
|
||||||
const trx_t* trx); /*!< to check if the operation must
|
|
||||||
be interrupted */
|
|
||||||
|
|
||||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
|
@ -59,17 +59,6 @@ enum buf_flush_t {
|
|||||||
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
|
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Algorithm to remove the pages for a tablespace from the buffer pool.
|
|
||||||
See buf_LRU_flush_or_remove_pages(). */
|
|
||||||
enum buf_remove_t {
|
|
||||||
BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer
|
|
||||||
pool, don't write or sync to disk */
|
|
||||||
BUF_REMOVE_FLUSH_NO_WRITE, /*!< Remove only, from the flush list,
|
|
||||||
don't write or sync to disk */
|
|
||||||
BUF_REMOVE_FLUSH_WRITE /*!< Flush dirty pages to disk only
|
|
||||||
don't remove from the buffer pool */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Flags for io_fix types */
|
/** Flags for io_fix types */
|
||||||
enum buf_io_fix {
|
enum buf_io_fix {
|
||||||
BUF_IO_NONE = 0, /**< no pending I/O */
|
BUF_IO_NONE = 0, /**< no pending I/O */
|
||||||
|
@ -929,17 +929,12 @@ bool
|
|||||||
fil_table_accessible(const dict_table_t* table)
|
fil_table_accessible(const dict_table_t* table)
|
||||||
MY_ATTRIBUTE((warn_unused_result, nonnull));
|
MY_ATTRIBUTE((warn_unused_result, nonnull));
|
||||||
|
|
||||||
/** Deletes an IBD tablespace, either general or single-table.
|
/** Delete a tablespace and associated .ibd file.
|
||||||
The tablespace must be cached in the memory cache. This will delete the
|
@param[in] id tablespace identifier
|
||||||
datafile, fil_space_t & fil_node_t entries from the file_system_t cache.
|
@param[in] drop_ahi whether to drop the adaptive hash index
|
||||||
@param[in] space_id Tablespace id
|
@return DB_SUCCESS or error */
|
||||||
@param[in] buf_remove Specify the action to take on the pages
|
|
||||||
for this table in the buffer pool.
|
|
||||||
@return true if success */
|
|
||||||
dberr_t
|
dberr_t
|
||||||
fil_delete_tablespace(
|
fil_delete_tablespace(ulint id, bool drop_ahi = false);
|
||||||
ulint id,
|
|
||||||
buf_remove_t buf_remove);
|
|
||||||
|
|
||||||
/** Truncate the tablespace to needed size.
|
/** Truncate the tablespace to needed size.
|
||||||
@param[in] space_id id of tablespace to truncate
|
@param[in] space_id id of tablespace to truncate
|
||||||
|
@ -1537,18 +1537,16 @@ PageConverter::PageConverter(
|
|||||||
:
|
:
|
||||||
AbstractCallback(trx),
|
AbstractCallback(trx),
|
||||||
m_cfg(cfg),
|
m_cfg(cfg),
|
||||||
|
m_index(cfg->m_indexes),
|
||||||
|
m_current_lsn(log_get_lsn()),
|
||||||
m_page_zip_ptr(0),
|
m_page_zip_ptr(0),
|
||||||
m_heap(0) UNIV_NOTHROW
|
m_rec_iter(),
|
||||||
|
m_offsets_(), m_offsets(m_offsets_),
|
||||||
|
m_heap(0),
|
||||||
|
m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW
|
||||||
{
|
{
|
||||||
m_index = m_cfg->m_indexes;
|
|
||||||
|
|
||||||
m_current_lsn = log_get_lsn();
|
|
||||||
ut_a(m_current_lsn > 0);
|
ut_a(m_current_lsn > 0);
|
||||||
|
|
||||||
m_offsets = m_offsets_;
|
|
||||||
rec_offs_init(m_offsets_);
|
rec_offs_init(m_offsets_);
|
||||||
|
|
||||||
m_cluster_index = dict_table_get_first_index(m_cfg->m_table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adjust the BLOB reference for a single column that is externally stored
|
/** Adjust the BLOB reference for a single column that is externally stored
|
||||||
@ -2008,7 +2006,7 @@ PageConverter::operator() (
|
|||||||
we can work on them */
|
we can work on them */
|
||||||
|
|
||||||
if ((err = update_page(block, page_type)) != DB_SUCCESS) {
|
if ((err = update_page(block, page_type)) != DB_SUCCESS) {
|
||||||
return(err);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: For compressed pages this function will write to the
|
/* Note: For compressed pages this function will write to the
|
||||||
@ -2047,9 +2045,15 @@ PageConverter::operator() (
|
|||||||
<< " at offset " << offset
|
<< " at offset " << offset
|
||||||
<< " looks corrupted in file " << m_filepath;
|
<< " looks corrupted in file " << m_filepath;
|
||||||
|
|
||||||
return(DB_CORRUPTION);
|
err = DB_CORRUPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we already had and old page with matching number
|
||||||
|
in the buffer pool, evict it now, because
|
||||||
|
we no longer evict the pages on DISCARD TABLESPACE. */
|
||||||
|
buf_page_get_gen(block->page.id, get_page_size(),
|
||||||
|
RW_NO_LATCH, NULL, BUF_EVICT_IF_IN_POOL,
|
||||||
|
__FILE__, __LINE__, NULL, NULL);
|
||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3649,8 +3653,7 @@ row_import_for_mysql(
|
|||||||
The only dirty pages generated should be from the pessimistic purge
|
The only dirty pages generated should be from the pessimistic purge
|
||||||
of delete marked records that couldn't be purged in Phase I. */
|
of delete marked records that couldn't be purged in Phase I. */
|
||||||
|
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(prebuilt->table->space, trx);
|
||||||
prebuilt->table->space, BUF_REMOVE_FLUSH_WRITE, trx);
|
|
||||||
|
|
||||||
if (trx_is_interrupted(trx)) {
|
if (trx_is_interrupted(trx)) {
|
||||||
ib::info() << "Phase III - Flush interrupted";
|
ib::info() << "Phase III - Flush interrupted";
|
||||||
|
@ -2503,10 +2503,7 @@ err_exit:
|
|||||||
/* We already have .ibd file here. it should be deleted. */
|
/* We already have .ibd file here. it should be deleted. */
|
||||||
|
|
||||||
if (dict_table_is_file_per_table(table)
|
if (dict_table_is_file_per_table(table)
|
||||||
&& fil_delete_tablespace(
|
&& fil_delete_tablespace(table->space) != DB_SUCCESS) {
|
||||||
table->space,
|
|
||||||
BUF_REMOVE_FLUSH_NO_WRITE)
|
|
||||||
!= DB_SUCCESS) {
|
|
||||||
|
|
||||||
ib::error() << "Not able to delete tablespace "
|
ib::error() << "Not able to delete tablespace "
|
||||||
<< table->space << " of table "
|
<< table->space << " of table "
|
||||||
@ -3173,9 +3170,6 @@ row_discard_tablespace(
|
|||||||
4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
|
4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
|
||||||
we do not allow the discard. */
|
we do not allow the discard. */
|
||||||
|
|
||||||
/* Play safe and remove all insert buffer entries, though we should
|
|
||||||
have removed them already when DISCARD TABLESPACE was called */
|
|
||||||
|
|
||||||
ibuf_delete_for_discarded_space(table->space);
|
ibuf_delete_for_discarded_space(table->space);
|
||||||
|
|
||||||
table_id_t new_id;
|
table_id_t new_id;
|
||||||
@ -3540,8 +3534,7 @@ row_drop_single_table_tablespace(
|
|||||||
|
|
||||||
ib::info() << "Removed datafile " << filepath
|
ib::info() << "Removed datafile " << filepath
|
||||||
<< " for table " << tablename;
|
<< " for table " << tablename;
|
||||||
} else if (fil_delete_tablespace(space_id, BUF_REMOVE_FLUSH_NO_WRITE)
|
} else if (fil_delete_tablespace(space_id) != DB_SUCCESS) {
|
||||||
!= DB_SUCCESS) {
|
|
||||||
|
|
||||||
ib::error() << "We removed the InnoDB internal data"
|
ib::error() << "We removed the InnoDB internal data"
|
||||||
" dictionary entry of table " << tablename
|
" dictionary entry of table " << tablename
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
Copyright (c) 2017, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@ -536,8 +537,7 @@ row_quiesce_table_start(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!trx_is_interrupted(trx)) {
|
if (!trx_is_interrupted(trx)) {
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(table->space, trx);
|
||||||
table->space, BUF_REMOVE_FLUSH_WRITE, trx);
|
|
||||||
|
|
||||||
if (trx_is_interrupted(trx)) {
|
if (trx_is_interrupted(trx)) {
|
||||||
|
|
||||||
|
@ -1100,21 +1100,22 @@ srv_undo_tablespaces_init(bool create_new_db)
|
|||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
/* Step-2: Flush the dirty pages from the buffer pool. */
|
/* Step-2: Flush the dirty pages from the buffer pool. */
|
||||||
|
trx_t* trx = trx_allocate_for_background();
|
||||||
|
|
||||||
for (undo::undo_spaces_t::const_iterator it
|
for (undo::undo_spaces_t::const_iterator it
|
||||||
= undo::Truncate::s_fix_up_spaces.begin();
|
= undo::Truncate::s_fix_up_spaces.begin();
|
||||||
it != undo::Truncate::s_fix_up_spaces.end();
|
it != undo::Truncate::s_fix_up_spaces.end();
|
||||||
++it) {
|
++it) {
|
||||||
|
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(TRX_SYS_SPACE, trx);
|
||||||
TRX_SYS_SPACE, BUF_REMOVE_FLUSH_WRITE, NULL);
|
|
||||||
|
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(*it, trx);
|
||||||
*it, BUF_REMOVE_FLUSH_WRITE, NULL);
|
|
||||||
|
|
||||||
/* Remove the truncate redo log file. */
|
/* Remove the truncate redo log file. */
|
||||||
undo::Truncate undo_trunc;
|
undo::Truncate undo_trunc;
|
||||||
undo_trunc.done_logging(*it);
|
undo_trunc.done_logging(*it);
|
||||||
}
|
}
|
||||||
|
trx_free_for_background(trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
|
@ -730,6 +730,8 @@ buf_page_is_corrupted(
|
|||||||
ulint zip_size,
|
ulint zip_size,
|
||||||
const fil_space_t* space)
|
const fil_space_t* space)
|
||||||
{
|
{
|
||||||
|
DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", return(TRUE); );
|
||||||
|
|
||||||
ulint checksum_field1;
|
ulint checksum_field1;
|
||||||
ulint checksum_field2;
|
ulint checksum_field2;
|
||||||
ulint space_id = mach_read_from_4(
|
ulint space_id = mach_read_from_4(
|
||||||
@ -838,8 +840,6 @@ buf_page_is_corrupted(
|
|||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(true); );
|
|
||||||
|
|
||||||
ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET);
|
ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET);
|
||||||
|
|
||||||
const srv_checksum_algorithm_t curr_algo =
|
const srv_checksum_algorithm_t curr_algo =
|
||||||
@ -2956,8 +2956,8 @@ buf_page_get_gen(
|
|||||||
ib_mutex_t* fix_mutex = NULL;
|
ib_mutex_t* fix_mutex = NULL;
|
||||||
buf_pool_t* buf_pool = buf_pool_get(space, offset);
|
buf_pool_t* buf_pool = buf_pool_get(space, offset);
|
||||||
|
|
||||||
ut_ad(mtr);
|
ut_ad((mtr == NULL) == (mode == BUF_EVICT_IF_IN_POOL));
|
||||||
ut_ad(mtr->state == MTR_ACTIVE);
|
ut_ad(!mtr || mtr->state == MTR_ACTIVE);
|
||||||
ut_ad((rw_latch == RW_S_LATCH)
|
ut_ad((rw_latch == RW_S_LATCH)
|
||||||
|| (rw_latch == RW_X_LATCH)
|
|| (rw_latch == RW_X_LATCH)
|
||||||
|| (rw_latch == RW_NO_LATCH));
|
|| (rw_latch == RW_NO_LATCH));
|
||||||
@ -2968,23 +2968,29 @@ buf_page_get_gen(
|
|||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
case BUF_EVICT_IF_IN_POOL:
|
||||||
|
/* After DISCARD TABLESPACE, the tablespace would not exist,
|
||||||
|
but in IMPORT TABLESPACE, PageConverter::operator() must
|
||||||
|
replace any old pages, which were not evicted during DISCARD.
|
||||||
|
Skip the assertion on zip_size. */
|
||||||
|
break;
|
||||||
case BUF_GET_NO_LATCH:
|
case BUF_GET_NO_LATCH:
|
||||||
ut_ad(rw_latch == RW_NO_LATCH);
|
ut_ad(rw_latch == RW_NO_LATCH);
|
||||||
break;
|
/* fall through */
|
||||||
case BUF_GET:
|
case BUF_GET:
|
||||||
case BUF_GET_IF_IN_POOL:
|
case BUF_GET_IF_IN_POOL:
|
||||||
case BUF_PEEK_IF_IN_POOL:
|
case BUF_PEEK_IF_IN_POOL:
|
||||||
case BUF_GET_IF_IN_POOL_OR_WATCH:
|
case BUF_GET_IF_IN_POOL_OR_WATCH:
|
||||||
case BUF_GET_POSSIBLY_FREED:
|
case BUF_GET_POSSIBLY_FREED:
|
||||||
|
ut_ad(zip_size == fil_space_get_zip_size(space));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ut_error;
|
ut_error;
|
||||||
}
|
}
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
ut_ad(zip_size == fil_space_get_zip_size(space));
|
|
||||||
ut_ad(ut_is_2pow(zip_size));
|
ut_ad(ut_is_2pow(zip_size));
|
||||||
#ifndef UNIV_LOG_DEBUG
|
#ifndef UNIV_LOG_DEBUG
|
||||||
ut_ad(!ibuf_inside(mtr)
|
ut_ad(!mtr || !ibuf_inside(mtr)
|
||||||
|| ibuf_page_low(space, zip_size, offset,
|
|| ibuf_page_low(space, zip_size, offset,
|
||||||
FALSE, file, line, NULL));
|
FALSE, file, line, NULL));
|
||||||
#endif
|
#endif
|
||||||
@ -3054,9 +3060,11 @@ loop:
|
|||||||
rw_lock_x_unlock(hash_lock);
|
rw_lock_x_unlock(hash_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == BUF_GET_IF_IN_POOL
|
switch (mode) {
|
||||||
|| mode == BUF_PEEK_IF_IN_POOL
|
case BUF_GET_IF_IN_POOL:
|
||||||
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
|
case BUF_GET_IF_IN_POOL_OR_WATCH:
|
||||||
|
case BUF_PEEK_IF_IN_POOL:
|
||||||
|
case BUF_EVICT_IF_IN_POOL:
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX));
|
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX));
|
||||||
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
|
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
|
||||||
@ -3145,8 +3153,10 @@ got_block:
|
|||||||
|
|
||||||
ut_ad(page_zip_get_size(&block->page.zip) == zip_size);
|
ut_ad(page_zip_get_size(&block->page.zip) == zip_size);
|
||||||
|
|
||||||
if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL) {
|
switch (mode) {
|
||||||
|
case BUF_GET_IF_IN_POOL:
|
||||||
|
case BUF_PEEK_IF_IN_POOL:
|
||||||
|
case BUF_EVICT_IF_IN_POOL:
|
||||||
bool must_read;
|
bool must_read;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -3184,6 +3194,22 @@ got_block:
|
|||||||
|
|
||||||
case BUF_BLOCK_FILE_PAGE:
|
case BUF_BLOCK_FILE_PAGE:
|
||||||
ut_ad(fix_mutex != &buf_pool->zip_mutex);
|
ut_ad(fix_mutex != &buf_pool->zip_mutex);
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
|
||||||
|
evict_from_pool:
|
||||||
|
ut_ad(!fix_block->page.oldest_modification);
|
||||||
|
mutex_enter(&buf_pool->LRU_list_mutex);
|
||||||
|
buf_block_unfix(fix_block);
|
||||||
|
mutex_enter(fix_mutex);
|
||||||
|
|
||||||
|
if (!buf_LRU_free_page(&fix_block->page, true)) {
|
||||||
|
ut_ad(0);
|
||||||
|
mutex_exit(&buf_pool->LRU_list_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_exit(fix_mutex);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUF_BLOCK_ZIP_PAGE:
|
case BUF_BLOCK_ZIP_PAGE:
|
||||||
@ -3218,6 +3244,10 @@ got_block:
|
|||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
|
||||||
|
goto evict_from_pool;
|
||||||
|
}
|
||||||
|
|
||||||
/* Buffer-fix the block so that it cannot be evicted
|
/* Buffer-fix the block so that it cannot be evicted
|
||||||
or relocated while we are attempting to allocate an
|
or relocated while we are attempting to allocate an
|
||||||
uncompressed page. */
|
uncompressed page. */
|
||||||
@ -4798,7 +4828,7 @@ database_corrupted:
|
|||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
/* Not a real corruption if it was triggered by
|
/* Not a real corruption if it was triggered by
|
||||||
error injection */
|
error injection */
|
||||||
DBUG_EXECUTE_IF("buf_page_is_corrupt_failure",
|
DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
|
||||||
if (bpage->space > TRX_SYS_SPACE) {
|
if (bpage->space > TRX_SYS_SPACE) {
|
||||||
buf_mark_space_corrupt(bpage);
|
buf_mark_space_corrupt(bpage);
|
||||||
ib_logf(IB_LOG_LEVEL_INFO,
|
ib_logf(IB_LOG_LEVEL_INFO,
|
||||||
@ -4866,7 +4896,7 @@ database_corrupted:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("buf_page_is_corrupt_failure",
|
DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
|
||||||
page_not_corrupt: bpage = bpage; );
|
page_not_corrupt: bpage = bpage; );
|
||||||
|
|
||||||
if (recv_recovery_is_on()) {
|
if (recv_recovery_is_on()) {
|
||||||
|
@ -571,26 +571,20 @@ buf_flush_or_remove_page(
|
|||||||
return(processed);
|
return(processed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Remove all dirty pages belonging to a given tablespace inside a specific
|
||||||
Remove all dirty pages belonging to a given tablespace inside a specific
|
|
||||||
buffer pool instance when we are deleting the data file(s) of that
|
buffer pool instance when we are deleting the data file(s) of that
|
||||||
tablespace. The pages still remain a part of LRU and are evicted from
|
tablespace. The pages still remain a part of LRU and are evicted from
|
||||||
the list as they age towards the tail of the LRU.
|
the list as they age towards the tail of the LRU.
|
||||||
|
@param[in,out] buf_pool buffer pool
|
||||||
|
@param[in] id tablespace identifier
|
||||||
|
@param[in] trx transaction (to check for interrupt),
|
||||||
|
or NULL if the files should not be written to
|
||||||
@retval DB_SUCCESS if all freed
|
@retval DB_SUCCESS if all freed
|
||||||
@retval DB_FAIL if not all freed
|
@retval DB_FAIL if not all freed
|
||||||
@retval DB_INTERRUPTED if the transaction was interrupted */
|
@retval DB_INTERRUPTED if the transaction was interrupted */
|
||||||
static MY_ATTRIBUTE((nonnull(1), warn_unused_result))
|
static MY_ATTRIBUTE((nonnull(1), warn_unused_result))
|
||||||
dberr_t
|
dberr_t
|
||||||
buf_flush_or_remove_pages(
|
buf_flush_or_remove_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx)
|
||||||
/*======================*/
|
|
||||||
buf_pool_t* buf_pool, /*!< buffer pool instance */
|
|
||||||
ulint id, /*!< in: target space id for which
|
|
||||||
to remove or flush pages */
|
|
||||||
bool flush, /*!< in: flush to disk if true but
|
|
||||||
don't remove else remove without
|
|
||||||
flushing to disk */
|
|
||||||
const trx_t* trx) /*!< to check if the operation must
|
|
||||||
be interrupted, can be 0 */
|
|
||||||
{
|
{
|
||||||
buf_page_t* prev;
|
buf_page_t* prev;
|
||||||
buf_page_t* bpage;
|
buf_page_t* bpage;
|
||||||
@ -621,7 +615,7 @@ rescan:
|
|||||||
/* Skip this block, as it does not belong to
|
/* Skip this block, as it does not belong to
|
||||||
the target space. */
|
the target space. */
|
||||||
|
|
||||||
} else if (!buf_flush_or_remove_page(buf_pool, bpage, flush,
|
} else if (!buf_flush_or_remove_page(buf_pool, bpage, trx,
|
||||||
&must_restart)) {
|
&must_restart)) {
|
||||||
|
|
||||||
/* Remove was unsuccessful, we have to try again
|
/* Remove was unsuccessful, we have to try again
|
||||||
@ -647,7 +641,7 @@ rescan:
|
|||||||
/* Cannot trust the prev pointer */
|
/* Cannot trust the prev pointer */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (flush) {
|
} else if (trx) {
|
||||||
|
|
||||||
/* The processing was successful. And during the
|
/* The processing was successful. And during the
|
||||||
processing we have released all the buf_pool mutexes
|
processing we have released all the buf_pool mutexes
|
||||||
@ -674,19 +668,17 @@ rescan:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DBUG_OFF
|
if (trx) {
|
||||||
if (flush) {
|
|
||||||
DBUG_EXECUTE_IF("ib_export_flush_crash",
|
DBUG_EXECUTE_IF("ib_export_flush_crash",
|
||||||
static ulint n_pages;
|
static ulint n_pages;
|
||||||
if (++n_pages == 4) {DBUG_SUICIDE();});
|
if (++n_pages == 4) {DBUG_SUICIDE();});
|
||||||
}
|
|
||||||
#endif /* DBUG_OFF */
|
|
||||||
|
|
||||||
/* The check for trx is interrupted is expensive, we want
|
/* The check for trx is interrupted is
|
||||||
to check every N iterations. */
|
expensive, we want to check every N iterations. */
|
||||||
if (!processed && trx && trx_is_interrupted(trx)) {
|
if (!processed && trx_is_interrupted(trx)) {
|
||||||
buf_flush_list_mutex_exit(buf_pool);
|
buf_flush_list_mutex_exit(buf_pool);
|
||||||
return(DB_INTERRUPTED);
|
return(DB_INTERRUPTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,28 +687,25 @@ rescan:
|
|||||||
return(all_freed ? DB_SUCCESS : DB_FAIL);
|
return(all_freed ? DB_SUCCESS : DB_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Remove or flush all the dirty pages that belong to a given tablespace
|
||||||
Remove or flush all the dirty pages that belong to a given tablespace
|
|
||||||
inside a specific buffer pool instance. The pages will remain in the LRU
|
inside a specific buffer pool instance. The pages will remain in the LRU
|
||||||
list and will be evicted from the LRU list as they age and move towards
|
list and will be evicted from the LRU list as they age and move towards
|
||||||
the tail of the LRU list. */
|
the tail of the LRU list.
|
||||||
|
@param[in,out] buf_pool buffer pool
|
||||||
|
@param[in] id tablespace identifier
|
||||||
|
@param[in] trx transaction (to check for interrupt),
|
||||||
|
or NULL if the files should not be written to
|
||||||
|
*/
|
||||||
static MY_ATTRIBUTE((nonnull(1)))
|
static MY_ATTRIBUTE((nonnull(1)))
|
||||||
void
|
void
|
||||||
buf_flush_dirty_pages(
|
buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx)
|
||||||
/*==================*/
|
|
||||||
buf_pool_t* buf_pool, /*!< buffer pool instance */
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
bool flush, /*!< in: flush to disk if true otherwise
|
|
||||||
remove the pages without flushing */
|
|
||||||
const trx_t* trx) /*!< to check if the operation must
|
|
||||||
be interrupted */
|
|
||||||
{
|
{
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
mutex_enter(&buf_pool->LRU_list_mutex);
|
mutex_enter(&buf_pool->LRU_list_mutex);
|
||||||
|
|
||||||
err = buf_flush_or_remove_pages(buf_pool, id, flush, trx);
|
err = buf_flush_or_remove_pages(buf_pool, id, trx);
|
||||||
|
|
||||||
mutex_exit(&buf_pool->LRU_list_mutex);
|
mutex_exit(&buf_pool->LRU_list_mutex);
|
||||||
|
|
||||||
@ -737,239 +726,27 @@ buf_flush_dirty_pages(
|
|||||||
|| buf_pool_get_dirty_pages_count(buf_pool, id) == 0);
|
|| buf_pool_get_dirty_pages_count(buf_pool, id) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Empty the flush list for all pages belonging to a tablespace.
|
||||||
Remove all pages that belong to a given tablespace inside a specific
|
@param[in] id tablespace identifier
|
||||||
buffer pool instance when we are DISCARDing the tablespace. */
|
@param[in] trx transaction, for checking for user interrupt;
|
||||||
static MY_ATTRIBUTE((nonnull))
|
or NULL if nothing is to be written
|
||||||
|
@param[in] drop_ahi whether to drop the adaptive hash index */
|
||||||
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
buf_LRU_remove_all_pages(
|
buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi)
|
||||||
/*=====================*/
|
|
||||||
buf_pool_t* buf_pool, /*!< buffer pool instance */
|
|
||||||
ulint id) /*!< in: space id */
|
|
||||||
{
|
{
|
||||||
buf_page_t* bpage;
|
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
|
||||||
ibool all_freed;
|
buf_pool_t* buf_pool = buf_pool_from_array(i);
|
||||||
|
if (drop_ahi) {
|
||||||
scan_again:
|
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
|
||||||
mutex_enter(&buf_pool->LRU_list_mutex);
|
|
||||||
|
|
||||||
all_freed = TRUE;
|
|
||||||
|
|
||||||
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
|
||||||
bpage != NULL;
|
|
||||||
/* No op */) {
|
|
||||||
|
|
||||||
prio_rw_lock_t* hash_lock;
|
|
||||||
buf_page_t* prev_bpage;
|
|
||||||
ib_mutex_t* block_mutex = NULL;
|
|
||||||
|
|
||||||
ut_a(buf_page_in_file(bpage));
|
|
||||||
ut_ad(bpage->in_LRU_list);
|
|
||||||
|
|
||||||
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
|
||||||
|
|
||||||
/* It is safe to check bpage->space and bpage->io_fix while
|
|
||||||
holding buf_pool->LRU_list_mutex only and later recheck
|
|
||||||
while holding the buf_page_get_mutex() mutex. */
|
|
||||||
|
|
||||||
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 (UNIV_UNLIKELY(buf_page_get_io_fix_unlocked(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 {
|
|
||||||
ulint fold = buf_page_address_fold(
|
|
||||||
bpage->space, bpage->offset);
|
|
||||||
|
|
||||||
hash_lock = buf_page_hash_lock_get(buf_pool, fold);
|
|
||||||
|
|
||||||
rw_lock_x_lock(hash_lock);
|
|
||||||
|
|
||||||
block_mutex = buf_page_get_mutex(bpage);
|
|
||||||
mutex_enter(block_mutex);
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(
|
|
||||||
buf_page_get_space(bpage) != id
|
|
||||||
|| bpage->buf_fix_count > 0
|
|
||||||
|| (buf_page_get_io_fix(bpage)
|
|
||||||
!= BUF_IO_NONE))) {
|
|
||||||
|
|
||||||
mutex_exit(block_mutex);
|
|
||||||
|
|
||||||
rw_lock_x_unlock(hash_lock);
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
buf_flush_dirty_pages(buf_pool, id, trx);
|
||||||
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) {
|
|
||||||
/* Do nothing, because the adaptive hash index
|
|
||||||
covers uncompressed pages only. */
|
|
||||||
} else if (((buf_block_t*) bpage)->index) {
|
|
||||||
ulint page_no;
|
|
||||||
ulint zip_size;
|
|
||||||
|
|
||||||
mutex_exit(&buf_pool->LRU_list_mutex);
|
|
||||||
|
|
||||||
zip_size = buf_page_get_zip_size(bpage);
|
|
||||||
page_no = buf_page_get_page_no(bpage);
|
|
||||||
|
|
||||||
mutex_exit(block_mutex);
|
|
||||||
|
|
||||||
rw_lock_x_unlock(hash_lock);
|
|
||||||
|
|
||||||
/* Note that the following call will acquire
|
|
||||||
and release block->lock X-latch. */
|
|
||||||
|
|
||||||
btr_search_drop_page_hash_when_freed(
|
|
||||||
id, zip_size, page_no);
|
|
||||||
|
|
||||||
goto scan_again;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bpage->oldest_modification != 0) {
|
|
||||||
|
|
||||||
buf_flush_remove(bpage);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(!bpage->in_flush_list);
|
|
||||||
|
|
||||||
/* Remove from the LRU list. */
|
|
||||||
|
|
||||||
if (buf_LRU_block_remove_hashed(bpage, true)) {
|
|
||||||
|
|
||||||
mutex_enter(block_mutex);
|
|
||||||
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
|
|
||||||
mutex_exit(block_mutex);
|
|
||||||
} else {
|
|
||||||
ut_ad(block_mutex == &buf_pool->zip_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(!mutex_own(block_mutex));
|
|
||||||
|
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
|
||||||
/* buf_LRU_block_remove_hashed() releases the hash_lock */
|
|
||||||
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX));
|
|
||||||
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
|
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
|
||||||
|
|
||||||
next_page:
|
|
||||||
bpage = prev_bpage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&buf_pool->LRU_list_mutex);
|
if (trx && !trx_is_interrupted(trx)) {
|
||||||
|
|
||||||
if (!all_freed) {
|
|
||||||
os_thread_sleep(20000);
|
|
||||||
|
|
||||||
goto scan_again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************//**
|
|
||||||
Remove pages belonging to a given tablespace inside a specific
|
|
||||||
buffer pool instance when we are deleting the data file(s) of that
|
|
||||||
tablespace. The pages still remain a part of LRU and are evicted from
|
|
||||||
the list as they age towards the tail of the LRU only if buf_remove
|
|
||||||
is BUF_REMOVE_FLUSH_NO_WRITE. */
|
|
||||||
static MY_ATTRIBUTE((nonnull(1)))
|
|
||||||
void
|
|
||||||
buf_LRU_remove_pages(
|
|
||||||
/*=================*/
|
|
||||||
buf_pool_t* buf_pool, /*!< buffer pool instance */
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
buf_remove_t buf_remove, /*!< in: remove or flush strategy */
|
|
||||||
const trx_t* trx) /*!< to check if the operation must
|
|
||||||
be interrupted */
|
|
||||||
{
|
|
||||||
switch (buf_remove) {
|
|
||||||
case BUF_REMOVE_ALL_NO_WRITE:
|
|
||||||
buf_LRU_remove_all_pages(buf_pool, id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BUF_REMOVE_FLUSH_NO_WRITE:
|
|
||||||
ut_a(trx == 0);
|
|
||||||
buf_flush_dirty_pages(buf_pool, id, false, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BUF_REMOVE_FLUSH_WRITE:
|
|
||||||
ut_a(trx != 0);
|
|
||||||
buf_flush_dirty_pages(buf_pool, id, true, trx);
|
|
||||||
/* Ensure that all asynchronous IO is completed. */
|
/* Ensure that all asynchronous IO is completed. */
|
||||||
os_aio_wait_until_no_pending_writes();
|
os_aio_wait_until_no_pending_writes();
|
||||||
fil_flush(id);
|
fil_flush(id);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************//**
|
|
||||||
Flushes all dirty pages or removes all pages belonging
|
|
||||||
to a given tablespace. A PROBLEM: if readahead is being started, what
|
|
||||||
guarantees that it will not try to read in pages after this operation
|
|
||||||
has completed? */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
buf_LRU_flush_or_remove_pages(
|
|
||||||
/*==========================*/
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
buf_remove_t buf_remove, /*!< in: remove or flush strategy */
|
|
||||||
const trx_t* trx) /*!< to check if the operation must
|
|
||||||
be interrupted */
|
|
||||||
{
|
|
||||||
ulint i;
|
|
||||||
|
|
||||||
/* Before we attempt to drop pages one by one we first
|
|
||||||
attempt to drop page hash index entries in batches to make
|
|
||||||
it more efficient. The batching attempt is a best effort
|
|
||||||
attempt and does not guarantee that all pages hash entries
|
|
||||||
will be dropped. We get rid of remaining page hash entries
|
|
||||||
one by one below. */
|
|
||||||
for (i = 0; i < srv_buf_pool_instances; i++) {
|
|
||||||
buf_pool_t* buf_pool;
|
|
||||||
|
|
||||||
buf_pool = buf_pool_from_array(i);
|
|
||||||
|
|
||||||
switch (buf_remove) {
|
|
||||||
case BUF_REMOVE_ALL_NO_WRITE:
|
|
||||||
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BUF_REMOVE_FLUSH_NO_WRITE:
|
|
||||||
/* It is a DROP TABLE for a single table
|
|
||||||
tablespace. No AHI entries exist because
|
|
||||||
we already dealt with them when freeing up
|
|
||||||
extents. */
|
|
||||||
case BUF_REMOVE_FLUSH_WRITE:
|
|
||||||
/* We allow read-only queries against the
|
|
||||||
table, there is no need to drop the AHI entries. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf_LRU_remove_pages(buf_pool, id, buf_remove, trx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1679,7 +1679,7 @@ dict_table_rename_in_cache(
|
|||||||
filepath = fil_make_ibd_name(table->name, false);
|
filepath = fil_make_ibd_name(table->name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE);
|
fil_delete_tablespace(table->space, true);
|
||||||
|
|
||||||
/* Delete any temp file hanging around. */
|
/* Delete any temp file hanging around. */
|
||||||
if (os_file_status(filepath, &exists, &ftype)
|
if (os_file_status(filepath, &exists, &ftype)
|
||||||
|
@ -2572,8 +2572,7 @@ fil_op_log_parse_or_replay(
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case MLOG_FILE_DELETE:
|
case MLOG_FILE_DELETE:
|
||||||
if (fil_tablespace_exists_in_mem(space_id)) {
|
if (fil_tablespace_exists_in_mem(space_id)) {
|
||||||
dberr_t err = fil_delete_tablespace(
|
dberr_t err = fil_delete_tablespace(space_id);
|
||||||
space_id, BUF_REMOVE_FLUSH_NO_WRITE);
|
|
||||||
ut_a(err == DB_SUCCESS);
|
ut_a(err == DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2851,7 +2850,7 @@ fil_close_tablespace(
|
|||||||
completely and permanently. The flag stop_new_ops also prevents
|
completely and permanently. The flag stop_new_ops also prevents
|
||||||
fil_flush() from being applied to this tablespace. */
|
fil_flush() from being applied to this tablespace. */
|
||||||
|
|
||||||
buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_FLUSH_WRITE, trx);
|
buf_LRU_flush_or_remove_pages(id, trx);
|
||||||
#endif
|
#endif
|
||||||
mutex_enter(&fil_system->mutex);
|
mutex_enter(&fil_system->mutex);
|
||||||
|
|
||||||
@ -2878,18 +2877,13 @@ fil_close_tablespace(
|
|||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************//**
|
/** Delete a tablespace and associated .ibd file.
|
||||||
Deletes a single-table tablespace. The tablespace must be cached in the
|
@param[in] id tablespace identifier
|
||||||
memory cache.
|
@param[in] drop_ahi whether to drop the adaptive hash index
|
||||||
@return DB_SUCCESS or error */
|
@return DB_SUCCESS or error */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
dberr_t
|
||||||
fil_delete_tablespace(
|
fil_delete_tablespace(ulint id, bool drop_ahi)
|
||||||
/*==================*/
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
buf_remove_t buf_remove) /*!< in: specify the action to take
|
|
||||||
on the tables pages in the buffer
|
|
||||||
pool */
|
|
||||||
{
|
{
|
||||||
char* path = 0;
|
char* path = 0;
|
||||||
fil_space_t* space = 0;
|
fil_space_t* space = 0;
|
||||||
@ -2945,7 +2939,7 @@ fil_delete_tablespace(
|
|||||||
To deal with potential read requests by checking the
|
To deal with potential read requests by checking the
|
||||||
::stop_new_ops flag in fil_io() */
|
::stop_new_ops flag in fil_io() */
|
||||||
|
|
||||||
buf_LRU_flush_or_remove_pages(id, buf_remove, 0);
|
buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi);
|
||||||
|
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
@ -3056,7 +3050,7 @@ fil_discard_tablespace(
|
|||||||
{
|
{
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
|
|
||||||
switch (err = fil_delete_tablespace(id, BUF_REMOVE_ALL_NO_WRITE)) {
|
switch (err = fil_delete_tablespace(id, true)) {
|
||||||
case DB_SUCCESS:
|
case DB_SUCCESS:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -5178,7 +5178,20 @@ ibuf_check_bitmap_on_import(
|
|||||||
return(DB_TABLE_NOT_FOUND);
|
return(DB_TABLE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
size = fil_space_get_size(space_id);
|
mtr_t mtr;
|
||||||
|
mtr_start(&mtr);
|
||||||
|
{
|
||||||
|
buf_block_t* sp = buf_page_get(space_id, zip_size, 0,
|
||||||
|
RW_S_LATCH, &mtr);
|
||||||
|
if (sp) {
|
||||||
|
size = mach_read_from_4(
|
||||||
|
FSP_HEADER_OFFSET + FSP_FREE_LIMIT
|
||||||
|
+ sp->frame);
|
||||||
|
} else {
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return(DB_TABLE_NOT_FOUND);
|
return(DB_TABLE_NOT_FOUND);
|
||||||
@ -5189,7 +5202,6 @@ ibuf_check_bitmap_on_import(
|
|||||||
page_size = zip_size ? zip_size : UNIV_PAGE_SIZE;
|
page_size = zip_size ? zip_size : UNIV_PAGE_SIZE;
|
||||||
|
|
||||||
for (page_no = 0; page_no < size; page_no += page_size) {
|
for (page_no = 0; page_no < size; page_no += page_size) {
|
||||||
mtr_t mtr;
|
|
||||||
page_t* bitmap_page;
|
page_t* bitmap_page;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ Created 11/5/1995 Heikki Tuuri
|
|||||||
#define BUF_GET_POSSIBLY_FREED 16
|
#define BUF_GET_POSSIBLY_FREED 16
|
||||||
/*!< Like BUF_GET, but do not mind
|
/*!< Like BUF_GET, but do not mind
|
||||||
if the file page has been freed. */
|
if the file page has been freed. */
|
||||||
|
#define BUF_EVICT_IF_IN_POOL 20 /*!< evict a clean block if found */
|
||||||
/* @} */
|
/* @} */
|
||||||
/** @name Modes for buf_page_get_known_nowait */
|
/** @name Modes for buf_page_get_known_nowait */
|
||||||
/* @{ */
|
/* @{ */
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
Copyright (c) 2017, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@ -53,19 +54,14 @@ These are low-level functions
|
|||||||
/** Minimum LRU list length for which the LRU_old pointer is defined */
|
/** Minimum LRU list length for which the LRU_old pointer is defined */
|
||||||
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
|
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Empty the flush list for all pages belonging to a tablespace.
|
||||||
Flushes all dirty pages or removes all pages belonging
|
@param[in] id tablespace identifier
|
||||||
to a given tablespace. A PROBLEM: if readahead is being started, what
|
@param[in] trx transaction, for checking for user interrupt;
|
||||||
guarantees that it will not try to read in pages after this operation
|
or NULL if nothing is to be written
|
||||||
has completed? */
|
@param[in] drop_ahi whether to drop the adaptive hash index */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false);
|
||||||
/*==========================*/
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
buf_remove_t buf_remove, /*!< in: remove or flush strategy */
|
|
||||||
const trx_t* trx); /*!< to check if the operation must
|
|
||||||
be interrupted */
|
|
||||||
|
|
||||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
|
@ -58,17 +58,6 @@ enum buf_flush_t {
|
|||||||
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
|
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Algorithm to remove the pages for a tablespace from the buffer pool.
|
|
||||||
See buf_LRU_flush_or_remove_pages(). */
|
|
||||||
enum buf_remove_t {
|
|
||||||
BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer
|
|
||||||
pool, don't write or sync to disk */
|
|
||||||
BUF_REMOVE_FLUSH_NO_WRITE, /*!< Remove only, from the flush list,
|
|
||||||
don't write or sync to disk */
|
|
||||||
BUF_REMOVE_FLUSH_WRITE /*!< Flush dirty pages to disk only
|
|
||||||
don't remove from the buffer pool */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Flags for io_fix types */
|
/** Flags for io_fix types */
|
||||||
enum buf_io_fix {
|
enum buf_io_fix {
|
||||||
BUF_IO_NONE = 0, /**< no pending I/O */
|
BUF_IO_NONE = 0, /**< no pending I/O */
|
||||||
|
@ -849,18 +849,13 @@ fil_op_log_parse_or_replay(
|
|||||||
only be parsed but not replayed */
|
only be parsed but not replayed */
|
||||||
ulint log_flags); /*!< in: redo log flags
|
ulint log_flags); /*!< in: redo log flags
|
||||||
(stored in the page number parameter) */
|
(stored in the page number parameter) */
|
||||||
/*******************************************************************//**
|
/** Delete a tablespace and associated .ibd file.
|
||||||
Deletes a single-table tablespace. The tablespace must be cached in the
|
@param[in] id tablespace identifier
|
||||||
memory cache.
|
@param[in] drop_ahi whether to drop the adaptive hash index
|
||||||
@return TRUE if success */
|
@return DB_SUCCESS or error */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
dberr_t
|
dberr_t
|
||||||
fil_delete_tablespace(
|
fil_delete_tablespace(ulint id, bool drop_ahi = false);
|
||||||
/*==================*/
|
|
||||||
ulint id, /*!< in: space id */
|
|
||||||
buf_remove_t buf_remove); /*!< in: specify the action to take
|
|
||||||
on the tables pages in the buffer
|
|
||||||
pool */
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
Closes a single-table tablespace. The tablespace must be cached in the
|
Closes a single-table tablespace. The tablespace must be cached in the
|
||||||
memory cache. Free all pages used by the tablespace.
|
memory cache. Free all pages used by the tablespace.
|
||||||
|
@ -2570,8 +2570,8 @@ os_file_get_size(
|
|||||||
|
|
||||||
return(offset);
|
return(offset);
|
||||||
#else
|
#else
|
||||||
return((os_offset_t) lseek(file, 0, SEEK_END));
|
struct stat statbuf;
|
||||||
|
return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size;
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2625,19 +2625,29 @@ os_file_set_size(
|
|||||||
if (srv_use_posix_fallocate) {
|
if (srv_use_posix_fallocate) {
|
||||||
int err;
|
int err;
|
||||||
do {
|
do {
|
||||||
err = posix_fallocate(file, 0, size);
|
os_offset_t current_size = os_file_get_size(file);
|
||||||
|
err = current_size >= size
|
||||||
|
? 0 : posix_fallocate(file, current_size,
|
||||||
|
size - current_size);
|
||||||
} while (err == EINTR
|
} while (err == EINTR
|
||||||
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
|
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
|
||||||
|
|
||||||
if (err) {
|
switch (err) {
|
||||||
|
case 0:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||||
"preallocating " INT64PF " bytes for"
|
"preallocating " INT64PF " bytes for"
|
||||||
"file %s failed with error %d",
|
"file %s failed with error %d",
|
||||||
size, name, err);
|
size, name, err);
|
||||||
|
/* fall through */
|
||||||
|
case EINTR:
|
||||||
|
errno = err;
|
||||||
|
return false;
|
||||||
|
case EINVAL:
|
||||||
|
/* fall back to the code below */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
/* Set errno because posix_fallocate() does not do it.*/
|
|
||||||
errno = err;
|
|
||||||
return(!err);
|
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@ -2679,11 +2689,12 @@ os_file_set_size(
|
|||||||
}
|
}
|
||||||
|
|
||||||
current_size += n_bytes;
|
current_size += n_bytes;
|
||||||
} while (current_size < size);
|
} while (current_size < size
|
||||||
|
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
|
||||||
|
|
||||||
free(buf2);
|
free(buf2);
|
||||||
|
|
||||||
return(ret && os_file_flush(file));
|
return(ret && current_size >= size && os_file_flush(file));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,18 +1602,16 @@ PageConverter::PageConverter(
|
|||||||
:
|
:
|
||||||
AbstractCallback(trx),
|
AbstractCallback(trx),
|
||||||
m_cfg(cfg),
|
m_cfg(cfg),
|
||||||
|
m_index(cfg->m_indexes),
|
||||||
|
m_current_lsn(log_get_lsn()),
|
||||||
m_page_zip_ptr(0),
|
m_page_zip_ptr(0),
|
||||||
m_heap(0) UNIV_NOTHROW
|
m_rec_iter(),
|
||||||
|
m_offsets_(), m_offsets(m_offsets_),
|
||||||
|
m_heap(0),
|
||||||
|
m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW
|
||||||
{
|
{
|
||||||
m_index = m_cfg->m_indexes;
|
|
||||||
|
|
||||||
m_current_lsn = log_get_lsn();
|
|
||||||
ut_a(m_current_lsn > 0);
|
ut_a(m_current_lsn > 0);
|
||||||
|
|
||||||
m_offsets = m_offsets_;
|
|
||||||
rec_offs_init(m_offsets_);
|
rec_offs_init(m_offsets_);
|
||||||
|
|
||||||
m_cluster_index = dict_table_get_first_index(m_cfg->m_table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2104,7 +2102,7 @@ PageConverter::operator() (
|
|||||||
we can work on them */
|
we can work on them */
|
||||||
|
|
||||||
if ((err = update_page(block, page_type)) != DB_SUCCESS) {
|
if ((err = update_page(block, page_type)) != DB_SUCCESS) {
|
||||||
return(err);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: For compressed pages this function will write to the
|
/* Note: For compressed pages this function will write to the
|
||||||
@ -2141,9 +2139,15 @@ PageConverter::operator() (
|
|||||||
"%s: Page %lu at offset " UINT64PF " looks corrupted.",
|
"%s: Page %lu at offset " UINT64PF " looks corrupted.",
|
||||||
m_filepath, (ulong) (offset / m_page_size), offset);
|
m_filepath, (ulong) (offset / m_page_size), offset);
|
||||||
|
|
||||||
return(DB_CORRUPTION);
|
err = DB_CORRUPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we already had and old page with matching number
|
||||||
|
in the buffer pool, evict it now, because
|
||||||
|
we no longer evict the pages on DISCARD TABLESPACE. */
|
||||||
|
buf_page_get_gen(get_space_id(), get_zip_size(), block->page.offset,
|
||||||
|
RW_NO_LATCH, NULL, BUF_EVICT_IF_IN_POOL,
|
||||||
|
__FILE__, __LINE__, NULL);
|
||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3717,8 +3721,7 @@ row_import_for_mysql(
|
|||||||
The only dirty pages generated should be from the pessimistic purge
|
The only dirty pages generated should be from the pessimistic purge
|
||||||
of delete marked records that couldn't be purged in Phase I. */
|
of delete marked records that couldn't be purged in Phase I. */
|
||||||
|
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(prebuilt->table->space, trx);
|
||||||
prebuilt->table->space, BUF_REMOVE_FLUSH_WRITE, trx);
|
|
||||||
|
|
||||||
if (trx_is_interrupted(trx)) {
|
if (trx_is_interrupted(trx)) {
|
||||||
ib_logf(IB_LOG_LEVEL_INFO, "Phase III - Flush interrupted");
|
ib_logf(IB_LOG_LEVEL_INFO, "Phase III - Flush interrupted");
|
||||||
|
@ -2494,10 +2494,7 @@ err_exit:
|
|||||||
/* We already have .ibd file here. it should be deleted. */
|
/* We already have .ibd file here. it should be deleted. */
|
||||||
|
|
||||||
if (table->space
|
if (table->space
|
||||||
&& fil_delete_tablespace(
|
&& fil_delete_tablespace(table->space) != DB_SUCCESS) {
|
||||||
table->space,
|
|
||||||
BUF_REMOVE_FLUSH_NO_WRITE)
|
|
||||||
!= DB_SUCCESS) {
|
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -3132,9 +3129,6 @@ row_discard_tablespace(
|
|||||||
4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
|
4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
|
||||||
we do not allow the discard. */
|
we do not allow the discard. */
|
||||||
|
|
||||||
/* Play safe and remove all insert buffer entries, though we should
|
|
||||||
have removed them already when DISCARD TABLESPACE was called */
|
|
||||||
|
|
||||||
ibuf_delete_for_discarded_space(table->space);
|
ibuf_delete_for_discarded_space(table->space);
|
||||||
|
|
||||||
table_id_t new_id;
|
table_id_t new_id;
|
||||||
@ -4516,9 +4510,7 @@ row_drop_table_for_mysql(
|
|||||||
|
|
||||||
fil_delete_file(filepath);
|
fil_delete_file(filepath);
|
||||||
|
|
||||||
} else if (fil_delete_tablespace(
|
} else if (fil_delete_tablespace(space_id)
|
||||||
space_id,
|
|
||||||
BUF_REMOVE_FLUSH_NO_WRITE)
|
|
||||||
!= DB_SUCCESS) {
|
!= DB_SUCCESS) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: We removed now the InnoDB"
|
"InnoDB: We removed now the InnoDB"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
Copyright (c) 2017, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@ -542,8 +543,7 @@ row_quiesce_table_start(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!trx_is_interrupted(trx)) {
|
if (!trx_is_interrupted(trx)) {
|
||||||
buf_LRU_flush_or_remove_pages(
|
buf_LRU_flush_or_remove_pages(table->space, trx);
|
||||||
table->space, BUF_REMOVE_FLUSH_WRITE, trx);
|
|
||||||
|
|
||||||
if (trx_is_interrupted(trx)) {
|
if (trx_is_interrupted(trx)) {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user