Merge 5.2 -> 5.3

(testcase for #798597 now crashes)
This commit is contained in:
Sergey Petrunya 2011-06-24 21:43:31 +04:00
commit 7880039fc0
32 changed files with 834 additions and 441 deletions

View File

@ -318,10 +318,12 @@ ENDIF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
# Special handling for tmp tables with the Aria engine # Special handling for tmp tables with the Aria engine
IF(WITH_ARIA_STORAGE_ENGINE) IF(WITH_ARIA_STORAGE_ENGINE)
ADD_DEFINITIONS(-DWITH_ARIA_STORAGE_ENGINE) ADD_DEFINITIONS(-DWITH_ARIA_STORAGE_ENGINE)
IF(WITH_MARIA_TMP_TABLES) SET(WITH_ARIA_TMP_TABLES 1 CACHE BOOL "Use Aria for temporary tables")
IF(WITH_ARIA_TMP_TABLES)
MESSAGE(STATUS "Using Aria for temporary tables")
ADD_DEFINITIONS(-DUSE_MARIA_FOR_TMP_TABLES) ADD_DEFINITIONS(-DUSE_MARIA_FOR_TMP_TABLES)
ENDIF(WITH_MARIA_TMP_TABLES) ENDIF()
ENDIF(WITH_ARIA_STORAGE_ENGINE) ENDIF()
ADD_DEFINITIONS(${STORAGE_ENGINE_DEFS}) ADD_DEFINITIONS(${STORAGE_ENGINE_DEFS})

View File

@ -60,6 +60,7 @@ enum options_client
OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG, OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG,
OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME,
OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT, OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT,
OPT_FLUSH_TABLES,
#ifdef HAVE_NDBCLUSTER_DB #ifdef HAVE_NDBCLUSTER_DB
OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING,
#endif #endif

View File

@ -16,7 +16,7 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */
#define CHECK_VERSION "2.6.0" #define CHECK_VERSION "2.7.0"
#include "client_priv.h" #include "client_priv.h"
#include <m_ctype.h> #include <m_ctype.h>
@ -35,8 +35,8 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0, opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0, tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0,
opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0;
opt_write_binlog= 1; static my_bool opt_write_binlog= 1, opt_flush_tables= 0;
static uint verbose = 0, opt_mysql_port=0; static uint verbose = 0, opt_mysql_port=0;
static int my_end_arg; static int my_end_arg;
static char * opt_mysql_unix_port = 0; static char * opt_mysql_unix_port = 0;
@ -121,6 +121,9 @@ static struct my_option my_long_options[] =
"If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.", "If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.",
&opt_extended, &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0, &opt_extended, &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0}, 0, 0, 0},
{"flush", OPT_FLUSH_TABLES, "Flush each table after check. This is useful if you don't want to have the checked tables take up space in the caches after the check",
&opt_flush_tables, &opt_flush_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0 },
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0}, NO_ARG, 0, 0, 0, 0, 0, 0},
{"host",'h', "Connect to host.", &current_host, {"host",'h', "Connect to host.", &current_host,
@ -685,6 +688,7 @@ static int disable_binlog()
static int handle_request_for_tables(char *tables, uint length) static int handle_request_for_tables(char *tables, uint length)
{ {
char *query, *end, options[100], message[100]; char *query, *end, options[100], message[100];
char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name;
uint query_length= 0; uint query_length= 0;
const char *op = 0; const char *op = 0;
@ -723,13 +727,17 @@ static int handle_request_for_tables(char *tables, uint length)
/* No backticks here as we added them before */ /* No backticks here as we added them before */
query_length= my_sprintf(query, query_length= my_sprintf(query,
(query, "%s TABLE %s %s", op, tables, options)); (query, "%s TABLE %s %s", op, tables, options));
table_name= tables;
} }
else else
{ {
char *ptr; char *ptr, *org;
ptr= strmov(strmov(query, op), " TABLE "); org= ptr= strmov(strmov(query, op), " TABLE ");
ptr= fix_table_name(ptr, tables); ptr= fix_table_name(ptr, tables);
strmake(table_name_buff, org, min((int) sizeof(table_name_buff)-1,
(int) (ptr - org)));
table_name= table_name_buff;
ptr= strxmov(ptr, " ", options, NullS); ptr= strxmov(ptr, " ", options, NullS);
query_length= (uint) (ptr - query); query_length= (uint) (ptr - query);
} }
@ -737,9 +745,21 @@ static int handle_request_for_tables(char *tables, uint length)
{ {
sprintf(message, "when executing '%s TABLE ... %s'", op, options); sprintf(message, "when executing '%s TABLE ... %s'", op, options);
DBerror(sock, message); DBerror(sock, message);
my_free(query, MYF(0));
return 1; return 1;
} }
print_result(); print_result();
if (opt_flush_tables)
{
query_length= my_sprintf(query,
(query, "FLUSH TABLES %s", table_name));
if (mysql_real_query(sock, query, query_length))
{
DBerror(sock, query);
my_free(query, MYF(0));
return 1;
}
}
my_free(query, MYF(0)); my_free(query, MYF(0));
return 0; return 0;
} }

View File

@ -2355,9 +2355,11 @@ sub remove_stale_vardir () {
mtr_report(" - WARNING: Using the 'mysql-test/var' symlink"); mtr_report(" - WARNING: Using the 'mysql-test/var' symlink");
# Make sure the directory where it points exist # Make sure the directory where it points exist
mtr_error("The destination for symlink $opt_vardir does not exist") if (! -d readlink($opt_vardir))
if ! -d readlink($opt_vardir); {
mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
unlink($opt_vardir);
}
foreach my $bin ( glob("$opt_vardir/*") ) foreach my $bin ( glob("$opt_vardir/*") )
{ {
mtr_verbose("Removing bin $bin"); mtr_verbose("Removing bin $bin");
@ -2424,8 +2426,11 @@ sub setup_vardir() {
# it's a symlink # it's a symlink
# Make sure the directory where it points exist # Make sure the directory where it points exist
mtr_error("The destination for symlink $opt_vardir does not exist") if (! -d readlink($opt_vardir))
if ! -d readlink($opt_vardir); {
mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
unlink($opt_vardir);
}
} }
elsif ( $opt_mem ) elsif ( $opt_mem )
{ {
@ -4957,14 +4962,13 @@ sub mysqld_arguments ($$$) {
if ( $opt_valgrind_mysqld ) if ( $opt_valgrind_mysqld )
{ {
mtr_add_arg($args, "--skip-safemalloc");
if ( $mysql_version_id < 50100 ) if ( $mysql_version_id < 50100 )
{ {
mtr_add_arg($args, "--skip-bdb"); mtr_add_arg($args, "--skip-bdb");
} }
} }
mtr_add_arg($args, "--loose-skip-safemalloc");
mtr_add_arg($args, "%s--disable-sync-frm"); mtr_add_arg($args, "%s--disable-sync-frm");
# Retry bind as this may fail on busy server # Retry bind as this may fail on busy server
mtr_add_arg($args, "%s--port-open-timeout=10"); mtr_add_arg($args, "%s--port-open-timeout=10");

View File

@ -1,4 +1,5 @@
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
drop view if exists v1,v2;
CREATE TABLE t1 (S1 INT); CREATE TABLE t1 (S1 INT);
CREATE TABLE t2 (S1 INT); CREATE TABLE t2 (S1 INT);
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
@ -1221,6 +1222,24 @@ f1
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
DROP TABLE t1; DROP TABLE t1;
# #
# Bug LP:798597: Incorrect "Duplicate entry" error with views and
# GROUP BY
#
CREATE TABLE t1 ( f1 int NOT NULL , f2 int NOT NULL ) ;
INSERT INTO t1 VALUES (214,0),(6,6);
CREATE TABLE t2 ( f2 int) ;
INSERT INTO t2 VALUES (88),(88);
CREATE ALGORITHM=MERGE VIEW v1 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0) ;
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0 or t1.f2 is null) ;
SELECT f1 , MIN(f2) FROM v1 GROUP BY f1;
f1 MIN(f2)
214 88
SELECT f1 , MIN(f2) FROM v2 GROUP BY f1;
f1 MIN(f2)
214 88
drop table t1,t2;
drop view v1,v2;
#
# BUG#47217 Lost optimization caused slowdown & wrong result. # BUG#47217 Lost optimization caused slowdown & wrong result.
# #
CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk)); CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));

View File

@ -657,15 +657,16 @@ CREATE TABLE t1 (a INT) PARTITION BY HASH (a);
FLUSH TABLES; FLUSH TABLES;
CHECK TABLE t1; CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check Error File './test/t1.par' not found (Errcode: 2)
test.t1 check Error Failed to read from the .par file test.t1 check Error Failed to read from the .par file
test.t1 check Error Incorrect information in file: './test/t1.frm' test.t1 check Error Incorrect information in file: './test/t1.frm'
test.t1 check error Corrupt test.t1 check error Corrupt
SELECT * FROM t1; SELECT * FROM t1;
ERROR HY000: Failed to read from the .par file ERROR HY000: File './test/t1.par' not found (Errcode: 2)
# Note that it is currently impossible to drop a partitioned table # Note that it is currently impossible to drop a partitioned table
# without the .par file # without the .par file
DROP TABLE t1; DROP TABLE t1;
ERROR 42S02: Unknown table 't1' ERROR HY000: File './test/t1.par' not found (Errcode: 2)
# #
# Bug#49477: Assertion `0' failed in ha_partition.cc:5530 # Bug#49477: Assertion `0' failed in ha_partition.cc:5530
# with temporary table and partitions # with temporary table and partitions

View File

@ -0,0 +1,11 @@
install plugin example soname 'ha_example.so';
create table t1(a int) engine=example;
drop table t1;
alter table mysql.plugin engine=innodb;
restart
create table t1(a int) engine=example;
select * from t1;
a
drop table t1;
alter table mysql.plugin engine=myisam;
uninstall plugin example;

View File

@ -29,28 +29,29 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`COMMAND` varchar(16) NOT NULL DEFAULT '', `COMMAND` varchar(16) NOT NULL DEFAULT '',
`TIME` int(7) NOT NULL DEFAULT '0', `TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL, `STATE` varchar(64) DEFAULT NULL,
`INFO` longtext `INFO` longtext,
`TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8 ) DEFAULT CHARSET=utf8
SHOW processlist; SHOW processlist;
Id User Host db Command Time State Info Id User Host db Command Time State Info
ID root HOST_NAME information_schema Query TIME NULL SHOW processlist ID root HOST_NAME information_schema Query TIME NULL SHOW processlist
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
SELECT * FROM processlist ORDER BY id; SELECT * FROM processlist ORDER BY id;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID root HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id ID root HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM processlist ORDER BY id; SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID root HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM processlist ORDER BY id ID root HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist; CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ; UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist; INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist; DROP TABLE test.t_processlist;
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) AS SELECT * FROM processlist WITH CHECK OPTION; CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist' ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) AS SELECT * FROM processlist; CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1; UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
DROP VIEW test.v_processlist; DROP VIEW test.v_processlist;
@ -99,25 +100,26 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`COMMAND` varchar(16) NOT NULL DEFAULT '', `COMMAND` varchar(16) NOT NULL DEFAULT '',
`TIME` int(7) NOT NULL DEFAULT '0', `TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL, `STATE` varchar(64) DEFAULT NULL,
`INFO` longtext `INFO` longtext,
`TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8 ) DEFAULT CHARSET=utf8
SHOW processlist; SHOW processlist;
Id User Host db Command Time State Info Id User Host db Command Time State Info
ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM processlist ORDER BY id; SELECT * FROM processlist ORDER BY id;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id TIME_MS
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM processlist ORDER BY id; SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM processlist ORDER BY id ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id TIME_MS
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist; CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ; UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist; INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema' ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist; DROP TABLE test.t_processlist;
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) AS SELECT * FROM processlist WITH CHECK OPTION; CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist' ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) AS SELECT * FROM processlist; CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1; UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema' ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
DROP VIEW test.v_processlist; DROP VIEW test.v_processlist;
@ -170,8 +172,8 @@ SHOW processlist;
Id User Host db Command Time State Info Id User Host db Command Time State Info
ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
#################################################################################### ####################################################################################
4.2 New connection con101 (ddicttestuser1 with PROCESS privilege) 4.2 New connection con101 (ddicttestuser1 with PROCESS privilege)
SHOW/SELECT shows all processes/threads. SHOW/SELECT shows all processes/threads.
@ -185,10 +187,10 @@ ID root HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID root HOST_NAME information_schema Sleep TIME NULL ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
5 Grant PROCESS privilege to anonymous user. 5 Grant PROCESS privilege to anonymous user.
connection default (user=root) connection default (user=root)
@ -209,11 +211,11 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID HOST_NAME information_schema Query TIME NULL SHOW processlist ID HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID root HOST_NAME information_schema Sleep TIME NULL ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
6 Revoke PROCESS privilege from ddicttestuser1 6 Revoke PROCESS privilege from ddicttestuser1
connection default (user=root) connection default (user=root)
@ -233,10 +235,10 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
7 Revoke PROCESS privilege from anonymous user 7 Revoke PROCESS privilege from anonymous user
connection default (user=root) connection default (user=root)
@ -251,9 +253,9 @@ SHOW GRANTS FOR ''@'localhost';
Grants for @localhost Grants for @localhost
GRANT USAGE ON *.* TO ''@'localhost' GRANT USAGE ON *.* TO ''@'localhost'
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
8 Grant SUPER (does not imply PROCESS) privilege to ddicttestuser1 8 Grant SUPER (does not imply PROCESS) privilege to ddicttestuser1
connection default (user=root) connection default (user=root)
@ -273,11 +275,11 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
9 Revoke SUPER privilege from user ddicttestuser1 9 Revoke SUPER privilege from user ddicttestuser1
connection default (user=root) connection default (user=root)
@ -299,12 +301,12 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
10 Grant SUPER privilege with grant option to user ddicttestuser1. 10 Grant SUPER privilege with grant option to user ddicttestuser1.
connection default (user=root) connection default (user=root)
@ -353,18 +355,18 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID root HOST_NAME information_schema Sleep TIME NULL ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
11 User ddicttestuser1 revokes PROCESS privilege from user ddicttestuser2 11 User ddicttestuser1 revokes PROCESS privilege from user ddicttestuser2
connection ddicttestuser1; connection ddicttestuser1;
@ -382,9 +384,9 @@ Id User Host db Command Time State Info
ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
11.2 Revoke SUPER,PROCESS,GRANT OPTION privilege from user ddicttestuser1 11.2 Revoke SUPER,PROCESS,GRANT OPTION privilege from user ddicttestuser1
connection default (user=root) connection default (user=root)
@ -411,15 +413,15 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
12 Revoke the SELECT privilege from user ddicttestuser1 12 Revoke the SELECT privilege from user ddicttestuser1
connection default (user=root) connection default (user=root)
@ -447,16 +449,16 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
SELECT * FROM information_schema.processlist; SELECT * FROM information_schema.processlist;
ID USER HOST DB COMMAND TIME STATE INFO ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
#################################################################################### ####################################################################################
12.2 Revoke only the SELECT privilege on the information_schema from ddicttestuser1. 12.2 Revoke only the SELECT privilege on the information_schema from ddicttestuser1.
connection default (user=root) connection default (user=root)

File diff suppressed because one or more lines are too long

View File

@ -78,7 +78,7 @@ ERROR HY000: Lost connection to MySQL server during query
* recovery happens * recovery happens
check table t1 extended; check table t1 extended;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
mysqltest.t1 check warning Size of indexfile is: 372 Should be: 8192 mysqltest.t1 check warning Size of indexfile is: 372 Expected: 8192
mysqltest.t1 check status OK mysqltest.t1 check status OK
* testing that checksum after recovery is as expected * testing that checksum after recovery is as expected
Checksum-check Checksum-check

View File

@ -2131,7 +2131,7 @@ c3 VARCHAR(10) NOT NULL,
KEY (c1), KEY (c1),
KEY (c2) KEY (c2)
) ENGINE=aria DEFAULT CHARSET=utf8 PACK_KEYS=0; ) ENGINE=aria DEFAULT CHARSET=utf8 PACK_KEYS=0;
Aria file: MYSQLD_DATADIR/test/t1 Aria file: MYSQLD_DATADIR/test/t1
Record format: Block Record format: Block
Crashsafe: yes Crashsafe: yes
Character set: utf8_general_ci (33) Character set: utf8_general_ci (33)

View File

@ -2,6 +2,7 @@
# Initialization # Initialization
--disable_warnings --disable_warnings
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
drop view if exists v1,v2;
--enable_warnings --enable_warnings
# #
@ -921,6 +922,23 @@ EXECUTE stmt;
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug LP:798597: Incorrect "Duplicate entry" error with views and
--echo # GROUP BY
--echo #
CREATE TABLE t1 ( f1 int NOT NULL , f2 int NOT NULL ) ;
INSERT INTO t1 VALUES (214,0),(6,6);
CREATE TABLE t2 ( f2 int) ;
INSERT INTO t2 VALUES (88),(88);
CREATE ALGORITHM=MERGE VIEW v1 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0) ;
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0 or t1.f2 is null) ;
SELECT f1 , MIN(f2) FROM v1 GROUP BY f1;
SELECT f1 , MIN(f2) FROM v2 GROUP BY f1;
drop table t1,t2;
drop view v1,v2;
--echo # --echo #
--echo # BUG#47217 Lost optimization caused slowdown & wrong result. --echo # BUG#47217 Lost optimization caused slowdown & wrong result.
--echo # --echo #

View File

@ -696,11 +696,13 @@ FLUSH TABLES;
--remove_file $MYSQLD_DATADIR/test/t1.par --remove_file $MYSQLD_DATADIR/test/t1.par
--replace_result $MYSQLD_DATADIR ./ --replace_result $MYSQLD_DATADIR ./
CHECK TABLE t1; CHECK TABLE t1;
--error ER_UNKNOWN_ERROR --replace_result $MYSQLD_DATADIR ./
--error 29
SELECT * FROM t1; SELECT * FROM t1;
--echo # Note that it is currently impossible to drop a partitioned table --echo # Note that it is currently impossible to drop a partitioned table
--echo # without the .par file --echo # without the .par file
--error ER_BAD_TABLE_ERROR --replace_result $MYSQLD_DATADIR ./
--error 29
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.frm --remove_file $MYSQLD_DATADIR/test/t1.frm
--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI --remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI

View File

@ -0,0 +1,27 @@
--source include/not_embedded.inc
--source include/have_example_plugin.inc
--source include/have_innodb.inc
if (!`select count(*) from information_schema.plugins
where plugin_name = 'innodb' and plugin_status = 'active' and
plugin_library is null`) {
skip Need compiled-in InnoDB;
}
--replace_regex /\.dll/.so/
eval install plugin example soname '$HA_EXAMPLE_SO';
create table t1(a int) engine=example;
drop table t1;
alter table mysql.plugin engine=innodb;
--echo restart
--source include/restart_mysqld.inc
create table t1(a int) engine=example;
select * from t1;
drop table t1;
alter table mysql.plugin engine=myisam;
uninstall plugin example;

View File

@ -2448,7 +2448,7 @@ bool ha_partition::read_par_file(const char *name)
fn_format(buff, name, "", ha_par_ext, MY_APPEND_EXT); fn_format(buff, name, "", ha_par_ext, MY_APPEND_EXT);
/* Following could be done with my_stat to read in whole file */ /* Following could be done with my_stat to read in whole file */
if ((file= my_open(buff, O_RDONLY | O_SHARE, MYF(0))) < 0) if ((file= my_open(buff, O_RDONLY | O_SHARE, MYF(MY_WME))) < 0)
DBUG_RETURN(true); DBUG_RETURN(true);
if (my_read(file, (uchar *) & buff[0], PAR_WORD_SIZE, MYF(MY_NABP))) if (my_read(file, (uchar *) & buff[0], PAR_WORD_SIZE, MYF(MY_NABP)))
goto err1; goto err1;

View File

@ -508,6 +508,9 @@ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
#else #else
; ;
#endif #endif
#ifdef SAFEMALLOC
my_bool sf_malloc_trough_check= 0;
#endif
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr; static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
static char *opt_init_slave, *language_ptr, *opt_init_connect; static char *opt_init_slave, *language_ptr, *opt_init_connect;
static char *default_character_set_name; static char *default_character_set_name;
@ -3118,7 +3121,8 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
{ {
/* At least, prevent new abuse ... */ /* At least, prevent new abuse ... */
DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0 || DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0 ||
strncmp(str, "Aria table", 11) == 0); strncmp(str, "Aria table", 11) == 0 ||
(MyFlags & ME_JUST_INFO));
error= ER_UNKNOWN_ERROR; error= ER_UNKNOWN_ERROR;
} }
@ -6019,7 +6023,7 @@ enum options_mysqld
OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP, OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE, OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
OPT_NDB_USE_COPYING_ALTER_TABLE, OPT_NDB_USE_COPYING_ALTER_TABLE,
OPT_SKIP_SAFEMALLOC, OPT_MUTEX_DEADLOCK_DETECTOR, OPT_SAFEMALLOC, OPT_MUTEX_DEADLOCK_DETECTOR,
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
OPT_SKIP_SYMLINKS, OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
@ -6992,12 +6996,11 @@ each time the SQL thread starts.",
{"skip-networking", OPT_SKIP_NETWORKING, {"skip-networking", OPT_SKIP_NETWORKING,
"Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
0, 0, 0}, 0, 0, 0},
#ifndef DBUG_OFF
#ifdef SAFEMALLOC #ifdef SAFEMALLOC
{"skip-safemalloc", OPT_SKIP_SAFEMALLOC, {"safemalloc", OPT_SAFEMALLOC,
"Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG, "Check all memory allocation for every malloc/free call.",
0, 0, 0, 0, 0, 0}, &sf_malloc_trough_check, &sf_malloc_trough_check, 0,
#endif GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
#endif #endif
{"skip-show-database", OPT_SKIP_SHOW_DB, {"skip-show-database", OPT_SKIP_SHOW_DB,
"Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, "Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
@ -9394,11 +9397,6 @@ mysqld_get_one_option(int optid,
} }
strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1); strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
break; break;
case OPT_SKIP_SAFEMALLOC:
#ifdef SAFEMALLOC
sf_malloc_quick=1;
#endif
break;
case OPT_LOWER_CASE_TABLE_NAMES: case OPT_LOWER_CASE_TABLE_NAMES:
lower_case_table_names= argument ? atoi(argument) : 1; lower_case_table_names= argument ? atoi(argument) : 1;
lower_case_table_names_used= 1; lower_case_table_names_used= 1;
@ -9593,6 +9591,9 @@ static int get_options(int *argc,char **argv)
&global_system_variables.datetime_format)) &global_system_variables.datetime_format))
return 1; return 1;
#ifdef SAFEMALLOC
sf_malloc_quick= !sf_malloc_trough_check;
#endif
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
one_thread_scheduler(&thread_scheduler); one_thread_scheduler(&thread_scheduler);
one_thread_scheduler(&extra_thread_scheduler); one_thread_scheduler(&extra_thread_scheduler);

View File

@ -1482,7 +1482,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{ {
char *end= buff + length; char *end= buff + length;
length+= my_snprintf(end, buff_len - length - 1, length+= my_snprintf(end, buff_len - length - 1,
end," Memory in use: %ldK Max memory used: %ldK", " Memory in use: %ldK Max memory used: %ldK",
(sf_malloc_cur_memory+1023L)/1024L, (sf_malloc_cur_memory+1023L)/1024L,
(sf_malloc_max_memory+1023L)/1024L); (sf_malloc_max_memory+1023L)/1024L);
} }

View File

@ -1432,15 +1432,23 @@ int plugin_init(int *argc, char **argv, int flags)
if (register_builtin(plugin, &tmp, &plugin_ptr)) if (register_builtin(plugin, &tmp, &plugin_ptr))
goto err_unlock; goto err_unlock;
/* only initialize MyISAM and CSV at this stage */ is_myisam= !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM");
if (!(is_myisam=
!my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM")) &&
my_strcasecmp(&my_charset_latin1, plugin->name, "CSV"))
continue;
if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED && /*
plugin_initialize(plugin_ptr)) strictly speaking, we should to initialize all plugins,
goto err_unlock; even for mysqld --help, because important subsystems
may be disabled otherwise, and the help will be incomplete.
For example, if the mysql.plugin table is not MyISAM.
But for now it's an unlikely corner case, and to optimize
mysqld --help for all other users, we will only initialize
MyISAM here.
*/
if (!(flags & PLUGIN_INIT_SKIP_INITIALIZATION) || is_myisam)
{
if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED &&
plugin_initialize(plugin_ptr))
goto err_unlock;
}
/* /*
initialize the global default storage engine so that it may initialize the global default storage engine so that it may
@ -1653,13 +1661,6 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
goto end; goto end;
} }
table->use_all_columns(); table->use_all_columns();
/*
there're no other threads running yet, so we don't need a mutex.
but plugin_add() before is designed to work in multi-threaded
environment, and it uses safe_mutex_assert_owner(), so we lock
the mutex here to satisfy the assert
*/
pthread_mutex_lock(&LOCK_plugin);
while (!(error= read_record_info.read_record(&read_record_info))) while (!(error= read_record_info.read_record(&read_record_info)))
{ {
DBUG_PRINT("info", ("init plugin record")); DBUG_PRINT("info", ("init plugin record"));
@ -1670,12 +1671,19 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
LEX_STRING name= {(char *)str_name.ptr(), str_name.length()}; LEX_STRING name= {(char *)str_name.ptr(), str_name.length()};
LEX_STRING dl= {(char *)str_dl.ptr(), str_dl.length()}; LEX_STRING dl= {(char *)str_dl.ptr(), str_dl.length()};
/*
there're no other threads running yet, so we don't need a mutex.
but plugin_add() before is designed to work in multi-threaded
environment, and it uses safe_mutex_assert_owner(), so we lock
the mutex here to satisfy the assert
*/
pthread_mutex_lock(&LOCK_plugin);
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG)) if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.", sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.",
str_name.c_ptr(), str_dl.c_ptr()); str_name.c_ptr(), str_dl.c_ptr());
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
pthread_mutex_unlock(&LOCK_plugin);
} }
pthread_mutex_unlock(&LOCK_plugin);
if (error > 0) if (error > 0)
sql_print_error(ER(ER_GET_ERRNO), my_errno); sql_print_error(ER(ER_GET_ERRNO), my_errno);
end_read_record(&read_record_info); end_read_record(&read_record_info);

View File

@ -13546,15 +13546,30 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 || (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ? (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
0 : FIELDFLAG_BINARY; 0 : FIELDFLAG_BINARY;
if (!using_unique_constraint) if (!using_unique_constraint)
{ {
cur_group->buff=(char*) group_buff; cur_group->buff=(char*) group_buff;
if (maybe_null && !field->null_bit)
{
/*
This can only happen in the unusual case where an outer join
table was found to be not-nullable by the optimizer and we
the item can't really be null.
We solve this by marking the item as !maybe_null to ensure
that the key,field and item definition match.
*/
(*cur_group->item)->maybe_null= maybe_null= 0;
}
if (!(cur_group->field= field->new_key_field(thd->mem_root,table, if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
group_buff + group_buff +
test(maybe_null), test(maybe_null),
field->null_ptr, field->null_ptr,
field->null_bit))) field->null_bit)))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
if (maybe_null) if (maybe_null)
{ {
/* /*
@ -13576,6 +13591,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
} }
keyinfo->key_length+= key_part_info->length; keyinfo->key_length+= key_part_info->length;
} }
/*
Ensure we didn't overrun the group buffer. The < is only true when
some maybe_null fields was changed to be not null fields.
*/
DBUG_ASSERT(using_unique_constraint ||
group_buff <= param->group_buff + param->group_length);
} }
if (distinct && field_count != param->hidden_field_count) if (distinct && field_count != param->hidden_field_count)

View File

@ -93,12 +93,16 @@ int main(int argc, char *argv[])
printf("\tFRM length %u\n", reader_handle.frm_length); printf("\tFRM length %u\n", reader_handle.frm_length);
if (reader_handle.comment_start_pos) if (reader_handle.comment_start_pos)
{ {
char *comment = char *comment = (char *) my_malloc(reader_handle.comment_length,
(char *) malloc(sizeof(char) * reader_handle.comment_length); MYF(MY_WME));
azread_comment(&reader_handle, comment); if (comment)
printf("\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length, {
reader_handle.comment_length, comment); azread_comment(&reader_handle, comment);
free(comment); printf("\tComment length %u\n\t\t%.*s\n",
reader_handle.comment_length,
reader_handle.comment_length, comment);
my_free(comment,MYF(0));
}
} }
} }
else else
@ -180,7 +184,7 @@ int main(int argc, char *argv[])
azio_stream writer_handle; azio_stream writer_handle;
buffer= (char *)malloc(reader_handle.longest_row); buffer= (char *) my_malloc(reader_handle.longest_row, MYF(0));
if (buffer == NULL) if (buffer == NULL)
{ {
printf("Could not allocate memory for row %llu\n", row_count); printf("Could not allocate memory for row %llu\n", row_count);
@ -251,7 +255,7 @@ int main(int argc, char *argv[])
break; break;
} }
free(buffer); my_free(buffer, MYF(0));
azclose(&writer_handle); azclose(&writer_handle);
} }

View File

@ -835,7 +835,7 @@ int ha_archive::write_row(uchar *buf)
if (!share->archive_write_open) if (!share->archive_write_open)
if (init_archive_writer()) if (init_archive_writer())
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); DBUG_RETURN(errno);
if (table->next_number_field && record == table->record[0]) if (table->next_number_field && record == table->record[0])
@ -1020,7 +1020,8 @@ int ha_archive::rnd_init(bool scan)
if (share->crashed) if (share->crashed)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
init_archive_reader(); if (init_archive_reader())
DBUG_RETURN(errno);
/* We rewind the file so that we can read from the beginning if scan */ /* We rewind the file so that we can read from the beginning if scan */
if (scan) if (scan)
@ -1317,7 +1318,8 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
char* frm_string; char* frm_string;
DBUG_ENTER("ha_archive::optimize"); DBUG_ENTER("ha_archive::optimize");
init_archive_reader(); if (init_archive_reader())
DBUG_RETURN(errno);
// now we close both our writer and our reader for the rename // now we close both our writer and our reader for the rename
if (share->archive_write_open) if (share->archive_write_open)
@ -1326,7 +1328,7 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
share->archive_write_open= FALSE; share->archive_write_open= FALSE;
} }
if (!(frm_string= (char*) malloc(archive.frm_length))) if (!(frm_string= (char*) my_malloc(archive.frm_length, MYF(0))))
return ENOMEM; return ENOMEM;
azread_frm(&archive, frm_string); azread_frm(&archive, frm_string);
@ -1337,12 +1339,12 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY))) if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY)))
{ {
free(frm_string); my_free(frm_string, MYF(0));
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
} }
rc= azwrite_frm(&writer, frm_string, archive.frm_length); rc= azwrite_frm(&writer, frm_string, archive.frm_length);
free(frm_string); my_free(frm_string, MYF(0));
if (rc) if (rc)
{ {
rc= HA_ERR_CRASHED_ON_USAGE; rc= HA_ERR_CRASHED_ON_USAGE;
@ -1547,7 +1549,9 @@ int ha_archive::info(uint flag)
if (flag & HA_STATUS_AUTO) if (flag & HA_STATUS_AUTO)
{ {
init_archive_reader(); if (init_archive_reader())
DBUG_RETURN(errno);
pthread_mutex_lock(&share->mutex); pthread_mutex_lock(&share->mutex);
azflush(&archive, Z_SYNC_FLUSH); azflush(&archive, Z_SYNC_FLUSH);
pthread_mutex_unlock(&share->mutex); pthread_mutex_unlock(&share->mutex);
@ -1626,7 +1630,9 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
Now we will rewind the archive file so that we are positioned at the Now we will rewind the archive file so that we are positioned at the
start of the file. start of the file.
*/ */
init_archive_reader(); if (init_archive_reader())
DBUG_RETURN(errno);
read_data_header(&archive); read_data_header(&archive);
while (!(rc= get_row(&archive, table->record[0]))) while (!(rc= get_row(&archive, table->record[0])))
count--; count--;

View File

@ -310,6 +310,31 @@ my_bool _ma_bitmap_end(MARIA_SHARE *share)
return res; return res;
} }
/*
Ensure that we have incremented open count before we try to read/write
a page while we have the bitmap lock.
This is needed to ensure that we don't call _ma_mark_file_changed() as
part of flushing a page to disk, as this locks share->internal_lock
and then mutex lock would happen in the wrong order.
*/
static inline void _ma_bitmap_mark_file_changed(MARIA_SHARE *share)
{
/*
It's extremely unlikely that the following test is true as it
only happens once if the table has changed.
*/
if (unlikely(!share->global_changed &&
(share->state.changed & STATE_CHANGED)))
{
/* purecov: begin inspected */
/* unlock mutex as it can't be hold during _ma_mark_file_changed() */
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
_ma_mark_file_changed(share);
pthread_mutex_lock(&share->bitmap.bitmap_lock);
/* purecov: end */
}
}
/* /*
Send updated bitmap to the page cache Send updated bitmap to the page cache
@ -413,24 +438,13 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* _ma_bitmap_mark_file_changed(share);
Before flusing bitmap, ensure that we have incremented open count.
This is needed to ensure that we don't call
_ma_mark_file_changed() as part of flushing bitmap page as in this
case we would use mutex lock in wrong order.
It's extremely unlikely that the following test is true as normally
this is happening when table is flushed.
*/
if (unlikely(!share->global_changed))
{
/* purecov: begin inspected */
/* unlock bitmap mutex as it can't be hold during _ma_mark_file_changed */
pthread_mutex_unlock(&bitmap->bitmap_lock);
_ma_mark_file_changed(share);
pthread_mutex_lock(&bitmap->bitmap_lock);
/* purecov: end */
}
/*
The following should be true as it was tested above. We have to test
this again as _ma_bitmap_mark_file_changed() did temporarly release
the bitmap mutex.
*/
if (bitmap->changed || bitmap->changed_not_flushed) if (bitmap->changed || bitmap->changed_not_flushed)
{ {
bitmap->flush_all_requested++; bitmap->flush_all_requested++;
@ -1010,6 +1024,8 @@ static my_bool _ma_change_bitmap_page(MARIA_HA *info,
{ {
DBUG_ENTER("_ma_change_bitmap_page"); DBUG_ENTER("_ma_change_bitmap_page");
_ma_bitmap_mark_file_changed(info->s);
if (bitmap->changed) if (bitmap->changed)
{ {
if (write_changed_bitmap(info->s, bitmap)) if (write_changed_bitmap(info->s, bitmap))
@ -1447,10 +1463,7 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
best_prefix_bits|= tmp; best_prefix_bits|= tmp;
int6store(best_data, best_prefix_bits); int6store(best_data, best_prefix_bits);
if (!(best_area_size-= best_prefix_area_size)) if (!(best_area_size-= best_prefix_area_size))
{ goto end;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
DBUG_RETURN(block->page_count);
}
best_data+= 6; best_data+= 6;
} }
best_area_size*= 3; /* Bits to set */ best_area_size*= 3; /* Bits to set */
@ -1468,6 +1481,7 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
bitmap->used_size= (uint) (best_data - bitmap->map); bitmap->used_size= (uint) (best_data - bitmap->map);
DBUG_ASSERT(bitmap->used_size <= bitmap->total_size); DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
} }
end:
bitmap->changed= 1; bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap);); DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
DBUG_RETURN(block->page_count); DBUG_RETURN(block->page_count);
@ -2142,7 +2156,7 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
Get bitmap pattern for a given page Get bitmap pattern for a given page
SYNOPSIS SYNOPSIS
get_page_bits() bitmap_get_page_bits()
info Maria handler info Maria handler
bitmap Bitmap handler bitmap Bitmap handler
page Page number page Page number
@ -2152,8 +2166,8 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
~0 Error (couldn't read page) ~0 Error (couldn't read page)
*/ */
uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap, static uint bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
pgcache_page_no_t page) pgcache_page_no_t page)
{ {
pgcache_page_no_t bitmap_page; pgcache_page_no_t bitmap_page;
uint offset_page, offset, tmp; uint offset_page, offset, tmp;
@ -2179,6 +2193,19 @@ uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
} }
/* As above, but take a lock while getting the data */
uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
pgcache_page_no_t page)
{
uint tmp;
pthread_mutex_lock(&bitmap->bitmap_lock);
tmp= bitmap_get_page_bits(info, bitmap, page);
pthread_mutex_unlock(&bitmap->bitmap_lock);
return tmp;
}
/* /*
Mark all pages in a region as free Mark all pages in a region as free
@ -2258,6 +2285,7 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* /*
Set all pages in a region as used Set all pages in a region as used
@ -2290,7 +2318,7 @@ my_bool _ma_bitmap_set_full_page_bits(MARIA_HA *info,
bitmap_page= page - page % bitmap->pages_covered; bitmap_page= page - page % bitmap->pages_covered;
if (page == bitmap_page || if (page == bitmap_page ||
page + page_count >= bitmap_page + bitmap->pages_covered) page + page_count > bitmap_page + bitmap->pages_covered)
{ {
DBUG_ASSERT(0); /* Wrong in data */ DBUG_ASSERT(0); /* Wrong in data */
DBUG_RETURN(1); DBUG_RETURN(1);
@ -2494,7 +2522,7 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
else else
{ {
DBUG_ASSERT(current_bitmap_value == DBUG_ASSERT(current_bitmap_value ==
_ma_bitmap_get_page_bits(info, bitmap, block->page)); bitmap_get_page_bits(info, bitmap, block->page));
} }
/* Handle all full pages and tail pages (for head page and blob) */ /* Handle all full pages and tail pages (for head page and blob) */
@ -2526,7 +2554,7 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
to not set the bits to the same value as before. to not set the bits to the same value as before.
*/ */
DBUG_ASSERT(current_bitmap_value == DBUG_ASSERT(current_bitmap_value ==
_ma_bitmap_get_page_bits(info, bitmap, block->page)); bitmap_get_page_bits(info, bitmap, block->page));
if (bits != current_bitmap_value) if (bits != current_bitmap_value)
{ {

View File

@ -412,12 +412,13 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
{ {
error=1; error=1;
_ma_check_print_error(param, _ma_check_print_error(param,
"Size of indexfile is: %-8s Should be: %s", "Size of indexfile is: %-8s Expected: %s",
llstr(size,buff), llstr(skr,buff2)); llstr(size,buff), llstr(skr,buff2));
share->state.state.key_file_length= size;
} }
else if (!(param->testflag & T_VERY_SILENT)) else if (!(param->testflag & T_VERY_SILENT))
_ma_check_print_warning(param, _ma_check_print_warning(param,
"Size of indexfile is: %-8s Should be: %s", "Size of indexfile is: %-8s Expected: %s",
llstr(size,buff), llstr(skr,buff2)); llstr(size,buff), llstr(skr,buff2));
} }
if (!(param->testflag & T_VERY_SILENT) && if (!(param->testflag & T_VERY_SILENT) &&
@ -439,18 +440,18 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
#endif #endif
if (skr != size) if (skr != size)
{ {
share->state.state.data_file_length=size; /* Skip other errors */
if (skr > size && skr != size + MEMMAP_EXTRA_MARGIN) if (skr > size && skr != size + MEMMAP_EXTRA_MARGIN)
{ {
share->state.state.data_file_length=size; /* Skip other errors */
error=1; error=1;
_ma_check_print_error(param,"Size of datafile is: %-9s Should be: %s", _ma_check_print_error(param,"Size of datafile is: %-9s Expected: %s",
llstr(size,buff), llstr(skr,buff2)); llstr(size,buff), llstr(skr,buff2));
param->testflag|=T_RETRY_WITHOUT_QUICK; param->testflag|=T_RETRY_WITHOUT_QUICK;
} }
else else
{ {
_ma_check_print_warning(param, _ma_check_print_warning(param,
"Size of datafile is: %-9s Should be: %s", "Size of datafile is: %-9s Expected: %s",
llstr(size,buff), llstr(skr,buff2)); llstr(size,buff), llstr(skr,buff2));
} }
} }
@ -1803,7 +1804,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
char llbuff[22], llbuff2[22]; char llbuff[22], llbuff2[22];
uint block_size= share->block_size; uint block_size= share->block_size;
ha_rows full_page_count, tail_count; ha_rows full_page_count, tail_count;
my_bool full_dir; my_bool full_dir, now_transactional;
uint offset_page, offset, free_count; uint offset_page, offset, free_count;
LINT_INIT(full_dir); LINT_INIT(full_dir);
@ -1814,6 +1815,10 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
my_errno); my_errno);
return 1; return 1;
} }
now_transactional= info->s->now_transactional;
info->s->now_transactional= 0; /* Don't log changes */
bitmap_buff= info->scan.bitmap_buff; bitmap_buff= info->scan.bitmap_buff;
page_buff= info->scan.page_buff; page_buff= info->scan.page_buff;
full_page_count= tail_count= 0; full_page_count= tail_count= 0;
@ -1833,7 +1838,8 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
if (_ma_killed_ptr(param)) if (_ma_killed_ptr(param))
{ {
_ma_scan_end_block_record(info); _ma_scan_end_block_record(info);
return -1; info->s->now_transactional= now_transactional;
return -1; /* Interrupted */
} }
if ((page % share->bitmap.pages_covered) == 0) if ((page % share->bitmap.pages_covered) == 0)
{ {
@ -2001,10 +2007,12 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
llstr(param->tail_count, llbuff), llstr(param->tail_count, llbuff),
llstr(tail_count, llbuff2)); llstr(tail_count, llbuff2));
info->s->now_transactional= now_transactional;
return param->error_printed != 0; return param->error_printed != 0;
err: err:
_ma_scan_end_block_record(info); _ma_scan_end_block_record(info);
info->s->now_transactional= now_transactional;
return 1; return 1;
} }

View File

@ -28,7 +28,8 @@ int maria_close(register MARIA_HA *info)
my_bool share_can_be_freed= FALSE; my_bool share_can_be_freed= FALSE;
MARIA_SHARE *share= info->s; MARIA_SHARE *share= info->s;
DBUG_ENTER("maria_close"); DBUG_ENTER("maria_close");
DBUG_PRINT("enter",("base: 0x%lx reopen: %u locks: %u", DBUG_PRINT("enter",("name: '%s' base: 0x%lx reopen: %u locks: %u",
share->open_file_name.str,
(long) info, (uint) share->reopen, (long) info, (uint) share->reopen,
(uint) share->tot_locks)); (uint) share->tot_locks));

View File

@ -494,6 +494,7 @@ error:
#define FLUSH_CACHE 2000 /* sort this many blocks at once */ #define FLUSH_CACHE 2000 /* sort this many blocks at once */
static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block); static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block);
static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link);
#ifndef DBUG_OFF #ifndef DBUG_OFF
static void test_key_cache(PAGECACHE *pagecache, static void test_key_cache(PAGECACHE *pagecache,
const char *where, my_bool lock); const char *where, my_bool lock);
@ -540,7 +541,7 @@ static void pagecache_debug_print _VARARGS((const char *fmt, ...));
#define KEYCACHE_DBUG_ASSERT(a) \ #define KEYCACHE_DBUG_ASSERT(a) \
{ if (! (a) && pagecache_debug_log) \ { if (! (a) && pagecache_debug_log) \
fclose(pagecache_debug_log); \ fclose(pagecache_debug_log); \
assert(a); } DBUG_ASSERT(a); }
#else #else
#define KEYCACHE_PRINT(l, m) #define KEYCACHE_PRINT(l, m)
#define KEYCACHE_DBUG_PRINT(l, m) DBUG_PRINT(l, m) #define KEYCACHE_DBUG_PRINT(l, m) DBUG_PRINT(l, m)
@ -1030,8 +1031,7 @@ ulong resize_pagecache(PAGECACHE *pagecache,
#ifdef THREAD #ifdef THREAD
while (pagecache->cnt_for_resize_op) while (pagecache->cnt_for_resize_op)
{ {
KEYCACHE_DBUG_PRINT("resize_pagecache: wait", DBUG_PRINT("wait", ("suspend thread %s %ld", thread->name, thread->id));
("suspend thread %ld", thread->id));
pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock);
} }
#else #else
@ -1050,8 +1050,9 @@ finish:
/* Signal for the next resize request to proceeed if any */ /* Signal for the next resize request to proceeed if any */
if (wqueue->last_thread) if (wqueue->last_thread)
{ {
KEYCACHE_DBUG_PRINT("resize_pagecache: signal", DBUG_PRINT("signal",
("thread %ld", wqueue->last_thread->next->id)); ("thread %s %ld", wqueue->last_thread->next->name,
wqueue->last_thread->next->id));
pagecache_pthread_cond_signal(&wqueue->last_thread->next->suspend); pagecache_pthread_cond_signal(&wqueue->last_thread->next->suspend);
} }
#endif #endif
@ -1075,6 +1076,7 @@ static inline void inc_counter_for_resize_op(PAGECACHE *pagecache)
Decrement counter blocking resize key cache operation; Decrement counter blocking resize key cache operation;
Signal the operation to proceed when counter becomes equal zero Signal the operation to proceed when counter becomes equal zero
*/ */
static inline void dec_counter_for_resize_op(PAGECACHE *pagecache) static inline void dec_counter_for_resize_op(PAGECACHE *pagecache)
{ {
#ifdef THREAD #ifdef THREAD
@ -1083,8 +1085,9 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache)
if (!--pagecache->cnt_for_resize_op && if (!--pagecache->cnt_for_resize_op &&
(last_thread= pagecache->resize_queue.last_thread)) (last_thread= pagecache->resize_queue.last_thread))
{ {
KEYCACHE_DBUG_PRINT("dec_counter_for_resize_op: signal", DBUG_PRINT("signal",
("thread %ld", last_thread->next->id)); ("thread %s %ld", last_thread->next->name,
last_thread->next->id));
pagecache_pthread_cond_signal(&last_thread->next->suspend); pagecache_pthread_cond_signal(&last_thread->next->suspend);
} }
#else #else
@ -1322,6 +1325,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
{ {
PAGECACHE_BLOCK_LINK *ins; PAGECACHE_BLOCK_LINK *ins;
PAGECACHE_BLOCK_LINK **ptr_ins; PAGECACHE_BLOCK_LINK **ptr_ins;
DBUG_ENTER("link_block");
PCBLOCK_INFO(block); PCBLOCK_INFO(block);
KEYCACHE_DBUG_ASSERT(! (block->hash_link && block->hash_link->requests)); KEYCACHE_DBUG_ASSERT(! (block->hash_link && block->hash_link->requests));
@ -1336,6 +1340,11 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
PAGECACHE_HASH_LINK *hash_link= PAGECACHE_HASH_LINK *hash_link=
(PAGECACHE_HASH_LINK *) first_thread->opt_info; (PAGECACHE_HASH_LINK *) first_thread->opt_info;
struct st_my_thread_var *thread; struct st_my_thread_var *thread;
DBUG_ASSERT(block->requests + block->wlocks + block->rlocks +
block->pins == 0);
DBUG_ASSERT(block->next_used == NULL);
do do
{ {
thread= next_thread; thread= next_thread;
@ -1346,7 +1355,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
*/ */
if ((PAGECACHE_HASH_LINK *) thread->opt_info == hash_link) if ((PAGECACHE_HASH_LINK *) thread->opt_info == hash_link)
{ {
KEYCACHE_DBUG_PRINT("link_block: signal", ("thread: %ld", thread->id)); DBUG_PRINT("signal", ("thread: %s %ld", thread->name, thread->id));
pagecache_pthread_cond_signal(&thread->suspend); pagecache_pthread_cond_signal(&thread->suspend);
wqueue_unlink_from_queue(&pagecache->waiting_for_block, thread); wqueue_unlink_from_queue(&pagecache->waiting_for_block, thread);
block->requests++; block->requests++;
@ -1354,14 +1363,17 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
} }
while (thread != last_thread); while (thread != last_thread);
hash_link->block= block; hash_link->block= block;
KEYCACHE_THREAD_TRACE("link_block: after signaling"); /* Ensure that no other thread tries to use this block */
block->status|= PCBLOCK_REASSIGNED;
DBUG_PRINT("signal", ("after signal"));
#if defined(PAGECACHE_DEBUG) #if defined(PAGECACHE_DEBUG)
KEYCACHE_DBUG_PRINT("link_block", KEYCACHE_DBUG_PRINT("link_block",
("linked,unlinked block: %u status: %x #requests: %u #available: %u", ("linked,unlinked block: %u status: %x #requests: %u #available: %u",
PCBLOCK_NUMBER(pagecache, block), block->status, PCBLOCK_NUMBER(pagecache, block), block->status,
block->requests, pagecache->blocks_available)); block->requests, pagecache->blocks_available));
#endif #endif
return; DBUG_VOID_RETURN;
} }
#else /* THREAD */ #else /* THREAD */
KEYCACHE_DBUG_ASSERT(! (!hot && pagecache->waiting_for_block.last_thread)); KEYCACHE_DBUG_ASSERT(! (!hot && pagecache->waiting_for_block.last_thread));
@ -1381,8 +1393,6 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
else else
{ {
/* The LRU chain is empty */ /* The LRU chain is empty */
/* QQ: Ask sanja if next line is correct; Should we really put block
in both chain if one chain is empty ? */
pagecache->used_last= pagecache->used_ins= block->next_used= block; pagecache->used_last= pagecache->used_ins= block->next_used= block;
block->prev_used= &block->next_used; block->prev_used= &block->next_used;
} }
@ -1396,6 +1406,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
KEYCACHE_DBUG_ASSERT((ulong) pagecache->blocks_available <= KEYCACHE_DBUG_ASSERT((ulong) pagecache->blocks_available <=
pagecache->blocks_used); pagecache->blocks_used);
#endif #endif
DBUG_VOID_RETURN;
} }
@ -1404,7 +1415,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
SYNOPSIS SYNOPSIS
unlink_block() unlink_block()
pagecache pointer to a page cache data structure pagecache pointer to a page cache data structure
block pointer to the block to unlink from the LRU chain block pointer to the block to unlink from the LRU chain
RETURN VALUE RETURN VALUE
@ -1511,7 +1522,7 @@ static void unreg_request(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *block, int at_end) PAGECACHE_BLOCK_LINK *block, int at_end)
{ {
DBUG_ENTER("unreg_request"); DBUG_ENTER("unreg_request");
DBUG_PRINT("enter", ("block 0x%lx (%u) status: %x reqs: %u", DBUG_PRINT("enter", ("block 0x%lx (%u) status: %x requests: %u",
(ulong)block, PCBLOCK_NUMBER(pagecache, block), (ulong)block, PCBLOCK_NUMBER(pagecache, block),
block->status, block->requests)); block->status, block->requests));
PCBLOCK_INFO(block); PCBLOCK_INFO(block);
@ -1580,18 +1591,23 @@ static inline void remove_reader(PAGECACHE_BLOCK_LINK *block)
static inline void wait_for_readers(PAGECACHE *pagecache static inline void wait_for_readers(PAGECACHE *pagecache
__attribute__((unused)), __attribute__((unused)),
PAGECACHE_BLOCK_LINK *block) PAGECACHE_BLOCK_LINK *block
__attribute__((unused)))
{ {
#ifdef THREAD #ifdef THREAD
struct st_my_thread_var *thread= my_thread_var; struct st_my_thread_var *thread= my_thread_var;
DBUG_ASSERT(block->condvar == NULL);
while (block->hash_link->requests) while (block->hash_link->requests)
{ {
KEYCACHE_DBUG_PRINT("wait_for_readers: wait", DBUG_ENTER("wait_for_readers");
("suspend thread: %ld block: %u", DBUG_PRINT("wait",
thread->id, PCBLOCK_NUMBER(pagecache, block))); ("suspend thread: %s %ld block: %u",
thread->name, thread->id,
PCBLOCK_NUMBER(pagecache, block)));
block->condvar= &thread->suspend; block->condvar= &thread->suspend;
pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock);
block->condvar= NULL; block->condvar= NULL;
DBUG_VOID_RETURN;
} }
#else #else
KEYCACHE_DBUG_ASSERT(block->hash_link->requests == 0); KEYCACHE_DBUG_ASSERT(block->hash_link->requests == 0);
@ -1599,6 +1615,30 @@ static inline void wait_for_readers(PAGECACHE *pagecache
} }
/*
Wait until the flush of the page is done.
*/
static void wait_for_flush(PAGECACHE *pagecache
__attribute__((unused)),
PAGECACHE_BLOCK_LINK *block
__attribute__((unused)))
{
struct st_my_thread_var *thread= my_thread_var;
DBUG_ENTER("wait_for_flush");
wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
do
{
DBUG_PRINT("wait",
("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
while(thread->next);
DBUG_VOID_RETURN;
}
/* /*
Add a hash link to a bucket in the hash_table Add a hash link to a bucket in the hash_table
*/ */
@ -1620,10 +1660,14 @@ static inline void link_hash(PAGECACHE_HASH_LINK **start,
static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link) static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link)
{ {
KEYCACHE_DBUG_PRINT("unlink_hash", ("fd: %u pos_ %lu #requests=%u", DBUG_ENTER("unlink_hash");
(uint) hash_link->file.file, (ulong) hash_link->pageno, DBUG_PRINT("enter", ("hash_link: %p fd: %u pos: %lu requests: %u",
hash_link->requests)); hash_link, (uint) hash_link->file.file,
KEYCACHE_DBUG_ASSERT(hash_link->requests == 0); (ulong) hash_link->pageno,
hash_link->requests));
DBUG_ASSERT(hash_link->requests == 0);
DBUG_ASSERT(!hash_link->block || hash_link->block->pins == 0);
if ((*hash_link->prev= hash_link->next)) if ((*hash_link->prev= hash_link->next))
hash_link->next->prev= hash_link->prev; hash_link->next->prev= hash_link->prev;
hash_link->block= NULL; hash_link->block= NULL;
@ -1654,23 +1698,32 @@ static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link)
if (page->file.file == hash_link->file.file && if (page->file.file == hash_link->file.file &&
page->pageno == hash_link->pageno) page->pageno == hash_link->pageno)
{ {
KEYCACHE_DBUG_PRINT("unlink_hash: signal", ("thread %ld", thread->id)); DBUG_PRINT("signal", ("thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_signal(&thread->suspend); pagecache_pthread_cond_signal(&thread->suspend);
wqueue_unlink_from_queue(&pagecache->waiting_for_hash_link, thread); wqueue_unlink_from_queue(&pagecache->waiting_for_hash_link, thread);
} }
} }
while (thread != last_thread); while (thread != last_thread);
/*
Add this to the hash, so that the waiting threads can find it
when they retry the call to get_hash_link(). This entry is special
in that it has no associated block.
*/
link_hash(&pagecache->hash_root[PAGECACHE_HASH(pagecache, link_hash(&pagecache->hash_root[PAGECACHE_HASH(pagecache,
hash_link->file, hash_link->file,
hash_link->pageno)], hash_link->pageno)],
hash_link); hash_link);
return; DBUG_VOID_RETURN;
} }
#else /* THREAD */ #else /* THREAD */
KEYCACHE_DBUG_ASSERT(! (pagecache->waiting_for_hash_link.last_thread)); KEYCACHE_DBUG_ASSERT(! (pagecache->waiting_for_hash_link.last_thread));
#endif /* THREAD */ #endif /* THREAD */
/* Add hash to free hash list */
hash_link->next= pagecache->free_hash_list; hash_link->next= pagecache->free_hash_list;
pagecache->free_hash_list= hash_link; pagecache->free_hash_list= hash_link;
DBUG_VOID_RETURN;
} }
@ -1701,8 +1754,6 @@ static PAGECACHE_HASH_LINK *get_present_hash_link(PAGECACHE *pagecache,
#endif #endif
DBUG_ENTER("get_present_hash_link"); DBUG_ENTER("get_present_hash_link");
DBUG_PRINT("enter", ("fd: %u pos: %lu", (uint) file->file, (ulong) pageno)); DBUG_PRINT("enter", ("fd: %u pos: %lu", (uint) file->file, (ulong) pageno));
KEYCACHE_PRINT("get_present_hash_link", ("fd: %u pos: %lu",
(uint) file->file, (ulong) pageno));
/* /*
Find the bucket in the hash table for the pair (file, pageno); Find the bucket in the hash table for the pair (file, pageno);
@ -1737,6 +1788,7 @@ static PAGECACHE_HASH_LINK *get_present_hash_link(PAGECACHE *pagecache,
} }
if (hash_link) if (hash_link)
{ {
DBUG_PRINT("exit", ("hash_link: %p", hash_link));
/* Register the request for the page */ /* Register the request for the page */
hash_link->requests++; hash_link->requests++;
} }
@ -1758,9 +1810,7 @@ static PAGECACHE_HASH_LINK *get_hash_link(PAGECACHE *pagecache,
{ {
reg1 PAGECACHE_HASH_LINK *hash_link; reg1 PAGECACHE_HASH_LINK *hash_link;
PAGECACHE_HASH_LINK **start; PAGECACHE_HASH_LINK **start;
DBUG_ENTER("get_hash_link");
KEYCACHE_DBUG_PRINT("get_hash_link", ("fd: %u pos: %lu",
(uint) file->file, (ulong) pageno));
restart: restart:
/* try to find the page in the cache */ /* try to find the page in the cache */
@ -1771,6 +1821,9 @@ restart:
/* There is no hash link in the hash table for the pair (file, pageno) */ /* There is no hash link in the hash table for the pair (file, pageno) */
if (pagecache->free_hash_list) if (pagecache->free_hash_list)
{ {
DBUG_PRINT("info", ("free_hash_list: %p free_hash_list->next: %p",
pagecache->free_hash_list,
pagecache->free_hash_list->next));
hash_link= pagecache->free_hash_list; hash_link= pagecache->free_hash_list;
pagecache->free_hash_list= hash_link->next; pagecache->free_hash_list= hash_link->next;
} }
@ -1784,21 +1837,20 @@ restart:
/* Wait for a free hash link */ /* Wait for a free hash link */
struct st_my_thread_var *thread= my_thread_var; struct st_my_thread_var *thread= my_thread_var;
PAGECACHE_PAGE page; PAGECACHE_PAGE page;
KEYCACHE_DBUG_PRINT("get_hash_link", ("waiting"));
page.file= *file; page.file= *file;
page.pageno= pageno; page.pageno= pageno;
thread->opt_info= (void *) &page; thread->opt_info= (void *) &page;
wqueue_link_into_queue(&pagecache->waiting_for_hash_link, thread); wqueue_link_into_queue(&pagecache->waiting_for_hash_link, thread);
KEYCACHE_DBUG_PRINT("get_hash_link: wait", DBUG_PRINT("wait",
("suspend thread %ld", thread->id)); ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock); &pagecache->cache_lock);
thread->opt_info= NULL; thread->opt_info= NULL;
#else DBUG_PRINT("thread", ("restarting..."));
KEYCACHE_DBUG_ASSERT(0);
#endif
DBUG_PRINT("info", ("restarting..."));
goto restart; goto restart;
#else
DBUG_ASSERT(0);
#endif
} }
hash_link->file= *file; hash_link->file= *file;
DBUG_ASSERT(pageno < ((ULL(1)) << 40)); DBUG_ASSERT(pageno < ((ULL(1)) << 40));
@ -1807,9 +1859,19 @@ restart:
/* Register the request for the page */ /* Register the request for the page */
hash_link->requests++; hash_link->requests++;
DBUG_ASSERT(hash_link->block == 0); DBUG_ASSERT(hash_link->block == 0);
DBUG_ASSERT(hash_link->requests == 1);
} }
else
return hash_link; {
/*
We have to copy the flush_log callback, as it may change if the table
goes from non_transactional to transactional during recovery
*/
hash_link->file.flush_log_callback= file->flush_log_callback;
}
DBUG_PRINT("exit", ("hash_link: %p block: %p", hash_link,
hash_link->block));
DBUG_RETURN(hash_link);
} }
@ -1923,16 +1985,7 @@ restart:
hash_link->requests--; hash_link->requests--;
{ {
#ifdef THREAD #ifdef THREAD
struct st_my_thread_var *thread= my_thread_var; wait_for_flush(pagecache, block);
wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
do
{
KEYCACHE_DBUG_PRINT("find_block: wait",
("suspend thread %ld", thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
while(thread->next);
#else #else
KEYCACHE_DBUG_ASSERT(0); KEYCACHE_DBUG_ASSERT(0);
/* /*
@ -1945,6 +1998,7 @@ restart:
#endif #endif
} }
/* Invalidate page in the block if it has not been done yet */ /* Invalidate page in the block if it has not been done yet */
DBUG_ASSERT(block->status); /* Should always be true */
if (block->status) if (block->status)
free_block(pagecache, block); free_block(pagecache, block);
return 0; return 0;
@ -1983,8 +2037,8 @@ restart:
/* Wait until the request can be resubmitted */ /* Wait until the request can be resubmitted */
do do
{ {
KEYCACHE_DBUG_PRINT("find_block: wait", DBUG_PRINT("wait",
("suspend thread %ld", thread->id)); ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock); &pagecache->cache_lock);
} }
@ -2056,32 +2110,39 @@ restart:
/* There are no never used blocks, use a block from the LRU chain */ /* There are no never used blocks, use a block from the LRU chain */
/* /*
Wait until a new block is added to the LRU chain; Ensure that we are going to register the block.
several threads might wait here for the same page, (This should be true as a new block could not have been
all of them must get the same block pinned by caller).
*/ */
DBUG_ASSERT(reg_req);
#ifdef THREAD #ifdef THREAD
if (! pagecache->used_last) if (! pagecache->used_last)
{ {
/*
Wait until a new block is added to the LRU chain;
several threads might wait here for the same page,
all of them must get the same block.
The block is given to us by the next thread executing
link_block().
*/
struct st_my_thread_var *thread= my_thread_var; struct st_my_thread_var *thread= my_thread_var;
thread->opt_info= (void *) hash_link; thread->opt_info= (void *) hash_link;
wqueue_link_into_queue(&pagecache->waiting_for_block, thread); wqueue_link_into_queue(&pagecache->waiting_for_block, thread);
do do
{ {
KEYCACHE_DBUG_PRINT("find_block: wait", DBUG_PRINT("wait",
("suspend thread %ld", thread->id)); ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock); &pagecache->cache_lock);
} }
while (thread->next); while (thread->next);
thread->opt_info= NULL; thread->opt_info= NULL;
block= hash_link->block; block= hash_link->block;
/* /* Ensure that the block is registered */
Ensure that we are register this block (all blocks not used by this DBUG_ASSERT(block->requests >= 1);
thread has to be registered).
*/
DBUG_ASSERT(reg_req);
} }
else else
#else #else
@ -2093,21 +2154,24 @@ restart:
unlinking it from the chain unlinking it from the chain
*/ */
block= pagecache->used_last->next_used; block= pagecache->used_last->next_used;
block->hits_left= init_hits_left;
block->last_hit_time= 0;
if (reg_req) if (reg_req)
reg_requests(pagecache, block, 1); reg_requests(pagecache, block, 1);
hash_link->block= block; hash_link->block= block;
DBUG_ASSERT(block->requests == 1);
} }
PCBLOCK_INFO(block); PCBLOCK_INFO(block);
DBUG_ASSERT(block->wlocks == 0);
DBUG_ASSERT(block->rlocks == 0); DBUG_ASSERT(block->hash_link == hash_link ||
DBUG_ASSERT(block->rlocks_queue == 0); !(block->status & PCBLOCK_IN_SWITCH));
DBUG_ASSERT(block->pins == 0);
if (block->hash_link != hash_link && if (block->hash_link != hash_link &&
! (block->status & PCBLOCK_IN_SWITCH) ) ! (block->status & PCBLOCK_IN_SWITCH) )
{ {
/* If another thread is flushing the block, wait for it. */
if (block->status & PCBLOCK_IN_FLUSH)
wait_for_flush(pagecache, block);
/* this is a primary request for a new page */ /* this is a primary request for a new page */
DBUG_ASSERT(block->wlocks == 0); DBUG_ASSERT(block->wlocks == 0);
DBUG_ASSERT(block->rlocks == 0); DBUG_ASSERT(block->rlocks == 0);
@ -2154,15 +2218,20 @@ restart:
/* Remove the hash link for this page from the hash table */ /* Remove the hash link for this page from the hash table */
unlink_hash(pagecache, block->hash_link); unlink_hash(pagecache, block->hash_link);
/* All pending requests for this page must be resubmitted */
#ifdef THREAD #ifdef THREAD
/* All pending requests for this page must be resubmitted. */
if (block->wqueue[COND_FOR_SAVED].last_thread) if (block->wqueue[COND_FOR_SAVED].last_thread)
wqueue_release_queue(&block->wqueue[COND_FOR_SAVED]); wqueue_release_queue(&block->wqueue[COND_FOR_SAVED]);
#endif #endif
} }
link_to_file_list(pagecache, block, file, link_to_file_list(pagecache, block, file,
(my_bool)(block->hash_link ? 1 : 0)); (my_bool)(block->hash_link ? 1 : 0));
block->hash_link= hash_link;
PCBLOCK_INFO(block); PCBLOCK_INFO(block);
block->hits_left= init_hits_left;
block->last_hit_time= 0;
block->status= error ? PCBLOCK_ERROR : 0; block->status= error ? PCBLOCK_ERROR : 0;
block->error= error ? (int16) my_errno : 0; block->error= error ? (int16) my_errno : 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
@ -2170,7 +2239,6 @@ restart:
if (error) if (error)
my_debug_put_break_here(); my_debug_put_break_here();
#endif #endif
block->hash_link= hash_link;
page_status= PAGE_TO_BE_READ; page_status= PAGE_TO_BE_READ;
DBUG_PRINT("info", ("page to be read set for page 0x%lx", DBUG_PRINT("info", ("page to be read set for page 0x%lx",
(ulong)block)); (ulong)block));
@ -2193,12 +2261,18 @@ restart:
} }
else else
{ {
/*
The block was found in the cache. It's either a already read
block or a block waiting to be read by another thread.
*/
if (reg_req) if (reg_req)
reg_requests(pagecache, block, 1); reg_requests(pagecache, block, 1);
KEYCACHE_DBUG_PRINT("find_block", KEYCACHE_DBUG_PRINT("find_block",
("block->hash_link: %p hash_link: %p " ("block->hash_link: %p hash_link: %p "
"block->status: %u", block->hash_link, "block->status: %u", block->hash_link,
hash_link, block->status )); hash_link, block->status ));
KEYCACHE_DBUG_ASSERT(block->hash_link == hash_link &&
hash_link->block == block);
page_status= (((block->hash_link == hash_link) && page_status= (((block->hash_link == hash_link) &&
(block->status & PCBLOCK_READ)) ? (block->status & PCBLOCK_READ)) ?
PAGE_READ : PAGE_WAIT_TO_BE_READ); PAGE_READ : PAGE_WAIT_TO_BE_READ);
@ -2332,8 +2406,8 @@ static my_bool pagecache_wait_lock(PAGECACHE *pagecache,
dec_counter_for_resize_op(pagecache); dec_counter_for_resize_op(pagecache);
do do
{ {
KEYCACHE_DBUG_PRINT("get_wrlock: wait", DBUG_PRINT("wait",
("suspend thread %ld", thread->id)); ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock); &pagecache->cache_lock);
} }
@ -2575,6 +2649,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
DBUG_ASSERT(!any || DBUG_ASSERT(!any ||
((lock == PAGECACHE_LOCK_LEFT_UNLOCKED) && ((lock == PAGECACHE_LOCK_LEFT_UNLOCKED) &&
(pin == PAGECACHE_UNPIN))); (pin == PAGECACHE_UNPIN)));
DBUG_ASSERT(block->hash_link->block == block);
switch (lock) { switch (lock) {
case PAGECACHE_LOCK_WRITE: /* free -> write */ case PAGECACHE_LOCK_WRITE: /* free -> write */
@ -2741,8 +2816,8 @@ static void read_block(PAGECACHE *pagecache,
wqueue_add_to_queue(&block->wqueue[COND_FOR_REQUESTED], thread); wqueue_add_to_queue(&block->wqueue[COND_FOR_REQUESTED], thread);
do do
{ {
DBUG_PRINT("read_block: wait", DBUG_PRINT("wait",
("suspend thread %ld", thread->id)); ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock); &pagecache->cache_lock);
} }
@ -3627,7 +3702,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache,
DBUG_ASSERT(0); DBUG_ASSERT(0);
DBUG_ASSERT(block->hash_link->requests > 0); DBUG_ASSERT(block->hash_link->requests > 0);
page_link->requests--; page_link->requests--;
/* See NOTE for pagecache_unlock about registering requests. */ /* See NOTE for pagecache_unlock() about registering requests. */
free_block(pagecache, block); free_block(pagecache, block);
dec_counter_for_resize_op(pagecache); dec_counter_for_resize_op(pagecache);
return 0; return 0;
@ -4232,6 +4307,7 @@ end:
static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block) static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
{ {
uint status= block->status;
KEYCACHE_THREAD_TRACE("free block"); KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block", KEYCACHE_DBUG_PRINT("free_block",
("block: %u hash_link 0x%lx", ("block: %u hash_link 0x%lx",
@ -4257,29 +4333,43 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
DBUG_ASSERT(block->rlocks_queue == 0); DBUG_ASSERT(block->rlocks_queue == 0);
DBUG_ASSERT(block->pins == 0); DBUG_ASSERT(block->pins == 0);
DBUG_ASSERT((block->status & ~(PCBLOCK_ERROR | PCBLOCK_READ | PCBLOCK_IN_FLUSH | PCBLOCK_CHANGED | PCBLOCK_REASSIGNED | PCBLOCK_DEL_WRITE)) == 0); DBUG_ASSERT((block->status & ~(PCBLOCK_ERROR | PCBLOCK_READ | PCBLOCK_IN_FLUSH | PCBLOCK_CHANGED | PCBLOCK_REASSIGNED | PCBLOCK_DEL_WRITE)) == 0);
DBUG_ASSERT(block->requests >= 1);
DBUG_ASSERT(block->next_used == NULL);
block->status= 0; block->status= 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
block->type= PAGECACHE_EMPTY_PAGE; block->type= PAGECACHE_EMPTY_PAGE;
#endif #endif
block->rec_lsn= LSN_MAX; block->rec_lsn= LSN_MAX;
block->hash_link= NULL;
if (block->temperature == PCBLOCK_WARM)
pagecache->warm_blocks--;
block->temperature= PCBLOCK_COLD;
KEYCACHE_THREAD_TRACE("free block"); KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block", KEYCACHE_DBUG_PRINT("free_block",
("block is freed")); ("block is freed"));
unreg_request(pagecache, block, 0); unreg_request(pagecache, block, 0);
DBUG_ASSERT(block->requests == 0);
DBUG_ASSERT(block->next_used != 0);
block->hash_link= NULL;
/* Remove the free block from the LRU ring. */ /*
unlink_block(pagecache, block); Block->requests is != 0 if unreg_requests()/link_block() gave the block
if (block->temperature == PCBLOCK_WARM) to a waiting thread
pagecache->warm_blocks--; */
block->temperature= PCBLOCK_COLD; if (!block->requests)
/* Insert the free block in the free list. */ {
block->next_used= pagecache->free_block_list; DBUG_ASSERT(block->next_used != 0);
pagecache->free_block_list= block;
/* Keep track of the number of currently unused blocks. */ /* Remove the free block from the LRU ring. */
pagecache->blocks_unused++; unlink_block(pagecache, block);
/* Insert the free block in the free list. */
block->next_used= pagecache->free_block_list;
pagecache->free_block_list= block;
/* Keep track of the number of currently unused blocks. */
pagecache->blocks_unused++;
}
else
{
/* keep flag set by link_block() */
block->status= status & PCBLOCK_REASSIGNED;
}
#ifdef THREAD #ifdef THREAD
/* All pending requests for this page must be resubmitted. */ /* All pending requests for this page must be resubmitted. */
@ -4537,8 +4627,9 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
wqueue_add_to_queue(&other_flusher->flush_queue, thread); wqueue_add_to_queue(&other_flusher->flush_queue, thread);
do do
{ {
KEYCACHE_DBUG_PRINT("flush_pagecache_blocks_int: wait1", DBUG_PRINT("wait",
("suspend thread %ld", thread->id)); ("(1) suspend thread %s %ld",
thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock); &pagecache->cache_lock);
} }
@ -4699,8 +4790,9 @@ restart:
wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
do do
{ {
KEYCACHE_DBUG_PRINT("flush_pagecache_blocks_int: wait2", DBUG_PRINT("wait",
("suspend thread %ld", thread->id)); ("(2) suspend thread %s %ld",
thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock); &pagecache->cache_lock);
} }
@ -4910,8 +5002,8 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
wqueue_add_to_queue(&other_flusher->flush_queue, thread); wqueue_add_to_queue(&other_flusher->flush_queue, thread);
do do
{ {
KEYCACHE_DBUG_PRINT("pagecache_collect_changed_blocks_with_lsn: wait", DBUG_PRINT("wait",
("suspend thread %ld", thread->id)); ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock); &pagecache->cache_lock);
} }
@ -5055,7 +5147,7 @@ static void pagecache_dump(PAGECACHE *pagecache)
PAGECACHE_PAGE *page; PAGECACHE_PAGE *page;
uint i; uint i;
fprintf(pagecache_dump_file, "thread:%u\n", thread->id); fprintf(pagecache_dump_file, "thread: %s %ld\n", thread->name, thread->id);
i=0; i=0;
thread=last=waiting_for_hash_link.last_thread; thread=last=waiting_for_hash_link.last_thread;
@ -5066,8 +5158,9 @@ static void pagecache_dump(PAGECACHE *pagecache)
thread= thread->next; thread= thread->next;
page= (PAGECACHE_PAGE *) thread->opt_info; page= (PAGECACHE_PAGE *) thread->opt_info;
fprintf(pagecache_dump_file, fprintf(pagecache_dump_file,
"thread:%u, (file,pageno)=(%u,%lu)\n", "thread: %s %ld, (file,pageno)=(%u,%lu)\n",
thread->id,(uint) page->file.file,(ulong) page->pageno); thread->name, thread->id,
(uint) page->file.file,(ulong) page->pageno);
if (++i == MAX_QUEUE_LEN) if (++i == MAX_QUEUE_LEN)
break; break;
} }
@ -5082,8 +5175,9 @@ static void pagecache_dump(PAGECACHE *pagecache)
thread=thread->next; thread=thread->next;
hash_link= (PAGECACHE_HASH_LINK *) thread->opt_info; hash_link= (PAGECACHE_HASH_LINK *) thread->opt_info;
fprintf(pagecache_dump_file, fprintf(pagecache_dump_file,
"thread:%u hash_link:%u (file,pageno)=(%u,%lu)\n", "thread: %s %u hash_link:%u (file,pageno)=(%u,%lu)\n",
thread->id, (uint) PAGECACHE_HASH_LINK_NUMBER(pagecache, hash_link), thread->name, thread->id,
(uint) PAGECACHE_HASH_LINK_NUMBER(pagecache, hash_link),
(uint) hash_link->file.file,(ulong) hash_link->pageno); (uint) hash_link->file.file,(ulong) hash_link->pageno);
if (++i == MAX_QUEUE_LEN) if (++i == MAX_QUEUE_LEN)
break; break;
@ -5112,7 +5206,7 @@ static void pagecache_dump(PAGECACHE *pagecache)
{ {
thread=thread->next; thread=thread->next;
fprintf(pagecache_dump_file, fprintf(pagecache_dump_file,
"thread:%u\n", thread->id); "thread: %s %ld\n", thread->name, thread->id);
if (++i == MAX_QUEUE_LEN) if (++i == MAX_QUEUE_LEN)
break; break;
} }

View File

@ -60,6 +60,7 @@ static int (*save_error_handler_hook)(uint, const char *,myf);
static uint recovery_warnings; /**< count of warnings */ static uint recovery_warnings; /**< count of warnings */
static uint recovery_found_crashed_tables; static uint recovery_found_crashed_tables;
HASH tables_to_redo; /* For maria_read_log */ HASH tables_to_redo; /* For maria_read_log */
ulong maria_recovery_force_crash_counter;
#define prototype_redo_exec_hook(R) \ #define prototype_redo_exec_hook(R) \
static int exec_REDO_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec) static int exec_REDO_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec)
@ -2939,6 +2940,12 @@ static int run_undo_phase(uint uncommitted)
translog_free_record_header(&rec); translog_free_record_header(&rec);
} }
/* Force a crash to test recovery of recovery */
if (maria_recovery_force_crash_counter)
{
DBUG_ASSERT(--maria_recovery_force_crash_counter > 0);
}
if (trnman_rollback_trn(trn)) if (trnman_rollback_trn(trn))
DBUG_RETURN(1); DBUG_RETURN(1);
/* We could want to span a few threads (4?) instead of 1 */ /* We could want to span a few threads (4?) instead of 1 */
@ -3436,6 +3443,12 @@ static int close_all_tables(void)
prepare_table_for_close(info, addr); prepare_table_for_close(info, addr);
error|= maria_close(info); error|= maria_close(info);
pthread_mutex_lock(&THR_LOCK_maria); pthread_mutex_lock(&THR_LOCK_maria);
/* Force a crash to test recovery of recovery */
if (maria_recovery_force_crash_counter)
{
DBUG_ASSERT(--maria_recovery_force_crash_counter > 0);
}
} }
end: end:
pthread_mutex_unlock(&THR_LOCK_maria); pthread_mutex_unlock(&THR_LOCK_maria);
@ -3510,7 +3523,7 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
/* /*
Reset state pointers. This is needed as in ALTER table we may do Reset state pointers. This is needed as in ALTER table we may do
commit fllowed by _ma_renable_logging_for_table and then commit followed by _ma_renable_logging_for_table and then
info->state may point to a state that was deleted by info->state may point to a state that was deleted by
_ma_trnman_end_trans_hook() _ma_trnman_end_trans_hook()
*/ */

View File

@ -32,4 +32,5 @@ int maria_apply_log(LSN lsn, LSN lsn_end, enum maria_apply_log_way apply,
my_bool take_checkpoints, uint *warnings_count); my_bool take_checkpoints, uint *warnings_count);
/* Table of tables to recover */ /* Table of tables to recover */
extern HASH tables_to_redo; extern HASH tables_to_redo;
extern ulong maria_recovery_force_crash_counter;
C_MODE_END C_MODE_END

View File

@ -949,6 +949,7 @@ static void get_options(register int *argc,register char ***argv)
static int maria_chk(HA_CHECK *param, char *filename) static int maria_chk(HA_CHECK *param, char *filename)
{ {
int error,lock_type,recreate; int error,lock_type,recreate;
uint warning_printed_by_chk_status;
my_bool rep_quick= test(param->testflag & (T_QUICK | T_FORCE_UNIQUENESS)); my_bool rep_quick= test(param->testflag & (T_QUICK | T_FORCE_UNIQUENESS));
MARIA_HA *info; MARIA_HA *info;
File datafile; File datafile;
@ -961,6 +962,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
recreate=0; recreate=0;
datafile=0; datafile=0;
param->isam_file_name=filename; /* For error messages */ param->isam_file_name=filename; /* For error messages */
warning_printed_by_chk_status= 0;
if (!(info=maria_open(filename, if (!(info=maria_open(filename,
(param->testflag & (T_DESCRIPT | T_READONLY)) ? (param->testflag & (T_DESCRIPT | T_READONLY)) ?
O_RDONLY : O_RDWR, O_RDONLY : O_RDWR,
@ -1303,7 +1305,12 @@ static int maria_chk(HA_CHECK *param, char *filename)
maria_chk_init_for_check(param, info); maria_chk_init_for_check(param, info);
if (opt_warning_for_wrong_transid == 0) if (opt_warning_for_wrong_transid == 0)
param->max_trid= ~ (ulonglong) 0; param->max_trid= ~ (ulonglong) 0;
error= maria_chk_status(param,info); error= maria_chk_status(param,info);
/* Forget warning printed by maria_chk_status if no problems found */
warning_printed_by_chk_status= param->warning_printed;
param->warning_printed= 0;
maria_intersect_keys_active(share->state.key_map, param->keys_in_use); maria_intersect_keys_active(share->state.key_map, param->keys_in_use);
error|= maria_chk_size(param,info); error|= maria_chk_size(param,info);
if (!error || !(param->testflag & (T_FAST | T_FORCE_CREATE))) if (!error || !(param->testflag & (T_FAST | T_FORCE_CREATE)))
@ -1371,8 +1378,12 @@ static int maria_chk(HA_CHECK *param, char *filename)
(state_updated ? UPDATE_STAT : 0) | (state_updated ? UPDATE_STAT : 0) |
((param->testflag & T_SORT_RECORDS) ? ((param->testflag & T_SORT_RECORDS) ?
UPDATE_SORT : 0))); UPDATE_SORT : 0)));
if (!(param->testflag & T_SILENT)) if (warning_printed_by_chk_status)
_ma_check_print_info(param, "Aria table '%s' was ok. Status updated",
filename);
else if (!(param->testflag & T_SILENT))
printf("State updated\n"); printf("State updated\n");
warning_printed_by_chk_status= 0;
} }
info->update&= ~HA_STATE_CHANGED; info->update&= ~HA_STATE_CHANGED;
_ma_reenable_logging_for_table(info, FALSE); _ma_reenable_logging_for_table(info, FALSE);
@ -1426,7 +1437,7 @@ end2:
"Aria table '%s' is corrupted\nFix it using switch \"-r\" or \"-o\"\n", "Aria table '%s' is corrupted\nFix it using switch \"-r\" or \"-o\"\n",
filename)); filename));
} }
else if (param->warning_printed && else if ((param->warning_printed || warning_printed_by_chk_status) &&
! (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX | ! (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX |
T_FORCE_CREATE))) T_FORCE_CREATE)))
{ {
@ -1435,6 +1446,7 @@ end2:
VOID(fprintf(stderr, "Aria table '%s' is usable but should be fixed\n", VOID(fprintf(stderr, "Aria table '%s' is usable but should be fixed\n",
filename)); filename));
} }
VOID(fflush(stderr)); VOID(fflush(stderr));
DBUG_RETURN(error); DBUG_RETURN(error);
} /* maria_chk */ } /* maria_chk */
@ -1464,7 +1476,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
printf("Aria file: %s\n",name); printf("Aria file: %s\n",name);
printf("Record format: %s\n", record_formats[share->data_file_type]); printf("Record format: %s\n", record_formats[share->data_file_type]);
printf("Crashsafe: %s\n", printf("Crashsafe: %s\n",
share->base.born_transactional ? "yes" : "no"); share->base.born_transactional ? "yes" : "no");

View File

@ -166,7 +166,7 @@ err:
#include "ma_check_standalone.h" #include "ma_check_standalone.h"
enum options_mc { enum options_mc {
OPT_CHARSETS_DIR=256 OPT_CHARSETS_DIR=256, OPT_FORCE_CRASH
}; };
static struct my_option my_long_options[] = static struct my_option my_long_options[] =
@ -186,6 +186,9 @@ static struct my_option my_long_options[] =
#ifndef DBUG_OFF #ifndef DBUG_OFF
{"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.", {"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"force-crash", OPT_FORCE_CRASH, "Force crash after # recovery events",
&maria_recovery_force_crash_counter, 0,0, GET_ULONG, REQUIRED_ARG,
0, 0, ~(long) 0, 0, 0, 0},
#endif #endif
{"help", '?', "Display this help and exit.", {"help", '?', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},

View File

@ -1095,7 +1095,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK); param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
/* Ensure we don't loose any rows when retrying without quick */ /* Ensure we don't loose any rows when retrying without quick */
param.testflag|= T_SAFE_REPAIR; param.testflag|= T_SAFE_REPAIR;
sql_print_information("Retrying repair of: '%s' without quick", sql_print_information("Retrying repair of: '%s' including modifying data file",
table->s->path.str); table->s->path.str);
continue; continue;
} }
@ -1697,15 +1697,15 @@ bool ha_myisam::check_and_repair(THD *thd)
if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt)) if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
{ {
sql_print_warning("Recovering table: '%s'",table->s->path.str); sql_print_warning("Recovering table: '%s'",table->s->path.str);
if (myisam_recover_options & (HA_RECOVER_FULL_BACKUP | HA_RECOVER_BACKUP)) if (myisam_recover_options & HA_RECOVER_FULL_BACKUP)
{ {
char buff[MY_BACKUP_NAME_EXTRA_LENGTH+1]; char buff[MY_BACKUP_NAME_EXTRA_LENGTH+1];
my_create_backup_name(buff, "", check_opt.start_time); my_create_backup_name(buff, "", check_opt.start_time);
sql_print_information("Making backup of data with extension '%s'", buff); sql_print_information("Making backup of index file with extension '%s'",
} buff);
if (myisam_recover_options & HA_RECOVER_FULL_BACKUP)
mi_make_backup_of_index(file, check_opt.start_time, mi_make_backup_of_index(file, check_opt.start_time,
MYF(MY_WME | ME_JUST_WARNING)); MYF(MY_WME | ME_JUST_WARNING));
}
check_opt.flags= check_opt.flags=
(((myisam_recover_options & (((myisam_recover_options &
(HA_RECOVER_BACKUP | HA_RECOVER_FULL_BACKUP)) ? T_BACKUP_DATA : 0) | (HA_RECOVER_BACKUP | HA_RECOVER_FULL_BACKUP)) ? T_BACKUP_DATA : 0) |

View File

@ -85,6 +85,8 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks,
uint buffer_length); uint buffer_length);
static ha_checksum mi_byte_checksum(const uchar *buf, uint length); static ha_checksum mi_byte_checksum(const uchar *buf, uint length);
static void set_data_file_type(MI_SORT_INFO *sort_info, MYISAM_SHARE *share); static void set_data_file_type(MI_SORT_INFO *sort_info, MYISAM_SHARE *share);
static int replace_data_file(HA_CHECK *param, MI_INFO *info,
const char *name, File new_file);
void myisamchk_init(HA_CHECK *param) void myisamchk_init(HA_CHECK *param)
{ {
@ -1733,17 +1735,8 @@ err:
/* Replace the actual file with the temporary file */ /* Replace the actual file with the temporary file */
if (new_file >= 0) if (new_file >= 0)
{ {
my_close(new_file,MYF(0)); got_error= replace_data_file(param, info, name, new_file);
info->dfile=new_file= -1; new_file= -1;
if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
DATA_TMP_EXT,
param->backup_time,
share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info,share,name,-1))
got_error=1;
param->retry_repair= 0; param->retry_repair= 0;
} }
} }
@ -2553,15 +2546,8 @@ err:
/* Replace the actual file with the temporary file */ /* Replace the actual file with the temporary file */
if (new_file >= 0) if (new_file >= 0)
{ {
my_close(new_file,MYF(0)); got_error= replace_data_file(param, info, name, new_file);
info->dfile=new_file= -1; new_file= -1;
if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
DATA_TMP_EXT, param->backup_time,
share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info,share,name,-1))
got_error=1;
} }
} }
if (got_error) if (got_error)
@ -3092,15 +3078,8 @@ err:
/* Replace the actual file with the temporary file */ /* Replace the actual file with the temporary file */
if (new_file >= 0) if (new_file >= 0)
{ {
my_close(new_file,MYF(0)); got_error= replace_data_file(param, info, name, new_file);
info->dfile=new_file= -1; new_file= -1;
if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
DATA_TMP_EXT, param->backup_time,
share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info,share,name,-1))
got_error=1;
} }
} }
if (got_error) if (got_error)
@ -4765,3 +4744,29 @@ int mi_make_backup_of_index(MI_INFO *info, time_t backup_time, myf flags)
my_create_backup_name(backup_name, info->s->index_file_name, backup_time); my_create_backup_name(backup_name, info->s->index_file_name, backup_time);
return my_copy(info->s->index_file_name, backup_name, flags); return my_copy(info->s->index_file_name, backup_name, flags);
} }
static int replace_data_file(HA_CHECK *param, MI_INFO *info,
const char *name, File new_file)
{
MYISAM_SHARE *share=info->s;
my_close(new_file,MYF(0));
info->dfile= -1;
if (param->testflag & T_BACKUP_DATA)
{
char buff[MY_BACKUP_NAME_EXTRA_LENGTH+1];
my_create_backup_name(buff, "", param->backup_time);
my_printf_error(0, /* No error, just info */
"Making backup of data file with extension '%s'",
MYF(ME_JUST_INFO | ME_NOREFRESH), buff);
}
if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
DATA_TMP_EXT, param->backup_time,
share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
mi_open_datafile(info, share, name, -1))
return 1;
return 0;
}

View File

@ -506,44 +506,23 @@ xtPublic void xt_p_init_threading(void)
xtPublic int xt_p_set_low_priority(pthread_t thr) xtPublic int xt_p_set_low_priority(pthread_t thr)
{ {
if (pth_min_priority == pth_max_priority) { if (pth_min_priority != pth_max_priority)
/* Under Linux the priority of normal (non-runtime) return pth_set_priority(thr, pth_min_priority);
* threads are set using the standard methods return 0;
* for setting process priority.
*/
/* We could set who == 0 because it should have the same affect
* as using the PID.
*/
/* -20 = highest, 20 = lowest */
#ifdef SET_GLOBAL_PRIORITY
if (setpriority(PRIO_PROCESS, getpid(), 20) == -1)
return errno;
#endif
return 0;
}
return pth_set_priority(thr, pth_min_priority);
} }
xtPublic int xt_p_set_normal_priority(pthread_t thr) xtPublic int xt_p_set_normal_priority(pthread_t thr)
{ {
if (pth_min_priority == pth_max_priority) { if (pth_min_priority != pth_max_priority)
if (setpriority(PRIO_PROCESS, getpid(), 0) == -1) return pth_set_priority(thr, pth_normal_priority);
return errno; return 0;
return 0;
}
return pth_set_priority(thr, pth_normal_priority);
} }
xtPublic int xt_p_set_high_priority(pthread_t thr) xtPublic int xt_p_set_high_priority(pthread_t thr)
{ {
if (pth_min_priority == pth_max_priority) { if (pth_min_priority != pth_max_priority)
if (setpriority(PRIO_PROCESS, getpid(), -20) == -1) return pth_set_priority(thr, pth_max_priority);
return errno; return 0;
return 0;
}
return pth_set_priority(thr, pth_max_priority);
} }
#ifdef DEBUG_LOCKING #ifdef DEBUG_LOCKING