mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge 10.4 into 10.5
This commit is contained in:
@@ -25,21 +25,24 @@
|
|||||||
#define DBUG_ASSERT_IF_WSREP(A) DBUG_ASSERT(A)
|
#define DBUG_ASSERT_IF_WSREP(A) DBUG_ASSERT(A)
|
||||||
|
|
||||||
#define WSREP_MYSQL_DB (char *)"mysql"
|
#define WSREP_MYSQL_DB (char *)"mysql"
|
||||||
|
#define WSREP_TO_ISOLATION_BEGIN_IF(db_, table_, table_list_) \
|
||||||
|
if (WSREP_ON && WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_))
|
||||||
|
|
||||||
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \
|
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \
|
||||||
if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) \
|
if (WSREP_ON && WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) \
|
||||||
goto wsrep_error_label;
|
goto wsrep_error_label;
|
||||||
|
|
||||||
#define WSREP_TO_ISOLATION_BEGIN_CREATE(db_, table_, table_list_, create_info_) \
|
#define WSREP_TO_ISOLATION_BEGIN_CREATE(db_, table_, table_list_, create_info_) \
|
||||||
if (WSREP(thd) && \
|
if (WSREP_ON && WSREP(thd) && \
|
||||||
wsrep_to_isolation_begin(thd, db_, table_, \
|
wsrep_to_isolation_begin(thd, db_, table_, \
|
||||||
table_list_, NULL, create_info_)) \
|
table_list_, nullptr, nullptr, create_info_))\
|
||||||
goto wsrep_error_label;
|
goto wsrep_error_label;
|
||||||
|
|
||||||
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_, create_info_) \
|
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_, fk_tables_, create_info_) \
|
||||||
if (WSREP(thd) && wsrep_thd_is_local(thd) && \
|
if (WSREP(thd) && wsrep_thd_is_local(thd) && \
|
||||||
wsrep_to_isolation_begin(thd, db_, table_, \
|
wsrep_to_isolation_begin(thd, db_, table_, \
|
||||||
table_list_, alter_info_, create_info_)) \
|
table_list_, alter_info_, \
|
||||||
|
fk_tables_, create_info_)) \
|
||||||
goto wsrep_error_label;
|
goto wsrep_error_label;
|
||||||
|
|
||||||
#define WSREP_TO_ISOLATION_END \
|
#define WSREP_TO_ISOLATION_END \
|
||||||
@@ -55,6 +58,10 @@
|
|||||||
if (WSREP(thd) && !thd->lex->no_write_to_binlog \
|
if (WSREP(thd) && !thd->lex->no_write_to_binlog \
|
||||||
&& wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto wsrep_error_label;
|
&& wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto wsrep_error_label;
|
||||||
|
|
||||||
|
#define WSREP_TO_ISOLATION_BEGIN_FK_TABLES(db_, table_, table_list_, fk_tables) \
|
||||||
|
if (WSREP(thd) && !thd->lex->no_write_to_binlog \
|
||||||
|
&& wsrep_to_isolation_begin(thd, db_, table_, table_list_, NULL, fk_tables))
|
||||||
|
|
||||||
#define WSREP_SYNC_WAIT(thd_, before_) \
|
#define WSREP_SYNC_WAIT(thd_, before_) \
|
||||||
{ if (WSREP_CLIENT(thd_) && \
|
{ if (WSREP_CLIENT(thd_) && \
|
||||||
wsrep_sync_wait(thd_, before_)) goto wsrep_error_label; }
|
wsrep_sync_wait(thd_, before_)) goto wsrep_error_label; }
|
||||||
@@ -68,7 +75,8 @@
|
|||||||
#define WSREP_DEBUG(...)
|
#define WSREP_DEBUG(...)
|
||||||
#define WSREP_ERROR(...)
|
#define WSREP_ERROR(...)
|
||||||
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) do { } while(0)
|
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) do { } while(0)
|
||||||
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_, create_info_)
|
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_, fk_tables_, create_info_)
|
||||||
|
#define WSREP_TO_ISOLATION_BEGIN_FK_TABLES(db_, table_, table_list_, fk_tables_)
|
||||||
#define WSREP_TO_ISOLATION_END
|
#define WSREP_TO_ISOLATION_END
|
||||||
#define WSREP_TO_ISOLATION_BEGIN_CREATE(db_, table_, table_list_, create_info_)
|
#define WSREP_TO_ISOLATION_BEGIN_CREATE(db_, table_, table_list_, create_info_)
|
||||||
#define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, table_, table_list_)
|
#define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, table_, table_list_)
|
||||||
|
@@ -130,5 +130,42 @@ connection default;
|
|||||||
#
|
#
|
||||||
alter user user1@localhost account lock;
|
alter user user1@localhost account lock;
|
||||||
ERROR HY000: Access denied, this account is locked
|
ERROR HY000: Access denied, this account is locked
|
||||||
|
#
|
||||||
|
# MDEV-24098 SHOW CREATE USER invalid for both PASSWORD EXPIRE and
|
||||||
|
# and LOCKED
|
||||||
|
#
|
||||||
|
alter user user1@localhost PASSWORD EXPIRE;
|
||||||
|
show create user user1@localhost;
|
||||||
|
CREATE USER for user1@localhost
|
||||||
|
CREATE USER `user1`@`localhost` ACCOUNT LOCK PASSWORD EXPIRE
|
||||||
|
drop user user1@localhost;
|
||||||
|
#
|
||||||
|
# MDEV-24098 CREATE USER/ALTER USER PASSWORD EXPIRE/LOCK in
|
||||||
|
# either order.
|
||||||
|
#
|
||||||
|
create user user1@localhost PASSWORD EXPIRE ACCOUNT LOCK;
|
||||||
|
show create user user1@localhost;
|
||||||
|
CREATE USER for user1@localhost
|
||||||
|
CREATE USER `user1`@`localhost` ACCOUNT LOCK PASSWORD EXPIRE
|
||||||
|
drop user user1@localhost;
|
||||||
|
create user user1@localhost ACCOUNT LOCK PASSWORD EXPIRE;
|
||||||
|
show create user user1@localhost;
|
||||||
|
CREATE USER for user1@localhost
|
||||||
|
CREATE USER `user1`@`localhost` ACCOUNT LOCK PASSWORD EXPIRE
|
||||||
|
alter user user1@localhost PASSWORD EXPIRE NEVER ACCOUNT UNLOCK ;
|
||||||
|
show create user user1@localhost;
|
||||||
|
CREATE USER for user1@localhost
|
||||||
|
CREATE USER `user1`@`localhost` PASSWORD EXPIRE
|
||||||
|
alter user user1@localhost ACCOUNT LOCK PASSWORD EXPIRE DEFAULT;
|
||||||
|
show create user user1@localhost;
|
||||||
|
CREATE USER for user1@localhost
|
||||||
|
CREATE USER `user1`@`localhost` ACCOUNT LOCK PASSWORD EXPIRE
|
||||||
|
alter user user1@localhost PASSWORD EXPIRE INTERVAL 60 DAY ACCOUNT UNLOCK;
|
||||||
|
select * from mysql.global_priv where user='user1';
|
||||||
|
Host User Priv
|
||||||
|
localhost user1 {"access":0,"version_id":100509,"plugin":"mysql_native_password","authentication_string":"","account_locked":false,"password_last_changed":0,"password_lifetime":60}
|
||||||
|
show create user user1@localhost;
|
||||||
|
CREATE USER for user1@localhost
|
||||||
|
CREATE USER `user1`@`localhost` PASSWORD EXPIRE
|
||||||
drop user user1@localhost;
|
drop user user1@localhost;
|
||||||
drop user user2@localhost;
|
drop user user2@localhost;
|
||||||
|
@@ -137,6 +137,32 @@ alter user user1@localhost account lock;
|
|||||||
--error ER_ACCOUNT_HAS_BEEN_LOCKED
|
--error ER_ACCOUNT_HAS_BEEN_LOCKED
|
||||||
--change_user user1
|
--change_user user1
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24098 SHOW CREATE USER invalid for both PASSWORD EXPIRE and
|
||||||
|
--echo # and LOCKED
|
||||||
|
--echo #
|
||||||
|
alter user user1@localhost PASSWORD EXPIRE;
|
||||||
|
show create user user1@localhost;
|
||||||
|
drop user user1@localhost;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24098 CREATE USER/ALTER USER PASSWORD EXPIRE/LOCK in
|
||||||
|
--echo # either order.
|
||||||
|
--echo #
|
||||||
|
create user user1@localhost PASSWORD EXPIRE ACCOUNT LOCK;
|
||||||
|
show create user user1@localhost;
|
||||||
|
drop user user1@localhost;
|
||||||
|
create user user1@localhost ACCOUNT LOCK PASSWORD EXPIRE;
|
||||||
|
show create user user1@localhost;
|
||||||
|
alter user user1@localhost PASSWORD EXPIRE NEVER ACCOUNT UNLOCK ;
|
||||||
|
show create user user1@localhost;
|
||||||
|
alter user user1@localhost ACCOUNT LOCK PASSWORD EXPIRE DEFAULT;
|
||||||
|
show create user user1@localhost;
|
||||||
|
# note output needs to be corrected by MDEV-24114: password expire users cannot be unexpired
|
||||||
|
alter user user1@localhost PASSWORD EXPIRE INTERVAL 60 DAY ACCOUNT UNLOCK;
|
||||||
|
select * from mysql.global_priv where user='user1';
|
||||||
|
show create user user1@localhost;
|
||||||
|
|
||||||
drop user user1@localhost;
|
drop user user1@localhost;
|
||||||
drop user user2@localhost;
|
drop user user2@localhost;
|
||||||
|
|
||||||
|
@@ -647,6 +647,7 @@ sub run_test_server ($$$) {
|
|||||||
# Client disconnected
|
# Client disconnected
|
||||||
mtr_verbose("Child closed socket");
|
mtr_verbose("Child closed socket");
|
||||||
$s->remove($sock);
|
$s->remove($sock);
|
||||||
|
$sock->close;
|
||||||
if (--$childs == 0){
|
if (--$childs == 0){
|
||||||
return ("Completed", $test_failure, $completed, $extra_warnings);
|
return ("Completed", $test_failure, $completed, $extra_warnings);
|
||||||
}
|
}
|
||||||
@@ -816,6 +817,7 @@ sub run_test_server ($$$) {
|
|||||||
# Test failure due to warnings, force is off
|
# Test failure due to warnings, force is off
|
||||||
return ("Warnings in log", 1, $completed, $extra_warnings);
|
return ("Warnings in log", 1, $completed, $extra_warnings);
|
||||||
}
|
}
|
||||||
|
next;
|
||||||
}
|
}
|
||||||
elsif ($line =~ /^SPENT/) {
|
elsif ($line =~ /^SPENT/) {
|
||||||
add_total_times($line);
|
add_total_times($line);
|
||||||
@@ -4102,6 +4104,7 @@ sub run_testcase ($$) {
|
|||||||
if (start_servers($tinfo))
|
if (start_servers($tinfo))
|
||||||
{
|
{
|
||||||
report_failure_and_restart($tinfo);
|
report_failure_and_restart($tinfo);
|
||||||
|
unlink $path_current_testlog;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
mysql-test/suite/galera/r/MDEV-24063.result
Normal file
8
mysql-test/suite/galera/r/MDEV-24063.result
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
connection node_2;
|
||||||
|
connection node_1;
|
||||||
|
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
|
||||||
|
connection node_2a;
|
||||||
|
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
|
||||||
|
connection node_2;
|
||||||
|
SET GLOBAL wsrep_on=OFF;
|
||||||
|
DROP TABLE t1;
|
657
mysql-test/suite/galera/r/galera_ddl_fk_conflict.result
Normal file
657
mysql-test/suite/galera/r/galera_ddl_fk_conflict.result
Normal file
@@ -0,0 +1,657 @@
|
|||||||
|
connection node_2;
|
||||||
|
connection node_1;
|
||||||
|
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||||
|
connection node_1b;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
######################################################################
|
||||||
|
# Test for OPTIMIZE
|
||||||
|
######################################################################
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #1: DML working on FK parent table BF aborted by DDL
|
||||||
|
# over child table
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p2 VALUES (1, 'INITIAL VALUE');
|
||||||
|
INSERT INTO p2 VALUES (2, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
|
||||||
|
INSERT INTO c1 VALUES (1,1);
|
||||||
|
CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk));
|
||||||
|
INSERT INTO c2 VALUES (1,1,1), (2,1,2);
|
||||||
|
connection node_1;
|
||||||
|
SET AUTOCOMMIT=ON;
|
||||||
|
START TRANSACTION;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
connection node_2;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
OPTIMIZE TABLE c1 ;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.c1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||||
|
test.c1 optimize status OK
|
||||||
|
connection node_1;
|
||||||
|
COMMIT;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #2: DML working on FK parent table tries to replicate, but
|
||||||
|
# fails in certification for earlier DDL on child table
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
OPTIMIZE TABLE c1 ;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.c1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||||
|
test.c1 optimize status OK
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #3: 2 DMLs working on two FK parent tables try to replicate,
|
||||||
|
# but fails in certification for earlier DDL on child table
|
||||||
|
# which is child to both FK parents
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
connection node_1b;
|
||||||
|
BEGIN;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
OPTIMIZE TABLE c2 ;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.c2 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||||
|
test.c2 optimize status OK
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1b;
|
||||||
|
UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
connection node_1b;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
DROP TABLE c1, c2;
|
||||||
|
DROP TABLE p1, p2;
|
||||||
|
######################################################################
|
||||||
|
# Test for OPTIMIZE
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
|
||||||
|
INSERT INTO c1 VALUES (1,1);
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #4: DML working on FK parent table tries to replicate, but
|
||||||
|
# fails in certification for earlier DDL on child table
|
||||||
|
# and another temporary table. TMP table should be skipped
|
||||||
|
# but FK child table should be replicated with proper keys
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
CREATE TEMPORARY TABLE tmp (i int);
|
||||||
|
OPTIMIZE TABLE c1, tmp ;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.c1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||||
|
test.c1 optimize status OK
|
||||||
|
test.tmp optimize note Table does not support optimize, doing recreate + analyze instead
|
||||||
|
test.tmp optimize status OK
|
||||||
|
DROP TABLE tmp;
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
DROP TABLE c1;
|
||||||
|
DROP TABLE p1;
|
||||||
|
######################################################################
|
||||||
|
# Test for REPAIR
|
||||||
|
######################################################################
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #1: DML working on FK parent table BF aborted by DDL
|
||||||
|
# over child table
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p2 VALUES (1, 'INITIAL VALUE');
|
||||||
|
INSERT INTO p2 VALUES (2, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
|
||||||
|
INSERT INTO c1 VALUES (1,1);
|
||||||
|
CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk));
|
||||||
|
INSERT INTO c2 VALUES (1,1,1), (2,1,2);
|
||||||
|
connection node_1;
|
||||||
|
SET AUTOCOMMIT=ON;
|
||||||
|
START TRANSACTION;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
connection node_2;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
REPAIR TABLE c1 ;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.c1 repair note The storage engine for the table doesn't support repair
|
||||||
|
connection node_1;
|
||||||
|
COMMIT;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #2: DML working on FK parent table tries to replicate, but
|
||||||
|
# fails in certification for earlier DDL on child table
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
REPAIR TABLE c1 ;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.c1 repair note The storage engine for the table doesn't support repair
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #3: 2 DMLs working on two FK parent tables try to replicate,
|
||||||
|
# but fails in certification for earlier DDL on child table
|
||||||
|
# which is child to both FK parents
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
connection node_1b;
|
||||||
|
BEGIN;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
REPAIR TABLE c2 ;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.c2 repair note The storage engine for the table doesn't support repair
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1b;
|
||||||
|
UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
connection node_1b;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
DROP TABLE c1, c2;
|
||||||
|
DROP TABLE p1, p2;
|
||||||
|
######################################################################
|
||||||
|
# Test for REPAIR
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
|
||||||
|
INSERT INTO c1 VALUES (1,1);
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #4: DML working on FK parent table tries to replicate, but
|
||||||
|
# fails in certification for earlier DDL on child table
|
||||||
|
# and another temporary table. TMP table should be skipped
|
||||||
|
# but FK child table should be replicated with proper keys
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
CREATE TEMPORARY TABLE tmp (i int);
|
||||||
|
REPAIR TABLE c1, tmp ;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.c1 repair note The storage engine for the table doesn't support repair
|
||||||
|
test.tmp repair note The storage engine for the table doesn't support repair
|
||||||
|
DROP TABLE tmp;
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
DROP TABLE c1;
|
||||||
|
DROP TABLE p1;
|
||||||
|
######################################################################
|
||||||
|
# Test for ALTER ENGINE=INNODB
|
||||||
|
######################################################################
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #1: DML working on FK parent table BF aborted by DDL
|
||||||
|
# over child table
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p2 VALUES (1, 'INITIAL VALUE');
|
||||||
|
INSERT INTO p2 VALUES (2, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
|
||||||
|
INSERT INTO c1 VALUES (1,1);
|
||||||
|
CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk));
|
||||||
|
INSERT INTO c2 VALUES (1,1,1), (2,1,2);
|
||||||
|
connection node_1;
|
||||||
|
SET AUTOCOMMIT=ON;
|
||||||
|
START TRANSACTION;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
connection node_2;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
ALTER TABLE c1 ENGINE=INNODB;
|
||||||
|
connection node_1;
|
||||||
|
COMMIT;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #2: DML working on FK parent table tries to replicate, but
|
||||||
|
# fails in certification for earlier DDL on child table
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
ALTER TABLE c1 ENGINE=INNODB;
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #3: 2 DMLs working on two FK parent tables try to replicate,
|
||||||
|
# but fails in certification for earlier DDL on child table
|
||||||
|
# which is child to both FK parents
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
connection node_1b;
|
||||||
|
BEGIN;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
ALTER TABLE c2 ENGINE=INNODB;
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1b;
|
||||||
|
UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
connection node_1b;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
DROP TABLE c1, c2;
|
||||||
|
DROP TABLE p1, p2;
|
||||||
|
######################################################################
|
||||||
|
# Test for TRUNCATE
|
||||||
|
######################################################################
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #1: DML working on FK parent table BF aborted by DDL
|
||||||
|
# over child table
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p2 VALUES (1, 'INITIAL VALUE');
|
||||||
|
INSERT INTO p2 VALUES (2, 'INITIAL VALUE');
|
||||||
|
CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
|
||||||
|
INSERT INTO c1 VALUES (1,1);
|
||||||
|
CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk));
|
||||||
|
INSERT INTO c2 VALUES (1,1,1), (2,1,2);
|
||||||
|
connection node_1;
|
||||||
|
SET AUTOCOMMIT=ON;
|
||||||
|
START TRANSACTION;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
connection node_2;
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
TRUNCATE TABLE c1 ;
|
||||||
|
connection node_1;
|
||||||
|
COMMIT;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #2: DML working on FK parent table tries to replicate, but
|
||||||
|
# fails in certification for earlier DDL on child table
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
TRUNCATE TABLE c1 ;
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Scenario #3: 2 DMLs working on two FK parent tables try to replicate,
|
||||||
|
# but fails in certification for earlier DDL on child table
|
||||||
|
# which is child to both FK parents
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
connection node_1;
|
||||||
|
BEGIN;
|
||||||
|
connection node_1b;
|
||||||
|
BEGIN;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||||
|
connection node_2;
|
||||||
|
TRUNCATE TABLE c2 ;
|
||||||
|
connection node_1a;
|
||||||
|
SET SESSION wsrep_on = 0;
|
||||||
|
SET SESSION wsrep_on = 1;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||||
|
connection node_1;
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1b;
|
||||||
|
UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2;
|
||||||
|
COMMIT;
|
||||||
|
connection node_1a;
|
||||||
|
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||||
|
connection node_1;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
connection node_1b;
|
||||||
|
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
I deadlocked
|
||||||
|
I deadlocked
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
connection node_2;
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_1
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
EXPECT_2
|
||||||
|
2
|
||||||
|
DROP TABLE c1, c2;
|
||||||
|
DROP TABLE p1, p2;
|
@@ -45,34 +45,34 @@ connection node_2;
|
|||||||
set session wsrep_sync_wait=15;
|
set session wsrep_sync_wait=15;
|
||||||
insert into t1(value) values (3);
|
insert into t1(value) values (3);
|
||||||
insert into t1(value) values (4);
|
insert into t1(value) values (4);
|
||||||
select * from t2;
|
select tbl, action from t2;
|
||||||
id tbl action
|
tbl action
|
||||||
1 t1 INSERT
|
t1 INSERT
|
||||||
3 t1 INSERT
|
t1 INSERT
|
||||||
4 t1 INSERT
|
t1 INSERT
|
||||||
6 t1 INSERT
|
t1 INSERT
|
||||||
connection node_1;
|
connection node_1;
|
||||||
drop trigger if exists log_insert;
|
drop trigger if exists log_insert;
|
||||||
insert into t1(value) values (5);
|
insert into t1(value) values (5);
|
||||||
select * from t2;
|
select tbl, action from t2;
|
||||||
id tbl action
|
tbl action
|
||||||
1 t1 INSERT
|
t1 INSERT
|
||||||
3 t1 INSERT
|
t1 INSERT
|
||||||
4 t1 INSERT
|
t1 INSERT
|
||||||
6 t1 INSERT
|
t1 INSERT
|
||||||
connection node_2;
|
connection node_2;
|
||||||
insert into t1(value) values (6);
|
insert into t1(value) values (6);
|
||||||
select * from t2;
|
select tbl, action from t2;
|
||||||
id tbl action
|
tbl action
|
||||||
1 t1 INSERT
|
t1 INSERT
|
||||||
3 t1 INSERT
|
t1 INSERT
|
||||||
4 t1 INSERT
|
t1 INSERT
|
||||||
6 t1 INSERT
|
t1 INSERT
|
||||||
connection node_1;
|
connection node_1;
|
||||||
select * from t2;
|
select tbl, action from t2;
|
||||||
id tbl action
|
tbl action
|
||||||
1 t1 INSERT
|
t1 INSERT
|
||||||
3 t1 INSERT
|
t1 INSERT
|
||||||
4 t1 INSERT
|
t1 INSERT
|
||||||
6 t1 INSERT
|
t1 INSERT
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
20
mysql-test/suite/galera/t/MDEV-24063.test
Normal file
20
mysql-test/suite/galera/t/MDEV-24063.test
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#
|
||||||
|
# MDEV-24063
|
||||||
|
#
|
||||||
|
# my_bool wsrep_thd_is_aborting(const THD*):
|
||||||
|
# Assertion `((&(&thd->LOCK_thd_data)->m_mutex)->count > 0 &&
|
||||||
|
# pthread_equal(pthread_self(), (&(&thd->LOCK_thd_data)->m_mutex)->thread))' failed.
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/galera_cluster.inc
|
||||||
|
|
||||||
|
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
|
||||||
|
--connection node_2a
|
||||||
|
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
SET GLOBAL wsrep_on=OFF;
|
||||||
|
--source include/shutdown_mysqld.inc
|
||||||
|
--source include/start_mysqld.inc
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
192
mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc
Normal file
192
mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
#
|
||||||
|
# Test for MDL BF-BF lock conflict
|
||||||
|
# There are some DDL statements, which take extensive MDL lock for
|
||||||
|
# a table referenced by foreign key constraint from the actual affetec table.
|
||||||
|
# This extensive MDL lock may cause MDL BF-BF confclict situations, if the
|
||||||
|
# FK parent table is not listed as certification key in the replication write set.
|
||||||
|
# i.e. if replication allows such DDL to apply in parallel with regular DML operating
|
||||||
|
# on the FK parent table.
|
||||||
|
#
|
||||||
|
# This test has two scenarios, where DML modifies FK parent table in node 1,
|
||||||
|
# and offending DDL for FK child table is sent from node 2.
|
||||||
|
#
|
||||||
|
# param: $table_admin_command
|
||||||
|
# DDL table command to test, script will build full SQL statement:
|
||||||
|
# $table_admin_command TABLE c;
|
||||||
|
#
|
||||||
|
# param: $table_admin_command_end
|
||||||
|
# Optional additional SQL syntax to end the SQL statement, if any
|
||||||
|
# $table_admin_command TABLE c $table_admin_command_end;
|
||||||
|
#
|
||||||
|
# scenario 1, can be used to test if a DDL statement causes such MDL locking vulnerability.
|
||||||
|
# call this test script with some table DDL command in $table_admin_command
|
||||||
|
# if scenario 1 passes (especially COMMIT does fail for ER_LOCK_DEADLOCK),
|
||||||
|
# then this particular DDL is vulnerable. scenraio 2 should fail for this DDL
|
||||||
|
# unless code has not been fixed to append parent table certification keys for it.
|
||||||
|
#
|
||||||
|
|
||||||
|
--echo ######################################################################
|
||||||
|
--echo # Test for $table_admin_command $table_admin_command_end
|
||||||
|
--echo ######################################################################
|
||||||
|
|
||||||
|
|
||||||
|
--echo ######################################################################
|
||||||
|
--echo #
|
||||||
|
--echo # Scenario #1: DML working on FK parent table BF aborted by DDL
|
||||||
|
--echo # over child table
|
||||||
|
--echo #
|
||||||
|
--echo ######################################################################
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
|
||||||
|
CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p2 VALUES (1, 'INITIAL VALUE');
|
||||||
|
INSERT INTO p2 VALUES (2, 'INITIAL VALUE');
|
||||||
|
|
||||||
|
CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
|
||||||
|
INSERT INTO c1 VALUES (1,1);
|
||||||
|
|
||||||
|
CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk));
|
||||||
|
INSERT INTO c2 VALUES (1,1,1), (2,1,2);
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
SET AUTOCOMMIT=ON;
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
# wait for tables to be created in node 2 and all rows inserted as well
|
||||||
|
--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/c%'
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
--let $wait_condition = SELECT COUNT(*) = 2 FROM c2
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
# replicate the DDL to be tested
|
||||||
|
--eval $table_admin_command TABLE c1 $table_admin_command_end
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
--error ER_LOCK_DEADLOCK
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
|
||||||
|
--echo ######################################################################
|
||||||
|
--echo #
|
||||||
|
--echo # Scenario #2: DML working on FK parent table tries to replicate, but
|
||||||
|
--echo # fails in certification for earlier DDL on child table
|
||||||
|
--echo #
|
||||||
|
--echo ######################################################################
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
# Block the applier on node #1 and issue DDL on node 2
|
||||||
|
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||||
|
--source include/galera_set_sync_point.inc
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
--eval $table_admin_command TABLE c1 $table_admin_command_end
|
||||||
|
|
||||||
|
--connection node_1a
|
||||||
|
--source include/galera_wait_sync_point.inc
|
||||||
|
--source include/galera_clear_sync_point.inc
|
||||||
|
--let $expected_cert_failures = `SELECT VARIABLE_VALUE+1 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'`
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
--send COMMIT
|
||||||
|
|
||||||
|
--connection node_1a
|
||||||
|
--let $wait_condition = SELECT VARIABLE_VALUE = $expected_cert_failures FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||||
|
--source include/galera_signal_sync_point.inc
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
--error ER_LOCK_DEADLOCK
|
||||||
|
--reap
|
||||||
|
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
|
||||||
|
|
||||||
|
--echo ######################################################################
|
||||||
|
--echo #
|
||||||
|
--echo # Scenario #3: 2 DMLs working on two FK parent tables try to replicate,
|
||||||
|
--echo # but fails in certification for earlier DDL on child table
|
||||||
|
--echo # which is child to both FK parents
|
||||||
|
--echo #
|
||||||
|
--echo ######################################################################
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
--connection node_1b
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
--connection node_1a
|
||||||
|
# Block the applier on node #1 and issue DDL on node 2
|
||||||
|
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||||
|
--source include/galera_set_sync_point.inc
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
--eval $table_admin_command TABLE c2 $table_admin_command_end
|
||||||
|
|
||||||
|
--connection node_1a
|
||||||
|
--source include/galera_wait_sync_point.inc
|
||||||
|
--source include/galera_clear_sync_point.inc
|
||||||
|
--let $expected_cert_failures = `SELECT VARIABLE_VALUE+2 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'`
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
--send COMMIT
|
||||||
|
|
||||||
|
--connection node_1b
|
||||||
|
UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2;
|
||||||
|
--send COMMIT
|
||||||
|
|
||||||
|
--connection node_1a
|
||||||
|
--let $wait_condition = SELECT VARIABLE_VALUE = $expected_cert_failures FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||||
|
--source include/galera_signal_sync_point.inc
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
--error ER_LOCK_DEADLOCK
|
||||||
|
--reap
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
|
||||||
|
--connection node_1b
|
||||||
|
--error ER_LOCK_DEADLOCK
|
||||||
|
--reap
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
|
||||||
|
DROP TABLE c1, c2;
|
||||||
|
DROP TABLE p1, p2;
|
37
mysql-test/suite/galera/t/galera_ddl_fk_conflict.test
Normal file
37
mysql-test/suite/galera/t/galera_ddl_fk_conflict.test
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#
|
||||||
|
# MDL BF-BF lock conflict
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/galera_cluster.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_debug_sync.inc
|
||||||
|
--source include/galera_have_debug_sync.inc
|
||||||
|
|
||||||
|
# sync point controlling session
|
||||||
|
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||||
|
--connection node_1a
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
|
||||||
|
# secondary conflicting DML victim session
|
||||||
|
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||||
|
--connection node_1b
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
|
||||||
|
--let $table_admin_command = OPTIMIZE
|
||||||
|
--source galera_ddl_fk_conflict.inc
|
||||||
|
--source galera_ddl_fk_conflict_with_tmp.inc
|
||||||
|
|
||||||
|
--let $table_admin_command = REPAIR
|
||||||
|
--source galera_ddl_fk_conflict.inc
|
||||||
|
--source galera_ddl_fk_conflict_with_tmp.inc
|
||||||
|
|
||||||
|
--let $table_admin_command = ALTER
|
||||||
|
--let $table_admin_command_end = ENGINE=INNODB
|
||||||
|
--source galera_ddl_fk_conflict.inc
|
||||||
|
|
||||||
|
--let $table_admin_command = TRUNCATE
|
||||||
|
--let $table_admin_command_end =
|
||||||
|
--source galera_ddl_fk_conflict.inc
|
||||||
|
|
||||||
|
# CHECK and ANALYZE are not affected
|
||||||
|
|
@@ -0,0 +1,69 @@
|
|||||||
|
--echo ######################################################################
|
||||||
|
--echo # Test for $table_admin_command $table_admin_command_end
|
||||||
|
--echo ######################################################################
|
||||||
|
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
|
||||||
|
CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
|
||||||
|
INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
|
||||||
|
INSERT INTO c1 VALUES (1,1);
|
||||||
|
|
||||||
|
--echo ######################################################################
|
||||||
|
--echo #
|
||||||
|
--echo # Scenario #4: DML working on FK parent table tries to replicate, but
|
||||||
|
--echo # fails in certification for earlier DDL on child table
|
||||||
|
--echo # and another temporary table. TMP table should be skipped
|
||||||
|
--echo # but FK child table should be replicated with proper keys
|
||||||
|
--echo #
|
||||||
|
--echo ######################################################################
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
# Block the applier on node #1 and issue DDL on node 2
|
||||||
|
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||||
|
--source include/galera_set_sync_point.inc
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
# wait for tables to be created in node 2 and all rows inserted as well
|
||||||
|
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/c1'
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
--let $wait_condition = SELECT COUNT(*) = 1 FROM c1
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
CREATE TEMPORARY TABLE tmp (i int);
|
||||||
|
--eval $table_admin_command TABLE c1, tmp $table_admin_command_end
|
||||||
|
DROP TABLE tmp;
|
||||||
|
|
||||||
|
--connection node_1a
|
||||||
|
--source include/galera_wait_sync_point.inc
|
||||||
|
--source include/galera_clear_sync_point.inc
|
||||||
|
--let $expected_cert_failures = `SELECT VARIABLE_VALUE+1 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'`
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
|
||||||
|
--send COMMIT
|
||||||
|
|
||||||
|
--connection node_1a
|
||||||
|
--let $wait_condition = SELECT VARIABLE_VALUE = $expected_cert_failures FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||||
|
--source include/galera_signal_sync_point.inc
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
--error ER_LOCK_DEADLOCK
|
||||||
|
--reap
|
||||||
|
|
||||||
|
SELECT 'I deadlocked';
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
|
||||||
|
|
||||||
|
DROP TABLE c1;
|
||||||
|
DROP TABLE p1;
|
@@ -55,18 +55,18 @@ insert into t1(value) values (2);
|
|||||||
set session wsrep_sync_wait=15;
|
set session wsrep_sync_wait=15;
|
||||||
insert into t1(value) values (3);
|
insert into t1(value) values (3);
|
||||||
insert into t1(value) values (4);
|
insert into t1(value) values (4);
|
||||||
select * from t2;
|
select tbl, action from t2;
|
||||||
|
|
||||||
--connection node_1
|
--connection node_1
|
||||||
drop trigger if exists log_insert;
|
drop trigger if exists log_insert;
|
||||||
insert into t1(value) values (5);
|
insert into t1(value) values (5);
|
||||||
select * from t2;
|
select tbl, action from t2;
|
||||||
|
|
||||||
--connection node_2
|
--connection node_2
|
||||||
insert into t1(value) values (6);
|
insert into t1(value) values (6);
|
||||||
select * from t2;
|
select tbl, action from t2;
|
||||||
|
|
||||||
--connection node_1
|
--connection node_1
|
||||||
select * from t2;
|
select tbl, action from t2;
|
||||||
|
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
--log-bin
|
|
9
mysql-test/suite/galera/t/mysql-wsrep#198.cnf
Normal file
9
mysql-test/suite/galera/t/mysql-wsrep#198.cnf
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
!include ../galera_2nodes.cnf
|
||||||
|
|
||||||
|
[mysqld.1]
|
||||||
|
log-bin
|
||||||
|
wsrep-debug=1
|
||||||
|
|
||||||
|
[mysqld.1]
|
||||||
|
log-bin
|
||||||
|
wsrep-debug=1
|
@@ -1,5 +1,6 @@
|
|||||||
--source include/galera_cluster.inc
|
--source include/galera_cluster.inc
|
||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
--source include/force_restart.inc
|
||||||
|
|
||||||
CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB;
|
CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
CREATE TABLE t2 (id INT PRIMARY KEY) ENGINE=InnoDB;
|
CREATE TABLE t2 (id INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
@@ -22,3 +22,19 @@ i
|
|||||||
1
|
1
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-23824 SIGSEGV in end_io_cache on REPAIR LOCAL TABLE for Aria table
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (i INT) ENGINE=Aria;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
SET max_session_mem_used=50000;
|
||||||
|
REPAIR LOCAL TABLE t1 USE_FRM;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
t1 repair error Failed to open partially repaired table
|
||||||
|
Warnings:
|
||||||
|
Error 1290 The MariaDB server is running with the --max-thread-mem-used=50000 option so it cannot execute this statement
|
||||||
|
REPAIR LOCAL TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair Error The MariaDB server is running with the --max-thread-mem-used=50000 option so it cannot execute this statement
|
||||||
|
test.t1 repair error Corrupt
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -22,3 +22,14 @@ SELECT * FROM INFORMATION_SCHEMA.TABLES;
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-23824 SIGSEGV in end_io_cache on REPAIR LOCAL TABLE for Aria table
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT) ENGINE=Aria;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
SET max_session_mem_used=50000;
|
||||||
|
REPAIR LOCAL TABLE t1 USE_FRM;
|
||||||
|
REPAIR LOCAL TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -16,7 +16,6 @@ wait/synch/sxlock/innodb/dict_operation_lock
|
|||||||
wait/synch/sxlock/innodb/fil_space_latch
|
wait/synch/sxlock/innodb/fil_space_latch
|
||||||
wait/synch/sxlock/innodb/fts_cache_init_rw_lock
|
wait/synch/sxlock/innodb/fts_cache_init_rw_lock
|
||||||
wait/synch/sxlock/innodb/fts_cache_rw_lock
|
wait/synch/sxlock/innodb/fts_cache_rw_lock
|
||||||
wait/synch/sxlock/innodb/index_online_log
|
|
||||||
wait/synch/sxlock/innodb/index_tree_rw_lock
|
wait/synch/sxlock/innodb/index_tree_rw_lock
|
||||||
wait/synch/sxlock/innodb/trx_i_s_cache_lock
|
wait/synch/sxlock/innodb/trx_i_s_cache_lock
|
||||||
wait/synch/sxlock/innodb/trx_purge_latch
|
wait/synch/sxlock/innodb/trx_purge_latch
|
||||||
|
@@ -45,6 +45,10 @@ ERROR 42000: Incorrect column specifier for column 's'
|
|||||||
create or replace table t (id int primary key, s date, e date,
|
create or replace table t (id int primary key, s date, e date,
|
||||||
period for mytime(s,x));
|
period for mytime(s,x));
|
||||||
ERROR 42S22: Unknown column 'x' in 'mytime'
|
ERROR 42S22: Unknown column 'x' in 'mytime'
|
||||||
|
# MDEV-18842: Unfortunate error message when the same column is used
|
||||||
|
# for application period start and end
|
||||||
|
create or replace table t (s date, t date, period for apt(s,s));
|
||||||
|
ERROR 42000: Column 's' specified twice
|
||||||
create or replace table t (id int primary key, s date, e date,
|
create or replace table t (id int primary key, s date, e date,
|
||||||
period for mytime(s,e),
|
period for mytime(s,e),
|
||||||
period for mytime2(s,e));
|
period for mytime2(s,e));
|
||||||
|
@@ -31,6 +31,12 @@ create or replace table t (id int primary key, s time, e time,
|
|||||||
--error ER_BAD_FIELD_ERROR
|
--error ER_BAD_FIELD_ERROR
|
||||||
create or replace table t (id int primary key, s date, e date,
|
create or replace table t (id int primary key, s date, e date,
|
||||||
period for mytime(s,x));
|
period for mytime(s,x));
|
||||||
|
|
||||||
|
--echo # MDEV-18842: Unfortunate error message when the same column is used
|
||||||
|
--echo # for application period start and end
|
||||||
|
--error ER_FIELD_SPECIFIED_TWICE
|
||||||
|
create or replace table t (s date, t date, period for apt(s,s));
|
||||||
|
|
||||||
--error ER_MORE_THAN_ONE_PERIOD
|
--error ER_MORE_THAN_ONE_PERIOD
|
||||||
create or replace table t (id int primary key, s date, e date,
|
create or replace table t (id int primary key, s date, e date,
|
||||||
period for mytime(s,e),
|
period for mytime(s,e),
|
||||||
|
@@ -22,7 +22,7 @@ START SLAVE IO_THREAD;
|
|||||||
include/wait_for_slave_io_error.inc [errno=1236]
|
include/wait_for_slave_io_error.inc [errno=1236]
|
||||||
connection master;
|
connection master;
|
||||||
FLUSH BINARY LOGS;
|
FLUSH BINARY LOGS;
|
||||||
PURGE BINARY LOGS TO 'master-bin.000002';;
|
include/wait_for_purge.inc "master-bin.000002"
|
||||||
FLUSH BINARY LOGS DELETE_DOMAIN_ID=(11);
|
FLUSH BINARY LOGS DELETE_DOMAIN_ID=(11);
|
||||||
SELECT @@global.gtid_binlog_pos, @@global.gtid_binlog_state;
|
SELECT @@global.gtid_binlog_pos, @@global.gtid_binlog_state;
|
||||||
@@global.gtid_binlog_pos @@global.gtid_binlog_state
|
@@global.gtid_binlog_pos @@global.gtid_binlog_state
|
||||||
|
@@ -53,17 +53,11 @@ START SLAVE IO_THREAD;
|
|||||||
# adjust the master binlog state
|
# adjust the master binlog state
|
||||||
FLUSH BINARY LOGS;
|
FLUSH BINARY LOGS;
|
||||||
--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
|
--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
|
||||||
--eval PURGE BINARY LOGS TO '$purge_to_binlog';
|
--let $purge_binlogs_to=$purge_to_binlog
|
||||||
|
--source include/wait_for_purge.inc
|
||||||
|
|
||||||
# with final removal of the extra domain
|
# with final removal of the extra domain
|
||||||
###adding to debug info to catch the failure (1076):
|
|
||||||
--error 0,1076
|
|
||||||
--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID=($extra_domain_id)
|
--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID=($extra_domain_id)
|
||||||
|
|
||||||
if ($mysql_errno == 1076) {
|
|
||||||
--echo ### Failure "Could not delete gtid domain"
|
|
||||||
--source include/show_rpl_debug_info.inc
|
|
||||||
}
|
|
||||||
|
|
||||||
SELECT @@global.gtid_binlog_pos, @@global.gtid_binlog_state;
|
SELECT @@global.gtid_binlog_pos, @@global.gtid_binlog_state;
|
||||||
|
|
||||||
--connection slave
|
--connection slave
|
||||||
|
@@ -449,7 +449,8 @@ mysqld_ld_preload_text() {
|
|||||||
set_malloc_lib() {
|
set_malloc_lib() {
|
||||||
malloc_lib="$1"
|
malloc_lib="$1"
|
||||||
if expr "$malloc_lib" : "\(tcmalloc\|jemalloc\)" > /dev/null ; then
|
if expr "$malloc_lib" : "\(tcmalloc\|jemalloc\)" > /dev/null ; then
|
||||||
if ! my_which ldconfig > /dev/null 2>&1
|
export PATH=$PATH:/sbin
|
||||||
|
if ! command -v ldconfig > /dev/null 2>&1
|
||||||
then
|
then
|
||||||
log_error "ldconfig command not found, required for ldconfig -p"
|
log_error "ldconfig command not found, required for ldconfig -p"
|
||||||
exit 1
|
exit 1
|
||||||
|
@@ -728,7 +728,7 @@ public:
|
|||||||
{
|
{
|
||||||
bytes_written = 0;
|
bytes_written = 0;
|
||||||
}
|
}
|
||||||
void harvest_bytes_written(ulonglong* counter)
|
void harvest_bytes_written(Atomic_counter<uint64> *counter)
|
||||||
{
|
{
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
char buf1[22],buf2[22];
|
char buf1[22],buf2[22];
|
||||||
|
@@ -461,7 +461,7 @@ static inline int add_relay_log(Relay_log_info* rli,LOG_INFO* linfo)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
rli->log_space_total += s.st_size;
|
rli->log_space_total += s.st_size;
|
||||||
DBUG_PRINT("info",("log_space_total: %llu", rli->log_space_total));
|
DBUG_PRINT("info",("log_space_total: %llu", uint64(rli->log_space_total)));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1254,7 +1254,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
|
|||||||
mysql_mutex_unlock(rli->relay_log.get_log_lock());
|
mysql_mutex_unlock(rli->relay_log.get_log_lock());
|
||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
DBUG_PRINT("info",("log_space_total: %llu",rli->log_space_total));
|
DBUG_PRINT("info",("log_space_total: %llu", uint64(rli->log_space_total)));
|
||||||
mysql_mutex_unlock(&rli->data_lock);
|
mysql_mutex_unlock(&rli->data_lock);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
@@ -240,7 +240,8 @@ public:
|
|||||||
threads, the SQL thread sets it to unblock the I/O thread and make it
|
threads, the SQL thread sets it to unblock the I/O thread and make it
|
||||||
temporarily forget about the constraint.
|
temporarily forget about the constraint.
|
||||||
*/
|
*/
|
||||||
ulonglong log_space_limit,log_space_total;
|
ulonglong log_space_limit;
|
||||||
|
Atomic_counter<uint64> log_space_total;
|
||||||
bool ignore_log_space_limit;
|
bool ignore_log_space_limit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -2819,7 +2819,7 @@ static bool wait_for_relay_log_space(Relay_log_info* rli)
|
|||||||
DBUG_PRINT("info", ("log_space_limit=%llu log_space_total=%llu "
|
DBUG_PRINT("info", ("log_space_limit=%llu log_space_total=%llu "
|
||||||
"ignore_log_space_limit=%d "
|
"ignore_log_space_limit=%d "
|
||||||
"sql_force_rotate_relay=%d",
|
"sql_force_rotate_relay=%d",
|
||||||
rli->log_space_limit, rli->log_space_total,
|
rli->log_space_limit, uint64(rli->log_space_total),
|
||||||
(int) rli->ignore_log_space_limit,
|
(int) rli->ignore_log_space_limit,
|
||||||
(int) rli->sql_force_rotate_relay));
|
(int) rli->sql_force_rotate_relay));
|
||||||
}
|
}
|
||||||
@@ -5085,7 +5085,7 @@ Stopping slave I/O thread due to out-of-memory error from master");
|
|||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("log_space_limit=%llu log_space_total=%llu "
|
DBUG_PRINT("info", ("log_space_limit=%llu log_space_total=%llu "
|
||||||
"ignore_log_space_limit=%d",
|
"ignore_log_space_limit=%d",
|
||||||
rli->log_space_limit, rli->log_space_total,
|
rli->log_space_limit, uint64(rli->log_space_total),
|
||||||
(int) rli->ignore_log_space_limit));
|
(int) rli->ignore_log_space_limit));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -9087,6 +9087,9 @@ bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
|
|||||||
append_identifier(thd, &result, username, strlen(username));
|
append_identifier(thd, &result, username, strlen(username));
|
||||||
add_user_parameters(thd, &result, acl_user, false);
|
add_user_parameters(thd, &result, acl_user, false);
|
||||||
|
|
||||||
|
if (acl_user->account_locked)
|
||||||
|
result.append(STRING_WITH_LEN(" ACCOUNT LOCK"));
|
||||||
|
|
||||||
if (acl_user->password_expired)
|
if (acl_user->password_expired)
|
||||||
result.append(STRING_WITH_LEN(" PASSWORD EXPIRE"));
|
result.append(STRING_WITH_LEN(" PASSWORD EXPIRE"));
|
||||||
else if (!acl_user->password_lifetime)
|
else if (!acl_user->password_lifetime)
|
||||||
@@ -9098,9 +9101,6 @@ bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
|
|||||||
result.append(STRING_WITH_LEN(" DAY"));
|
result.append(STRING_WITH_LEN(" DAY"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acl_user->account_locked)
|
|
||||||
result.append(STRING_WITH_LEN(" ACCOUNT LOCK"));
|
|
||||||
|
|
||||||
protocol->prepare_for_resend();
|
protocol->prepare_for_resend();
|
||||||
protocol->store(result.ptr(), result.length(), result.charset());
|
protocol->store(result.ptr(), result.length(), result.charset());
|
||||||
if (protocol->write())
|
if (protocol->write())
|
||||||
|
104
sql/sql_admin.cc
104
sql/sql_admin.cc
@@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates.
|
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2011, 2019, MariaDB
|
Copyright (c) 2011, 2020, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
#include "strfunc.h"
|
#include "strfunc.h"
|
||||||
#include "sql_admin.h"
|
#include "sql_admin.h"
|
||||||
#include "sql_statistics.h"
|
#include "sql_statistics.h"
|
||||||
|
#include "wsrep_mysqld.h"
|
||||||
/* Prepare, run and cleanup for mysql_recreate_table() */
|
/* Prepare, run and cleanup for mysql_recreate_table() */
|
||||||
|
|
||||||
static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
|
static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
|
||||||
@@ -90,10 +90,10 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table,
|
|||||||
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||||
HA_CHECK_OPT *check_opt)
|
HA_CHECK_OPT *check_opt)
|
||||||
{
|
{
|
||||||
int error= 0;
|
int error= 0, create_error= 0;
|
||||||
TABLE tmp_table, *table;
|
TABLE tmp_table, *table;
|
||||||
TABLE_LIST *pos_in_locked_tables= 0;
|
TABLE_LIST *pos_in_locked_tables= 0;
|
||||||
TABLE_SHARE *share;
|
TABLE_SHARE *share= 0;
|
||||||
bool has_mdl_lock= FALSE;
|
bool has_mdl_lock= FALSE;
|
||||||
char from[FN_REFLEN],tmp[FN_REFLEN+32];
|
char from[FN_REFLEN],tmp[FN_REFLEN+32];
|
||||||
const char **ext;
|
const char **ext;
|
||||||
@@ -206,6 +206,17 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
|||||||
HA_EXTRA_NOT_USED, NULL);
|
HA_EXTRA_NOT_USED, NULL);
|
||||||
table_list->table= 0;
|
table_list->table= 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Table open failed, maybe because we run out of memory.
|
||||||
|
Close all open tables and relaese all MDL locks
|
||||||
|
*/
|
||||||
|
tdc_release_share(share);
|
||||||
|
share->tdc->flush(thd, true);
|
||||||
|
share= 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
After this point we have an exclusive metadata lock on our table
|
After this point we have an exclusive metadata lock on our table
|
||||||
in both cases when table was successfully open in mysql_admin_table()
|
in both cases when table was successfully open in mysql_admin_table()
|
||||||
@@ -219,11 +230,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (dd_recreate_table(thd, table_list->db.str, table_list->table_name.str))
|
if (dd_recreate_table(thd, table_list->db.str, table_list->table_name.str))
|
||||||
{
|
create_error= send_check_errmsg(thd, table_list, "repair",
|
||||||
error= send_check_errmsg(thd, table_list, "repair",
|
|
||||||
"Failed generating table from .frm file");
|
"Failed generating table from .frm file");
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
'FALSE' for 'using_transactions' means don't postpone
|
'FALSE' for 'using_transactions' means don't postpone
|
||||||
invalidation till the end of a transaction, but do it
|
invalidation till the end of a transaction, but do it
|
||||||
@@ -236,6 +244,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
|||||||
"Failed restoring .MYD file");
|
"Failed restoring .MYD file");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
if (create_error)
|
||||||
|
goto end;
|
||||||
|
|
||||||
if (thd->locked_tables_list.locked_tables())
|
if (thd->locked_tables_list.locked_tables())
|
||||||
{
|
{
|
||||||
@@ -263,7 +273,8 @@ end:
|
|||||||
if (table == &tmp_table)
|
if (table == &tmp_table)
|
||||||
{
|
{
|
||||||
closefrm(table);
|
closefrm(table);
|
||||||
tdc_release_share(table->s);
|
if (share)
|
||||||
|
tdc_release_share(share);
|
||||||
}
|
}
|
||||||
/* In case of a temporary table there will be no metadata lock. */
|
/* In case of a temporary table there will be no metadata lock. */
|
||||||
if (unlikely(error) && has_mdl_lock)
|
if (unlikely(error) && has_mdl_lock)
|
||||||
@@ -418,6 +429,50 @@ dbug_err:
|
|||||||
return open_error;
|
return open_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_WSREP
|
||||||
|
/*
|
||||||
|
OPTIMIZE, REPAIR and ALTER may take MDL locks not only for the affected table, but
|
||||||
|
also for the table referenced by foreign key constraint.
|
||||||
|
This wsrep_toi_replication() function handles TOI replication for OPTIMIZE and REPAIR
|
||||||
|
so that certification keys for potential FK parent tables are also appended in the
|
||||||
|
write set.
|
||||||
|
ALTER TABLE case is handled elsewhere.
|
||||||
|
*/
|
||||||
|
static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables)
|
||||||
|
{
|
||||||
|
if (!WSREP(thd) || !WSREP_CLIENT(thd)) return false;
|
||||||
|
|
||||||
|
LEX *lex= thd->lex;
|
||||||
|
/* only handle OPTIMIZE and REPAIR here */
|
||||||
|
switch (lex->sql_command)
|
||||||
|
{
|
||||||
|
case SQLCOM_OPTIMIZE:
|
||||||
|
case SQLCOM_REPAIR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
close_thread_tables(thd);
|
||||||
|
wsrep::key_array keys;
|
||||||
|
|
||||||
|
wsrep_append_fk_parent_table(thd, tables, &keys);
|
||||||
|
|
||||||
|
/* now TOI replication, with no locks held */
|
||||||
|
if (keys.empty())
|
||||||
|
{
|
||||||
|
WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, tables);
|
||||||
|
} else {
|
||||||
|
WSREP_TO_ISOLATION_BEGIN_FK_TABLES(NULL, NULL, tables, &keys) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wsrep_error_label:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
@@ -486,6 +541,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
table->table= NULL;
|
table->table= NULL;
|
||||||
|
#ifdef WITH_WSREP
|
||||||
|
if (wsrep_toi_replication(thd, tables))
|
||||||
|
{
|
||||||
|
WSREP_INFO("wsrep TOI replication of has failed, skipping OPTIMIZE");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
{
|
{
|
||||||
@@ -592,6 +654,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
#endif
|
#endif
|
||||||
DBUG_PRINT("admin", ("table: %p", table->table));
|
DBUG_PRINT("admin", ("table: %p", table->table));
|
||||||
|
|
||||||
|
if (table->schema_table)
|
||||||
|
{
|
||||||
|
result_code= HA_ADMIN_NOT_IMPLEMENTED;
|
||||||
|
goto send_result;
|
||||||
|
}
|
||||||
|
|
||||||
if (prepare_func)
|
if (prepare_func)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("admin", ("calling prepare_func"));
|
DBUG_PRINT("admin", ("calling prepare_func"));
|
||||||
@@ -650,12 +718,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
goto send_result;
|
goto send_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->schema_table)
|
|
||||||
{
|
|
||||||
result_code= HA_ADMIN_NOT_IMPLEMENTED;
|
|
||||||
goto send_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
|
if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
|
||||||
{
|
{
|
||||||
/* purecov: begin inspected */
|
/* purecov: begin inspected */
|
||||||
@@ -1338,10 +1400,10 @@ bool Sql_cmd_analyze_table::execute(THD *thd)
|
|||||||
m_lex->first_select_lex()->table_list.first= first_table;
|
m_lex->first_select_lex()->table_list.first= first_table;
|
||||||
m_lex->query_tables= first_table;
|
m_lex->query_tables= first_table;
|
||||||
|
|
||||||
error:
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
wsrep_error_label:
|
wsrep_error_label:
|
||||||
#endif
|
#endif /* WITH_WSREP */
|
||||||
|
error:
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1380,7 +1442,6 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
|
|||||||
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table,
|
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table,
|
||||||
FALSE, UINT_MAX, FALSE))
|
FALSE, UINT_MAX, FALSE))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
|
|
||||||
|
|
||||||
res= (specialflag & SPECIAL_NO_NEW_FUNC) ?
|
res= (specialflag & SPECIAL_NO_NEW_FUNC) ?
|
||||||
mysql_recreate_table(thd, first_table, true) :
|
mysql_recreate_table(thd, first_table, true) :
|
||||||
@@ -1399,9 +1460,6 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
|
|||||||
m_lex->query_tables= first_table;
|
m_lex->query_tables= first_table;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
#ifdef WITH_WSREP
|
|
||||||
wsrep_error_label:
|
|
||||||
#endif
|
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1416,7 +1474,6 @@ bool Sql_cmd_repair_table::execute(THD *thd)
|
|||||||
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table,
|
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table,
|
||||||
FALSE, UINT_MAX, FALSE))
|
FALSE, UINT_MAX, FALSE))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
|
|
||||||
res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "repair",
|
res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "repair",
|
||||||
TL_WRITE, 1,
|
TL_WRITE, 1,
|
||||||
MY_TEST(m_lex->check_opt.sql_flags & TT_USEFRM),
|
MY_TEST(m_lex->check_opt.sql_flags & TT_USEFRM),
|
||||||
@@ -1435,8 +1492,5 @@ bool Sql_cmd_repair_table::execute(THD *thd)
|
|||||||
m_lex->query_tables= first_table;
|
m_lex->query_tables= first_table;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
#ifdef WITH_WSREP
|
|
||||||
wsrep_error_label:
|
|
||||||
#endif
|
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
@@ -490,6 +490,25 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
|||||||
|
|
||||||
if (check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, FALSE))
|
if (check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, FALSE))
|
||||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||||
|
#ifdef WITH_WSREP
|
||||||
|
if (WSREP(thd) && WSREP_CLIENT(thd) &&
|
||||||
|
(!thd->is_current_stmt_binlog_format_row() ||
|
||||||
|
!thd->find_temporary_table(first_table)))
|
||||||
|
{
|
||||||
|
wsrep::key_array keys;
|
||||||
|
wsrep_append_fk_parent_table(thd, first_table, &keys);
|
||||||
|
|
||||||
|
WSREP_TO_ISOLATION_BEGIN_ALTER(lex->name.str ? select_lex->db.str
|
||||||
|
: first_table->db.str,
|
||||||
|
lex->name.str ? lex->name.str
|
||||||
|
: first_table->table_name.str,
|
||||||
|
first_table, &alter_info, &keys,
|
||||||
|
used_engine ? &create_info : nullptr);
|
||||||
|
|
||||||
|
thd->variables.auto_increment_offset = 1;
|
||||||
|
thd->variables.auto_increment_increment = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (lex->name.str && !test_all_bits(priv, INSERT_ACL | CREATE_ACL))
|
if (lex->name.str && !test_all_bits(priv, INSERT_ACL | CREATE_ACL))
|
||||||
{
|
{
|
||||||
@@ -517,20 +536,6 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
|||||||
thd->work_part_info= 0;
|
thd->work_part_info= 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
|
||||||
if (WSREP(thd) &&
|
|
||||||
(!thd->is_current_stmt_binlog_format_row() ||
|
|
||||||
!thd->find_temporary_table(first_table)))
|
|
||||||
{
|
|
||||||
WSREP_TO_ISOLATION_BEGIN_ALTER((lex->name.str ? select_lex->db.str : first_table->db.str),
|
|
||||||
(lex->name.str ? lex->name.str : first_table->table_name.str),
|
|
||||||
first_table, &alter_info, used_engine ? &create_info : NULL);
|
|
||||||
|
|
||||||
thd->variables.auto_increment_offset = 1;
|
|
||||||
thd->variables.auto_increment_increment = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result= mysql_alter_table(thd, &select_lex->db, &lex->name,
|
result= mysql_alter_table(thd, &select_lex->db, &lex->name,
|
||||||
&create_info,
|
&create_info,
|
||||||
first_table,
|
first_table,
|
||||||
|
@@ -3448,7 +3448,7 @@ public:
|
|||||||
void awake_no_mutex(killed_state state_to_set);
|
void awake_no_mutex(killed_state state_to_set);
|
||||||
void awake(killed_state state_to_set)
|
void awake(killed_state state_to_set)
|
||||||
{
|
{
|
||||||
bool wsrep_on_local= WSREP_NNULL(this);
|
bool wsrep_on_local= variables.wsrep_on;
|
||||||
/*
|
/*
|
||||||
mutex locking order (LOCK_thd_data - LOCK_thd_kill)) requires
|
mutex locking order (LOCK_thd_data - LOCK_thd_kill)) requires
|
||||||
to grab LOCK_thd_data here
|
to grab LOCK_thd_data here
|
||||||
|
@@ -4469,6 +4469,12 @@ public:
|
|||||||
|
|
||||||
int add_period(Lex_ident name, Lex_ident_sys_st start, Lex_ident_sys_st end)
|
int add_period(Lex_ident name, Lex_ident_sys_st start, Lex_ident_sys_st end)
|
||||||
{
|
{
|
||||||
|
if (lex_string_cmp(system_charset_info, &start, &end) == 0)
|
||||||
|
{
|
||||||
|
my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), start.str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Table_period_info &info= create_info.period_info;
|
Table_period_info &info= create_info.period_info;
|
||||||
|
|
||||||
if (check_exists && info.name.streq(name))
|
if (check_exists && info.name.streq(name))
|
||||||
|
@@ -427,9 +427,23 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
|
|||||||
bool hton_can_recreate;
|
bool hton_can_recreate;
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
if (WSREP(thd) &&
|
if (WSREP(thd))
|
||||||
wsrep_to_isolation_begin(thd, table_ref->db.str, table_ref->table_name.str, NULL))
|
{
|
||||||
|
wsrep::key_array keys;
|
||||||
|
wsrep_append_fk_parent_table(thd, table_ref, &keys);
|
||||||
|
if (keys.empty())
|
||||||
|
{
|
||||||
|
WSREP_TO_ISOLATION_BEGIN_IF(table_ref->db.str, table_ref->table_name.str, NULL)
|
||||||
|
{
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
WSREP_TO_ISOLATION_BEGIN_FK_TABLES(NULL, NULL, table_ref, &keys)
|
||||||
|
{
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
if (lock_table(thd, table_ref, &hton_can_recreate))
|
if (lock_table(thd, table_ref, &hton_can_recreate))
|
||||||
|
@@ -2501,7 +2501,7 @@ create:
|
|||||||
Lex->pop_select(); //main select
|
Lex->pop_select(); //main select
|
||||||
}
|
}
|
||||||
| create_or_replace USER_SYM opt_if_not_exists clear_privileges
|
| create_or_replace USER_SYM opt_if_not_exists clear_privileges
|
||||||
grant_list opt_require_clause opt_resource_options opt_account_locking opt_password_expiration
|
grant_list opt_require_clause opt_resource_options opt_account_locking_and_opt_password_expiration
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_USER,
|
if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_USER,
|
||||||
$1 | $3)))
|
$1 | $3)))
|
||||||
@@ -7312,7 +7312,7 @@ alter:
|
|||||||
} OPTIONS_SYM '(' server_options_list ')' { }
|
} OPTIONS_SYM '(' server_options_list ')' { }
|
||||||
/* ALTER USER foo is allowed for MySQL compatibility. */
|
/* ALTER USER foo is allowed for MySQL compatibility. */
|
||||||
| ALTER USER_SYM opt_if_exists clear_privileges grant_list
|
| ALTER USER_SYM opt_if_exists clear_privileges grant_list
|
||||||
opt_require_clause opt_resource_options opt_account_locking opt_password_expiration
|
opt_require_clause opt_resource_options opt_account_locking_and_opt_password_expiration
|
||||||
{
|
{
|
||||||
Lex->create_info.set($3);
|
Lex->create_info.set($3);
|
||||||
Lex->sql_command= SQLCOM_ALTER_USER;
|
Lex->sql_command= SQLCOM_ALTER_USER;
|
||||||
@@ -7348,39 +7348,46 @@ alter:
|
|||||||
} stmt_end {}
|
} stmt_end {}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_account_locking:
|
account_locking_option:
|
||||||
/* Nothing */ {}
|
LOCK_SYM
|
||||||
| ACCOUNT_SYM LOCK_SYM
|
|
||||||
{
|
{
|
||||||
Lex->account_options.account_locked= ACCOUNTLOCK_LOCKED;
|
Lex->account_options.account_locked= ACCOUNTLOCK_LOCKED;
|
||||||
}
|
}
|
||||||
| ACCOUNT_SYM UNLOCK_SYM
|
| UNLOCK_SYM
|
||||||
{
|
{
|
||||||
Lex->account_options.account_locked= ACCOUNTLOCK_UNLOCKED;
|
Lex->account_options.account_locked= ACCOUNTLOCK_UNLOCKED;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
opt_password_expiration:
|
|
||||||
/* Nothing */ {}
|
opt_password_expire_option:
|
||||||
| PASSWORD_SYM EXPIRE_SYM
|
/* empty */
|
||||||
{
|
{
|
||||||
Lex->account_options.password_expire= PASSWORD_EXPIRE_NOW;
|
Lex->account_options.password_expire= PASSWORD_EXPIRE_NOW;
|
||||||
}
|
}
|
||||||
| PASSWORD_SYM EXPIRE_SYM NEVER_SYM
|
| NEVER_SYM
|
||||||
{
|
{
|
||||||
Lex->account_options.password_expire= PASSWORD_EXPIRE_NEVER;
|
Lex->account_options.password_expire= PASSWORD_EXPIRE_NEVER;
|
||||||
}
|
}
|
||||||
| PASSWORD_SYM EXPIRE_SYM DEFAULT
|
| DEFAULT
|
||||||
{
|
{
|
||||||
Lex->account_options.password_expire= PASSWORD_EXPIRE_DEFAULT;
|
Lex->account_options.password_expire= PASSWORD_EXPIRE_DEFAULT;
|
||||||
}
|
}
|
||||||
| PASSWORD_SYM EXPIRE_SYM INTERVAL_SYM NUM DAY_SYM
|
| INTERVAL_SYM NUM DAY_SYM
|
||||||
{
|
{
|
||||||
Lex->account_options.password_expire= PASSWORD_EXPIRE_INTERVAL;
|
Lex->account_options.password_expire= PASSWORD_EXPIRE_INTERVAL;
|
||||||
if (!(Lex->account_options.num_expiration_days= atoi($4.str)))
|
if (!(Lex->account_options.num_expiration_days= atoi($2.str)))
|
||||||
my_yyabort_error((ER_WRONG_VALUE, MYF(0), "DAY", $4.str));
|
my_yyabort_error((ER_WRONG_VALUE, MYF(0), "DAY", $2.str));
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_account_locking_and_opt_password_expiration:
|
||||||
|
/* empty */
|
||||||
|
| ACCOUNT_SYM account_locking_option
|
||||||
|
| PASSWORD_SYM EXPIRE_SYM opt_password_expire_option
|
||||||
|
| ACCOUNT_SYM account_locking_option PASSWORD_SYM EXPIRE_SYM opt_password_expire_option
|
||||||
|
| PASSWORD_SYM EXPIRE_SYM opt_password_expire_option ACCOUNT_SYM account_locking_option
|
||||||
|
;
|
||||||
|
|
||||||
ev_alter_on_schedule_completion:
|
ev_alter_on_schedule_completion:
|
||||||
/* empty */ { $$= 0;}
|
/* empty */ { $$= 0;}
|
||||||
| ON SCHEDULE_SYM ev_schedule_time { $$= 1; }
|
| ON SCHEDULE_SYM ev_schedule_time { $$= 1; }
|
||||||
|
@@ -245,6 +245,16 @@ void Wsrep_client_service::will_replay()
|
|||||||
mysql_mutex_unlock(&LOCK_wsrep_replaying);
|
mysql_mutex_unlock(&LOCK_wsrep_replaying);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Wsrep_client_service::signal_replayed()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(m_thd == current_thd);
|
||||||
|
mysql_mutex_lock(&LOCK_wsrep_replaying);
|
||||||
|
--wsrep_replaying;
|
||||||
|
DBUG_ASSERT(wsrep_replaying >= 0);
|
||||||
|
mysql_cond_broadcast(&COND_wsrep_replaying);
|
||||||
|
mysql_mutex_unlock(&LOCK_wsrep_replaying);
|
||||||
|
}
|
||||||
|
|
||||||
enum wsrep::provider::status Wsrep_client_service::replay()
|
enum wsrep::provider::status Wsrep_client_service::replay()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -273,14 +283,15 @@ enum wsrep::provider::status Wsrep_client_service::replay()
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete replayer_thd;
|
delete replayer_thd;
|
||||||
|
|
||||||
mysql_mutex_lock(&LOCK_wsrep_replaying);
|
|
||||||
--wsrep_replaying;
|
|
||||||
mysql_cond_broadcast(&COND_wsrep_replaying);
|
|
||||||
mysql_mutex_unlock(&LOCK_wsrep_replaying);
|
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum wsrep::provider::status Wsrep_client_service::replay_unordered()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return wsrep::provider::error_not_implemented;
|
||||||
|
}
|
||||||
|
|
||||||
void Wsrep_client_service::wait_for_replayers(wsrep::unique_lock<wsrep::mutex>& lock)
|
void Wsrep_client_service::wait_for_replayers(wsrep::unique_lock<wsrep::mutex>& lock)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(m_thd == current_thd);
|
DBUG_ASSERT(m_thd == current_thd);
|
||||||
@@ -300,6 +311,12 @@ void Wsrep_client_service::wait_for_replayers(wsrep::unique_lock<wsrep::mutex>&
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum wsrep::provider::status Wsrep_client_service::commit_by_xid()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return wsrep::provider::error_not_implemented;
|
||||||
|
}
|
||||||
|
|
||||||
void Wsrep_client_service::debug_sync(const char* sync_point)
|
void Wsrep_client_service::debug_sync(const char* sync_point)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(m_thd == current_thd);
|
DBUG_ASSERT(m_thd == current_thd);
|
||||||
|
@@ -48,8 +48,19 @@ public:
|
|||||||
void emergency_shutdown()
|
void emergency_shutdown()
|
||||||
{ throw wsrep::not_implemented_error(); }
|
{ throw wsrep::not_implemented_error(); }
|
||||||
void will_replay();
|
void will_replay();
|
||||||
|
void signal_replayed();
|
||||||
enum wsrep::provider::status replay();
|
enum wsrep::provider::status replay();
|
||||||
|
enum wsrep::provider::status replay_unordered();
|
||||||
void wait_for_replayers(wsrep::unique_lock<wsrep::mutex>&);
|
void wait_for_replayers(wsrep::unique_lock<wsrep::mutex>&);
|
||||||
|
enum wsrep::provider::status commit_by_xid();
|
||||||
|
bool is_explicit_xa()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool is_xa_rollback()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void debug_sync(const char*);
|
void debug_sync(const char*);
|
||||||
void debug_crash(const char*);
|
void debug_crash(const char*);
|
||||||
int bf_rollback();
|
int bf_rollback();
|
||||||
|
@@ -1261,6 +1261,51 @@ void wsrep_keys_free(wsrep_key_arr_t* key_arr)
|
|||||||
key_arr->keys_len= 0;
|
key_arr->keys_len= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wsrep_append_fk_parent_table(THD* thd, TABLE_LIST* tables, wsrep::key_array* keys)
|
||||||
|
{
|
||||||
|
if (!WSREP(thd) || !WSREP_CLIENT(thd)) return;
|
||||||
|
TABLE_LIST *table;
|
||||||
|
|
||||||
|
thd->mdl_context.release_transactional_locks();
|
||||||
|
uint counter;
|
||||||
|
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
|
||||||
|
|
||||||
|
if (thd->open_temporary_tables(tables) ||
|
||||||
|
open_tables(thd, &tables, &counter, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL))
|
||||||
|
{
|
||||||
|
WSREP_DEBUG("unable to open table for FK checks for %s", thd->query());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (table= tables; table; table= table->next_local)
|
||||||
|
{
|
||||||
|
if (!is_temporary_table(table) && table->table)
|
||||||
|
{
|
||||||
|
FOREIGN_KEY_INFO *f_key_info;
|
||||||
|
List<FOREIGN_KEY_INFO> f_key_list;
|
||||||
|
|
||||||
|
table->table->file->get_foreign_key_list(thd, &f_key_list);
|
||||||
|
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
|
||||||
|
while ((f_key_info=it++))
|
||||||
|
{
|
||||||
|
WSREP_DEBUG("appended fkey %s", f_key_info->referenced_table->str);
|
||||||
|
keys->push_back(wsrep_prepare_key_for_toi(f_key_info->referenced_db->str,
|
||||||
|
f_key_info->referenced_table->str,
|
||||||
|
wsrep::key::shared));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close the table and release MDL locks */
|
||||||
|
close_thread_tables(thd);
|
||||||
|
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
|
||||||
|
for (table= tables; table; table= table->next_local)
|
||||||
|
{
|
||||||
|
table->table= NULL;
|
||||||
|
table->mdl_request.ticket= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @param db Database string
|
* @param db Database string
|
||||||
* @param table Table string
|
* @param table Table string
|
||||||
@@ -1514,7 +1559,8 @@ wsrep_prepare_keys_for_alter_add_fk(const char* child_table_db,
|
|||||||
wsrep::key_array wsrep_prepare_keys_for_toi(const char *db,
|
wsrep::key_array wsrep_prepare_keys_for_toi(const char *db,
|
||||||
const char *table,
|
const char *table,
|
||||||
const TABLE_LIST *table_list,
|
const TABLE_LIST *table_list,
|
||||||
const Alter_info* alter_info)
|
const Alter_info *alter_info,
|
||||||
|
const wsrep::key_array *fk_tables)
|
||||||
{
|
{
|
||||||
wsrep::key_array ret;
|
wsrep::key_array ret;
|
||||||
if (db || table)
|
if (db || table)
|
||||||
@@ -1534,8 +1580,13 @@ wsrep::key_array wsrep_prepare_keys_for_toi(const char* db,
|
|||||||
ret.insert(ret.end(), fk.begin(), fk.end());
|
ret.insert(ret.end(), fk.begin(), fk.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fk_tables && !fk_tables->empty())
|
||||||
|
{
|
||||||
|
ret.insert(ret.end(), fk_tables->begin(), fk_tables->end());
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct Query_log_Event from thd query and serialize it
|
* Construct Query_log_Event from thd query and serialize it
|
||||||
* into buffer.
|
* into buffer.
|
||||||
@@ -2071,6 +2122,7 @@ fail:
|
|||||||
static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||||
const TABLE_LIST *table_list,
|
const TABLE_LIST *table_list,
|
||||||
const Alter_info *alter_info,
|
const Alter_info *alter_info,
|
||||||
|
const wsrep::key_array *fk_tables,
|
||||||
const HA_CREATE_INFO *create_info)
|
const HA_CREATE_INFO *create_info)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(wsrep_OSU_method_get(thd) == WSREP_OSU_TOI);
|
DBUG_ASSERT(wsrep_OSU_method_get(thd) == WSREP_OSU_TOI);
|
||||||
@@ -2102,7 +2154,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
|||||||
struct wsrep_buf buff= { buf, buf_len };
|
struct wsrep_buf buff= { buf, buf_len };
|
||||||
|
|
||||||
wsrep::key_array key_array=
|
wsrep::key_array key_array=
|
||||||
wsrep_prepare_keys_for_toi(db, table, table_list, alter_info);
|
wsrep_prepare_keys_for_toi(db, table, table_list, alter_info, fk_tables);
|
||||||
|
|
||||||
if (thd->has_read_only_protection())
|
if (thd->has_read_only_protection())
|
||||||
{
|
{
|
||||||
@@ -2251,6 +2303,7 @@ static void wsrep_RSU_end(THD *thd)
|
|||||||
int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
||||||
const TABLE_LIST* table_list,
|
const TABLE_LIST* table_list,
|
||||||
const Alter_info *alter_info,
|
const Alter_info *alter_info,
|
||||||
|
const wsrep::key_array *fk_tables,
|
||||||
const HA_CREATE_INFO *create_info)
|
const HA_CREATE_INFO *create_info)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -2305,7 +2358,8 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
|||||||
{
|
{
|
||||||
switch (wsrep_OSU_method_get(thd)) {
|
switch (wsrep_OSU_method_get(thd)) {
|
||||||
case WSREP_OSU_TOI:
|
case WSREP_OSU_TOI:
|
||||||
ret= wsrep_TOI_begin(thd, db_, table_, table_list, alter_info, create_info);
|
ret= wsrep_TOI_begin(thd, db_, table_, table_list, alter_info, fk_tables,
|
||||||
|
create_info);
|
||||||
break;
|
break;
|
||||||
case WSREP_OSU_RSU:
|
case WSREP_OSU_RSU:
|
||||||
ret= wsrep_RSU_begin(thd, db_, table_);
|
ret= wsrep_RSU_begin(thd, db_, table_);
|
||||||
|
@@ -215,6 +215,7 @@ wsrep_sync_wait_upto (THD* thd, wsrep_gtid_t* upto, int timeout);
|
|||||||
extern void wsrep_last_committed_id (wsrep_gtid_t* gtid);
|
extern void wsrep_last_committed_id (wsrep_gtid_t* gtid);
|
||||||
extern int wsrep_check_opts();
|
extern int wsrep_check_opts();
|
||||||
extern void wsrep_prepend_PATH (const char* path);
|
extern void wsrep_prepend_PATH (const char* path);
|
||||||
|
void wsrep_append_fk_parent_table(THD* thd, TABLE_LIST* table, wsrep::key_array* keys);
|
||||||
|
|
||||||
/* Other global variables */
|
/* Other global variables */
|
||||||
extern wsrep_seqno_t wsrep_locked_seqno;
|
extern wsrep_seqno_t wsrep_locked_seqno;
|
||||||
@@ -362,8 +363,9 @@ struct HA_CREATE_INFO;
|
|||||||
|
|
||||||
int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
||||||
const TABLE_LIST* table_list,
|
const TABLE_LIST* table_list,
|
||||||
const Alter_info* alter_info= NULL,
|
const Alter_info* alter_info= nullptr,
|
||||||
const HA_CREATE_INFO* create_info= NULL);
|
const wsrep::key_array *fk_tables= nullptr,
|
||||||
|
const HA_CREATE_INFO* create_info= nullptr);
|
||||||
|
|
||||||
bool wsrep_should_replicate_ddl(THD* thd, const enum legacy_db_type db_type);
|
bool wsrep_should_replicate_ddl(THD* thd, const enum legacy_db_type db_type);
|
||||||
bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list);
|
bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list);
|
||||||
@@ -607,6 +609,9 @@ void wsrep_deinit_server();
|
|||||||
*/
|
*/
|
||||||
enum wsrep::streaming_context::fragment_unit wsrep_fragment_unit(ulong unit);
|
enum wsrep::streaming_context::fragment_unit wsrep_fragment_unit(ulong unit);
|
||||||
|
|
||||||
|
wsrep::key wsrep_prepare_key_for_toi(const char* db, const char* table,
|
||||||
|
enum wsrep::key::type type);
|
||||||
|
|
||||||
#else /* !WITH_WSREP */
|
#else /* !WITH_WSREP */
|
||||||
|
|
||||||
/* These macros are needed to compile MariaDB without WSREP support
|
/* These macros are needed to compile MariaDB without WSREP support
|
||||||
|
@@ -3483,7 +3483,7 @@ re_evict:
|
|||||||
if (fix_block->page.ibuf_exist) {
|
if (fix_block->page.ibuf_exist) {
|
||||||
fix_block->page.ibuf_exist = false;
|
fix_block->page.ibuf_exist = false;
|
||||||
ibuf_merge_or_delete_for_page(fix_block, page_id,
|
ibuf_merge_or_delete_for_page(fix_block, page_id,
|
||||||
zip_size, true);
|
zip_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rw_latch == RW_X_LATCH) {
|
if (rw_latch == RW_X_LATCH) {
|
||||||
@@ -3550,7 +3550,7 @@ buf_page_get_gen(
|
|||||||
{
|
{
|
||||||
rw_lock_x_lock_inline(&block->lock, 0, file, line);
|
rw_lock_x_lock_inline(&block->lock, 0, file, line);
|
||||||
block->page.ibuf_exist= false;
|
block->page.ibuf_exist= false;
|
||||||
ibuf_merge_or_delete_for_page(block, page_id, block->zip_size(), true);
|
ibuf_merge_or_delete_for_page(block, page_id, block->zip_size());
|
||||||
|
|
||||||
if (rw_latch == RW_X_LATCH)
|
if (rw_latch == RW_X_LATCH)
|
||||||
{
|
{
|
||||||
@@ -3823,7 +3823,7 @@ loop:
|
|||||||
if (block->page.ibuf_exist)
|
if (block->page.ibuf_exist)
|
||||||
{
|
{
|
||||||
if (!recv_recovery_is_on())
|
if (!recv_recovery_is_on())
|
||||||
ibuf_merge_or_delete_for_page(nullptr, page_id, zip_size, true);
|
ibuf_merge_or_delete_for_page(nullptr, page_id, zip_size);
|
||||||
block->page.ibuf_exist= false;
|
block->page.ibuf_exist= false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3885,7 +3885,7 @@ loop:
|
|||||||
/* Delete possible entries for the page from the insert buffer:
|
/* Delete possible entries for the page from the insert buffer:
|
||||||
such can exist if the page belonged to an index which was dropped */
|
such can exist if the page belonged to an index which was dropped */
|
||||||
if (!recv_recovery_is_on())
|
if (!recv_recovery_is_on())
|
||||||
ibuf_merge_or_delete_for_page(nullptr, page_id, zip_size, true);
|
ibuf_merge_or_delete_for_page(nullptr, page_id, zip_size);
|
||||||
|
|
||||||
static_assert(FIL_PAGE_PREV + 4 == FIL_PAGE_NEXT, "adjacent");
|
static_assert(FIL_PAGE_PREV + 4 == FIL_PAGE_NEXT, "adjacent");
|
||||||
memset_aligned<8>(block->frame + FIL_PAGE_PREV, 0xff, 8);
|
memset_aligned<8>(block->frame + FIL_PAGE_PREV, 0xff, 8);
|
||||||
|
@@ -5268,87 +5268,3 @@ dict_tf_to_row_format_string(
|
|||||||
ut_error;
|
ut_error;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Look for any dictionary objects that are found in the given tablespace.
|
|
||||||
@param[in] space_id Tablespace ID to search for.
|
|
||||||
@return true if tablespace is empty. */
|
|
||||||
bool
|
|
||||||
dict_space_is_empty(
|
|
||||||
ulint space_id)
|
|
||||||
{
|
|
||||||
btr_pcur_t pcur;
|
|
||||||
const rec_t* rec;
|
|
||||||
mtr_t mtr;
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
dict_sys_lock();
|
|
||||||
mtr_start(&mtr);
|
|
||||||
|
|
||||||
for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
|
|
||||||
rec != NULL;
|
|
||||||
rec = dict_getnext_system(&pcur, &mtr)) {
|
|
||||||
const byte* field;
|
|
||||||
ulint len;
|
|
||||||
ulint space_id_for_table;
|
|
||||||
|
|
||||||
field = rec_get_nth_field_old(
|
|
||||||
rec, DICT_FLD__SYS_TABLES__SPACE, &len);
|
|
||||||
ut_ad(len == 4);
|
|
||||||
space_id_for_table = mach_read_from_4(field);
|
|
||||||
|
|
||||||
if (space_id_for_table == space_id) {
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
|
||||||
dict_sys_unlock();
|
|
||||||
|
|
||||||
return(!found);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Find the space_id for the given name in sys_tablespaces.
|
|
||||||
@param[in] name Tablespace name to search for.
|
|
||||||
@return the tablespace ID. */
|
|
||||||
ulint
|
|
||||||
dict_space_get_id(
|
|
||||||
const char* name)
|
|
||||||
{
|
|
||||||
btr_pcur_t pcur;
|
|
||||||
const rec_t* rec;
|
|
||||||
mtr_t mtr;
|
|
||||||
ulint name_len = strlen(name);
|
|
||||||
ulint id = ULINT_UNDEFINED;
|
|
||||||
|
|
||||||
dict_sys_lock();
|
|
||||||
mtr_start(&mtr);
|
|
||||||
|
|
||||||
for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLESPACES);
|
|
||||||
rec != NULL;
|
|
||||||
rec = dict_getnext_system(&pcur, &mtr)) {
|
|
||||||
const byte* field;
|
|
||||||
ulint len;
|
|
||||||
|
|
||||||
field = rec_get_nth_field_old(
|
|
||||||
rec, DICT_FLD__SYS_TABLESPACES__NAME, &len);
|
|
||||||
ut_ad(len > 0);
|
|
||||||
ut_ad(len < OS_FILE_MAX_PATH);
|
|
||||||
|
|
||||||
if (len == name_len && !memcmp(name, field, len)) {
|
|
||||||
field = rec_get_nth_field_old(
|
|
||||||
rec, DICT_FLD__SYS_TABLESPACES__SPACE, &len);
|
|
||||||
ut_ad(len == 4);
|
|
||||||
id = mach_read_from_4(field);
|
|
||||||
|
|
||||||
/* This is normally called by dict_getnext_system()
|
|
||||||
at the end of the index. */
|
|
||||||
btr_pcur_close(&pcur);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
|
||||||
dict_sys_unlock();
|
|
||||||
|
|
||||||
return(id);
|
|
||||||
}
|
|
||||||
|
@@ -541,6 +541,7 @@ static PSI_mutex_info all_innodb_mutexes[] = {
|
|||||||
PSI_KEY(ibuf_bitmap_mutex),
|
PSI_KEY(ibuf_bitmap_mutex),
|
||||||
PSI_KEY(ibuf_mutex),
|
PSI_KEY(ibuf_mutex),
|
||||||
PSI_KEY(ibuf_pessimistic_insert_mutex),
|
PSI_KEY(ibuf_pessimistic_insert_mutex),
|
||||||
|
PSI_KEY(index_online_log),
|
||||||
PSI_KEY(log_sys_mutex),
|
PSI_KEY(log_sys_mutex),
|
||||||
PSI_KEY(page_zip_stat_per_index_mutex),
|
PSI_KEY(page_zip_stat_per_index_mutex),
|
||||||
PSI_KEY(purge_sys_pq_mutex),
|
PSI_KEY(purge_sys_pq_mutex),
|
||||||
@@ -587,7 +588,6 @@ static PSI_rwlock_info all_innodb_rwlocks[] = {
|
|||||||
PSI_RWLOCK_KEY(trx_i_s_cache_lock),
|
PSI_RWLOCK_KEY(trx_i_s_cache_lock),
|
||||||
PSI_RWLOCK_KEY(trx_purge_latch),
|
PSI_RWLOCK_KEY(trx_purge_latch),
|
||||||
PSI_RWLOCK_KEY(index_tree_rw_lock),
|
PSI_RWLOCK_KEY(index_tree_rw_lock),
|
||||||
PSI_RWLOCK_KEY(index_online_log),
|
|
||||||
};
|
};
|
||||||
# endif /* UNIV_PFS_RWLOCK */
|
# endif /* UNIV_PFS_RWLOCK */
|
||||||
|
|
||||||
@@ -15264,24 +15264,6 @@ struct table_list_item {
|
|||||||
const char* name;
|
const char* name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Structure to compare two st_tablename objects using their
|
|
||||||
db and tablename. It is used in the ordering of cascade_fk_set.
|
|
||||||
It returns true if the first argument precedes the second argument
|
|
||||||
and false otherwise. */
|
|
||||||
struct tablename_compare {
|
|
||||||
|
|
||||||
bool operator()(const st_handler_tablename lhs,
|
|
||||||
const st_handler_tablename rhs) const
|
|
||||||
{
|
|
||||||
int cmp = strcmp(lhs.db, rhs.db);
|
|
||||||
if (cmp == 0) {
|
|
||||||
cmp = strcmp(lhs.tablename, rhs.tablename);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(cmp < 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
Checks if ALTER TABLE may change the storage engine of the table.
|
Checks if ALTER TABLE may change the storage engine of the table.
|
||||||
Changing storage engines is not allowed for tables for which there
|
Changing storage engines is not allowed for tables for which there
|
||||||
|
@@ -51,12 +51,7 @@ struct ha_table_option_struct
|
|||||||
uint encryption; /*!< DEFAULT, ON, OFF */
|
uint encryption; /*!< DEFAULT, ON, OFF */
|
||||||
ulonglong encryption_key_id; /*!< encryption key id */
|
ulonglong encryption_key_id; /*!< encryption key id */
|
||||||
};
|
};
|
||||||
/* JAN: TODO: MySQL 5.7 handler.h */
|
|
||||||
struct st_handler_tablename
|
|
||||||
{
|
|
||||||
const char *db;
|
|
||||||
const char *tablename;
|
|
||||||
};
|
|
||||||
/** The class defining a handle to an Innodb table */
|
/** The class defining a handle to an Innodb table */
|
||||||
class ha_innobase final : public handler
|
class ha_innobase final : public handler
|
||||||
{
|
{
|
||||||
|
@@ -4170,19 +4170,11 @@ insert buffer. If the page is not read, but created in the buffer pool, this
|
|||||||
function deletes its buffered entries from the insert buffer; there can
|
function deletes its buffered entries from the insert buffer; there can
|
||||||
exist entries for such a page if the page belonged to an index which
|
exist entries for such a page if the page belonged to an index which
|
||||||
subsequently was dropped.
|
subsequently was dropped.
|
||||||
@param[in,out] block if page has been read from disk,
|
@param block X-latched page to try to apply changes to, or NULL to discard
|
||||||
pointer to the page x-latched, else NULL
|
@param page_id page identifier
|
||||||
@param[in] page_id page id of the index page
|
@param zip_size ROW_FORMAT=COMPRESSED page size, or 0 */
|
||||||
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
|
void ibuf_merge_or_delete_for_page(buf_block_t *block, const page_id_t page_id,
|
||||||
@param[in] update_ibuf_bitmap normally this is set, but
|
ulint zip_size)
|
||||||
if we have deleted or are deleting the tablespace, then we naturally do not
|
|
||||||
want to update a non-existent bitmap page */
|
|
||||||
void
|
|
||||||
ibuf_merge_or_delete_for_page(
|
|
||||||
buf_block_t* block,
|
|
||||||
const page_id_t page_id,
|
|
||||||
ulint zip_size,
|
|
||||||
bool update_ibuf_bitmap)
|
|
||||||
{
|
{
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
#ifdef UNIV_IBUF_DEBUG
|
#ifdef UNIV_IBUF_DEBUG
|
||||||
@@ -4211,16 +4203,10 @@ ibuf_merge_or_delete_for_page(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_space_t* space;
|
fil_space_t* space = fil_space_t::get(page_id.space());
|
||||||
|
|
||||||
if (update_ibuf_bitmap) {
|
|
||||||
space = fil_space_t::get(page_id.space());
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(!space)) {
|
if (UNIV_UNLIKELY(!space)) {
|
||||||
/* Do not try to read the bitmap page from the
|
|
||||||
non-existent tablespace, delete the ibuf records */
|
|
||||||
block = NULL;
|
block = NULL;
|
||||||
update_ibuf_bitmap = false;
|
|
||||||
} else {
|
} else {
|
||||||
ulint bitmap_bits = 0;
|
ulint bitmap_bits = 0;
|
||||||
|
|
||||||
@@ -4245,14 +4231,6 @@ ibuf_merge_or_delete_for_page(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (block != NULL
|
|
||||||
&& (ibuf_fixed_addr_page(page_id, physical_size)
|
|
||||||
|| fsp_descr_page(page_id, physical_size))) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
space = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mem_heap_t* heap = mem_heap_create(512);
|
mem_heap_t* heap = mem_heap_create(512);
|
||||||
|
|
||||||
@@ -4297,12 +4275,11 @@ loop:
|
|||||||
ibuf.index, search_tuple, PAGE_CUR_GE, BTR_MODIFY_LEAF,
|
ibuf.index, search_tuple, PAGE_CUR_GE, BTR_MODIFY_LEAF,
|
||||||
&pcur, &mtr);
|
&pcur, &mtr);
|
||||||
|
|
||||||
if (block != NULL) {
|
if (block) {
|
||||||
ut_ad(rw_lock_own(&block->lock, RW_LOCK_X));
|
ut_ad(rw_lock_own(&block->lock, RW_LOCK_X));
|
||||||
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
|
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
|
||||||
rw_lock_x_lock(&block->lock);
|
rw_lock_x_lock(&block->lock);
|
||||||
|
|
||||||
mtr.set_named_space(space);
|
|
||||||
mtr.memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
mtr.memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
||||||
/* This is a user page (secondary index leaf page),
|
/* This is a user page (secondary index leaf page),
|
||||||
but we pretend that it is a change buffer page in
|
but we pretend that it is a change buffer page in
|
||||||
@@ -4311,7 +4288,9 @@ loop:
|
|||||||
the block is io-fixed. Other threads must not try to
|
the block is io-fixed. Other threads must not try to
|
||||||
latch an io-fixed block. */
|
latch an io-fixed block. */
|
||||||
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
|
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
|
||||||
} else if (update_ibuf_bitmap) {
|
}
|
||||||
|
|
||||||
|
if (space) {
|
||||||
mtr.set_named_space(space);
|
mtr.set_named_space(space);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4467,7 +4446,7 @@ loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
reset_bit:
|
reset_bit:
|
||||||
if (!update_ibuf_bitmap) {
|
if (!space) {
|
||||||
} else if (buf_block_t* bitmap = ibuf_bitmap_get_map_page(
|
} else if (buf_block_t* bitmap = ibuf_bitmap_get_map_page(
|
||||||
page_id, zip_size, &mtr)) {
|
page_id, zip_size, &mtr)) {
|
||||||
/* FIXME: update the bitmap byte only once! */
|
/* FIXME: update the bitmap byte only once! */
|
||||||
|
@@ -910,19 +910,6 @@ inline ulint dict_tf_get_zip_size(ulint flags)
|
|||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determine the extent size (in pages) for the given table
|
|
||||||
@param[in] table the table whose extent size is being
|
|
||||||
calculated.
|
|
||||||
@return extent size in pages (256, 128 or 64) */
|
|
||||||
inline ulint dict_table_extent_size(const dict_table_t* table)
|
|
||||||
{
|
|
||||||
if (ulint zip_size = table->space->zip_size()) {
|
|
||||||
return (1U << 20) / zip_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FSP_EXTENT_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Checks if a column is in the ordering columns of the clustered index of a
|
Checks if a column is in the ordering columns of the clustered index of a
|
||||||
table. Column prefixes are treated like whole columns.
|
table. Column prefixes are treated like whole columns.
|
||||||
@@ -1803,20 +1790,6 @@ dict_table_decode_n_col(
|
|||||||
ulint* n_col,
|
ulint* n_col,
|
||||||
ulint* n_v_col);
|
ulint* n_v_col);
|
||||||
|
|
||||||
/** Look for any dictionary objects that are found in the given tablespace.
|
|
||||||
@param[in] space_id Tablespace ID to search for.
|
|
||||||
@return true if tablespace is empty. */
|
|
||||||
bool
|
|
||||||
dict_space_is_empty(
|
|
||||||
ulint space_id);
|
|
||||||
|
|
||||||
/** Find the space_id for the given name in sys_tablespaces.
|
|
||||||
@param[in] name Tablespace name to search for.
|
|
||||||
@return the tablespace ID. */
|
|
||||||
ulint
|
|
||||||
dict_space_get_id(
|
|
||||||
const char* name);
|
|
||||||
|
|
||||||
/** Free the virtual column template
|
/** Free the virtual column template
|
||||||
@param[in,out] vc_templ virtual column template */
|
@param[in,out] vc_templ virtual column template */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
@@ -329,19 +329,11 @@ insert buffer. If the page is not read, but created in the buffer pool, this
|
|||||||
function deletes its buffered entries from the insert buffer; there can
|
function deletes its buffered entries from the insert buffer; there can
|
||||||
exist entries for such a page if the page belonged to an index which
|
exist entries for such a page if the page belonged to an index which
|
||||||
subsequently was dropped.
|
subsequently was dropped.
|
||||||
@param[in,out] block if page has been read from disk,
|
@param block X-latched page to try to apply changes to, or NULL to discard
|
||||||
pointer to the page x-latched, else NULL
|
@param page_id page identifier
|
||||||
@param[in] page_id page id of the index page
|
@param zip_size ROW_FORMAT=COMPRESSED page size, or 0 */
|
||||||
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
|
void ibuf_merge_or_delete_for_page(buf_block_t *block, const page_id_t page_id,
|
||||||
@param[in] update_ibuf_bitmap normally this is set, but
|
ulint zip_size);
|
||||||
if we have deleted or are deleting the tablespace, then we naturally do not
|
|
||||||
want to update a non-existent bitmap page */
|
|
||||||
void
|
|
||||||
ibuf_merge_or_delete_for_page(
|
|
||||||
buf_block_t* block,
|
|
||||||
const page_id_t page_id,
|
|
||||||
ulint zip_size,
|
|
||||||
bool update_ibuf_bitmap);
|
|
||||||
|
|
||||||
/** Delete all change buffer entries for a tablespace,
|
/** Delete all change buffer entries for a tablespace,
|
||||||
in DISCARD TABLESPACE, IMPORT TABLESPACE, or crash recovery.
|
in DISCARD TABLESPACE, IMPORT TABLESPACE, or crash recovery.
|
||||||
|
@@ -985,20 +985,6 @@ public:
|
|||||||
/*------------------------------*/
|
/*------------------------------*/
|
||||||
char* detailed_error; /*!< detailed error message for last
|
char* detailed_error; /*!< detailed error message for last
|
||||||
error, or empty. */
|
error, or empty. */
|
||||||
/* Lock wait statistics */
|
|
||||||
ulint n_rec_lock_waits;
|
|
||||||
/*!< Number of record lock waits,
|
|
||||||
might not be exactly correct. */
|
|
||||||
ulint n_table_lock_waits;
|
|
||||||
/*!< Number of table lock waits,
|
|
||||||
might not be exactly correct. */
|
|
||||||
ulint total_rec_lock_wait_time;
|
|
||||||
/*!< Total rec lock wait time up
|
|
||||||
to this moment. */
|
|
||||||
ulint total_table_lock_wait_time;
|
|
||||||
/*!< Total table lock wait time
|
|
||||||
up to this moment. */
|
|
||||||
|
|
||||||
rw_trx_hash_element_t *rw_trx_hash_element;
|
rw_trx_hash_element_t *rw_trx_hash_element;
|
||||||
LF_PINS *rw_trx_hash_pins;
|
LF_PINS *rw_trx_hash_pins;
|
||||||
ulint magic_n;
|
ulint magic_n;
|
||||||
|
@@ -4259,72 +4259,152 @@ os_file_set_umask(ulint umask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static int win32_get_block_size(HANDLE volume_handle, const char *volume_name)
|
|
||||||
|
/* Checks whether physical drive is on SSD.*/
|
||||||
|
static bool is_drive_on_ssd(DWORD nr)
|
||||||
{
|
{
|
||||||
STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR disk_alignment;
|
char physical_drive_path[32];
|
||||||
STORAGE_PROPERTY_QUERY storage_query;
|
snprintf(physical_drive_path, sizeof(physical_drive_path),
|
||||||
DWORD tmp;
|
"\\\\.\\PhysicalDrive%lu", nr);
|
||||||
|
|
||||||
memset(&storage_query, 0, sizeof(storage_query));
|
HANDLE h= CreateFile(physical_drive_path, 0,
|
||||||
storage_query.PropertyId = StorageAccessAlignmentProperty;
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
storage_query.QueryType = PropertyStandardQuery;
|
nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||||
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (os_win32_device_io_control(volume_handle,
|
|
||||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
|
||||||
&storage_query,
|
|
||||||
sizeof storage_query,
|
|
||||||
&disk_alignment,
|
|
||||||
sizeof disk_alignment,
|
|
||||||
&tmp) && tmp == sizeof disk_alignment) {
|
|
||||||
return disk_alignment.BytesPerPhysicalSector;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (GetLastError()) {
|
|
||||||
case ERROR_INVALID_FUNCTION:
|
|
||||||
case ERROR_NOT_SUPPORTED:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
os_file_handle_error_no_exit(
|
|
||||||
volume_name,
|
|
||||||
"DeviceIoControl(IOCTL_STORAGE_QUERY_PROPERTY / StorageAccessAlignmentProperty)",
|
|
||||||
FALSE);
|
|
||||||
}
|
|
||||||
return 512;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool win32_is_ssd(HANDLE volume_handle)
|
|
||||||
{
|
|
||||||
DWORD tmp;
|
|
||||||
DEVICE_SEEK_PENALTY_DESCRIPTOR seek_penalty;
|
DEVICE_SEEK_PENALTY_DESCRIPTOR seek_penalty;
|
||||||
STORAGE_PROPERTY_QUERY storage_query;
|
STORAGE_PROPERTY_QUERY storage_query{};
|
||||||
memset(&storage_query, 0, sizeof(storage_query));
|
|
||||||
|
|
||||||
storage_query.PropertyId= StorageDeviceSeekPenaltyProperty;
|
storage_query.PropertyId= StorageDeviceSeekPenaltyProperty;
|
||||||
storage_query.QueryType= PropertyStandardQuery;
|
storage_query.QueryType= PropertyStandardQuery;
|
||||||
|
|
||||||
if (os_win32_device_io_control(volume_handle,
|
bool on_ssd= false;
|
||||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
DWORD bytes_written;
|
||||||
&storage_query,
|
if (DeviceIoControl(h, IOCTL_STORAGE_QUERY_PROPERTY, &storage_query,
|
||||||
sizeof storage_query,
|
sizeof storage_query, &seek_penalty, sizeof seek_penalty,
|
||||||
&seek_penalty,
|
&bytes_written, nullptr))
|
||||||
sizeof seek_penalty,
|
{
|
||||||
&tmp) && tmp == sizeof(seek_penalty)){
|
on_ssd= seek_penalty.IncursSeekPenalty;
|
||||||
return !seek_penalty.IncursSeekPenalty;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
on_ssd= false;
|
||||||
|
}
|
||||||
|
CloseHandle(h);
|
||||||
|
return on_ssd;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEVICE_TRIM_DESCRIPTOR trim;
|
/*
|
||||||
storage_query.PropertyId = StorageDeviceTrimProperty;
|
Checks whether volume is on SSD, by checking all physical drives
|
||||||
if (os_win32_device_io_control(volume_handle,
|
in that volume.
|
||||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
*/
|
||||||
&storage_query,
|
static bool is_volume_on_ssd(const char *volume_mount_point)
|
||||||
sizeof storage_query,
|
{
|
||||||
&trim,
|
char volume_name[MAX_PATH];
|
||||||
sizeof trim,
|
|
||||||
&tmp) && tmp == sizeof trim) {
|
if (!GetVolumeNameForVolumeMountPoint(volume_mount_point, volume_name,
|
||||||
return trim.TrimEnabled;
|
array_elements(volume_name)))
|
||||||
}
|
{
|
||||||
|
/* This can fail, e.g if file is on network share */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Chomp last backslash, this is needed to open volume.*/
|
||||||
|
size_t length= strlen(volume_name);
|
||||||
|
if (length && volume_name[length - 1] == '\\')
|
||||||
|
volume_name[length - 1]= 0;
|
||||||
|
|
||||||
|
/* Open volume handle */
|
||||||
|
HANDLE volume_handle= CreateFile(
|
||||||
|
volume_name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||||
|
|
||||||
|
if (volume_handle == INVALID_HANDLE_VALUE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Enumerate all volume extends, check whether all of them are on SSD
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Anticipate common case where there is only one extent.*/
|
||||||
|
VOLUME_DISK_EXTENTS single_extent;
|
||||||
|
|
||||||
|
/* But also have a place to manage allocated data.*/
|
||||||
|
std::unique_ptr<BYTE[]> lifetime;
|
||||||
|
|
||||||
|
DWORD bytes_written;
|
||||||
|
VOLUME_DISK_EXTENTS *extents= nullptr;
|
||||||
|
if (DeviceIoControl(volume_handle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
|
||||||
|
nullptr, 0, &single_extent, sizeof(single_extent),
|
||||||
|
&bytes_written, nullptr))
|
||||||
|
{
|
||||||
|
/* Worked on the first try. Use the preallocated buffer.*/
|
||||||
|
extents= &single_extent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VOLUME_DISK_EXTENTS *last_query= &single_extent;
|
||||||
|
while (GetLastError() == ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
DWORD extentCount= last_query->NumberOfDiskExtents;
|
||||||
|
DWORD allocatedSize=
|
||||||
|
FIELD_OFFSET(VOLUME_DISK_EXTENTS, Extents[extentCount]);
|
||||||
|
lifetime.reset(new BYTE[allocatedSize]);
|
||||||
|
last_query= (VOLUME_DISK_EXTENTS *) lifetime.get();
|
||||||
|
if (DeviceIoControl(volume_handle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
|
||||||
|
nullptr, 0, last_query, allocatedSize,
|
||||||
|
&bytes_written, nullptr))
|
||||||
|
{
|
||||||
|
extents= last_query;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle(volume_handle);
|
||||||
|
if (!extents)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (DWORD i= 0; i < extents->NumberOfDiskExtents; i++)
|
||||||
|
if (!is_drive_on_ssd(extents->Extents[i].DiskNumber))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
static bool is_file_on_ssd(char *file_path)
|
||||||
|
{
|
||||||
|
/* Cache of volume_path => volume_info, protected by rwlock.*/
|
||||||
|
static std::unordered_map<std::string, bool> cache;
|
||||||
|
static SRWLOCK lock= SRWLOCK_INIT;
|
||||||
|
|
||||||
|
/* Preset result, in case something fails, e.g we're on network drive.*/
|
||||||
|
char volume_path[MAX_PATH];
|
||||||
|
if (!GetVolumePathName(file_path, volume_path, array_elements(volume_path)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Try cached volume info first.*/
|
||||||
|
std::string volume_path_str(volume_path);
|
||||||
|
bool found;
|
||||||
|
bool result;
|
||||||
|
AcquireSRWLockShared(&lock);
|
||||||
|
auto e= cache.find(volume_path_str);
|
||||||
|
if ((found= e != cache.end()))
|
||||||
|
result= e->second;
|
||||||
|
ReleaseSRWLockShared(&lock);
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result= is_volume_on_ssd(volume_path);
|
||||||
|
|
||||||
|
/* Update cache */
|
||||||
|
AcquireSRWLockExclusive(&lock);
|
||||||
|
cache[volume_path_str]= result;
|
||||||
|
ReleaseSRWLockExclusive(&lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Determine some file metadata when creating or reading the file.
|
/** Determine some file metadata when creating or reading the file.
|
||||||
@@ -4361,48 +4441,12 @@ void fil_node_t::find_metadata(os_file_t file
|
|||||||
space->atomic_write_supported = space->purpose == FIL_TYPE_TEMPORARY
|
space->atomic_write_supported = space->purpose == FIL_TYPE_TEMPORARY
|
||||||
|| space->purpose == FIL_TYPE_IMPORT;
|
|| space->purpose == FIL_TYPE_IMPORT;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
block_size = 512;
|
on_ssd = is_file_on_ssd(name);
|
||||||
on_ssd = false;
|
FILE_STORAGE_INFO info;
|
||||||
// Open volume for this file, find out it "physical bytes per sector"
|
if (GetFileInformationByHandleEx(
|
||||||
char volume[MAX_PATH + 4];
|
file, FileStorageInfo, &info, sizeof(info))) {
|
||||||
if (!GetVolumePathName(name, volume + 4, MAX_PATH)) {
|
block_size = info.PhysicalBytesPerSectorForAtomicity;
|
||||||
os_file_handle_error_no_exit(name,
|
|
||||||
"GetVolumePathName()", FALSE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Special prefix required for volume names.
|
|
||||||
memcpy(volume, "\\\\.\\", 4);
|
|
||||||
|
|
||||||
size_t len = strlen(volume);
|
|
||||||
if (volume[len - 1] == '\\') {
|
|
||||||
// Trim trailing backslash from volume name.
|
|
||||||
volume[len - 1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE volume_handle = CreateFile(volume, FILE_READ_ATTRIBUTES,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
0, OPEN_EXISTING, 0, 0);
|
|
||||||
|
|
||||||
if (volume_handle != INVALID_HANDLE_VALUE) {
|
|
||||||
block_size = win32_get_block_size(volume_handle, volume);
|
|
||||||
on_ssd = win32_is_ssd(volume_handle);
|
|
||||||
CloseHandle(volume_handle);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
|
||||||
Report error, unless it is expected, e.g
|
|
||||||
missing permissions, or error when trying to
|
|
||||||
open volume for UNC share.
|
|
||||||
*/
|
|
||||||
if (GetLastError() != ERROR_ACCESS_DENIED
|
|
||||||
&& GetDriveType(volume) == DRIVE_FIXED) {
|
|
||||||
os_file_handle_error_no_exit(volume, "CreateFile()", FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Currently we support file block size up to 4KiB */
|
|
||||||
if (block_size > 4096) {
|
|
||||||
block_size = 4096;
|
|
||||||
} else if (block_size < 512) {
|
|
||||||
block_size = 512;
|
block_size = 512;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@@ -59,12 +59,12 @@ const dtuple_t trx_undo_metadata = {
|
|||||||
static ulint trx_undo_left(const buf_block_t *undo_block, const byte *ptr)
|
static ulint trx_undo_left(const buf_block_t *undo_block, const byte *ptr)
|
||||||
{
|
{
|
||||||
ut_ad(ptr >= &undo_block->frame[TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE]);
|
ut_ad(ptr >= &undo_block->frame[TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE]);
|
||||||
ut_ad(ptr <= &undo_block->frame[srv_page_size - 10 - FIL_PAGE_DATA_END]);
|
|
||||||
|
|
||||||
/* The 10 is supposed to be an extra safety margin (and needed for
|
/* The 10 is supposed to be an extra safety margin (and needed for
|
||||||
compatibility with older versions) */
|
compatibility with older versions) */
|
||||||
return srv_page_size - ulint(ptr - undo_block->frame) -
|
lint left= srv_page_size - (ptr - undo_block->frame) -
|
||||||
(10 + FIL_PAGE_DATA_END);
|
(10 + FIL_PAGE_DATA_END);
|
||||||
|
ut_ad(left >= 0);
|
||||||
|
return left < 0 ? 0 : static_cast<ulint>(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
|
@@ -460,10 +460,6 @@ void trx_t::free()
|
|||||||
MEM_NOACCESS(&xid, sizeof xid);
|
MEM_NOACCESS(&xid, sizeof xid);
|
||||||
MEM_NOACCESS(&mod_tables, sizeof mod_tables);
|
MEM_NOACCESS(&mod_tables, sizeof mod_tables);
|
||||||
MEM_NOACCESS(&detailed_error, sizeof detailed_error);
|
MEM_NOACCESS(&detailed_error, sizeof detailed_error);
|
||||||
MEM_NOACCESS(&n_rec_lock_waits, sizeof n_rec_lock_waits);
|
|
||||||
MEM_NOACCESS(&n_table_lock_waits, sizeof n_table_lock_waits);
|
|
||||||
MEM_NOACCESS(&total_rec_lock_wait_time, sizeof total_rec_lock_wait_time);
|
|
||||||
MEM_NOACCESS(&total_table_lock_wait_time, sizeof total_table_lock_wait_time);
|
|
||||||
MEM_NOACCESS(&magic_n, sizeof magic_n);
|
MEM_NOACCESS(&magic_n, sizeof magic_n);
|
||||||
trx_pools->mem_free(this);
|
trx_pools->mem_free(this);
|
||||||
}
|
}
|
||||||
|
@@ -2360,6 +2360,14 @@ static int initialize_variables_for_repair(HA_CHECK *param,
|
|||||||
{
|
{
|
||||||
MARIA_SHARE *share= info->s;
|
MARIA_SHARE *share= info->s;
|
||||||
|
|
||||||
|
/*
|
||||||
|
We have to clear these variables first, as the cleanup-in-case-of-error
|
||||||
|
handling may touch these.
|
||||||
|
*/
|
||||||
|
bzero((char*) sort_info, sizeof(*sort_info));
|
||||||
|
bzero((char*) sort_param, sizeof(*sort_param));
|
||||||
|
bzero(&info->rec_cache, sizeof(info->rec_cache));
|
||||||
|
|
||||||
if (share->data_file_type == NO_RECORD)
|
if (share->data_file_type == NO_RECORD)
|
||||||
{
|
{
|
||||||
_ma_check_print_error(param,
|
_ma_check_print_error(param,
|
||||||
@@ -2374,9 +2382,6 @@ static int initialize_variables_for_repair(HA_CHECK *param,
|
|||||||
if (share->lock.update_status)
|
if (share->lock.update_status)
|
||||||
(*share->lock.update_status)(info->lock.status_param);
|
(*share->lock.update_status)(info->lock.status_param);
|
||||||
|
|
||||||
bzero((char*) sort_info, sizeof(*sort_info));
|
|
||||||
bzero((char*) sort_param, sizeof(*sort_param));
|
|
||||||
|
|
||||||
param->testflag|= T_REP; /* for easy checking */
|
param->testflag|= T_REP; /* for easy checking */
|
||||||
if (share->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
|
if (share->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
|
||||||
param->testflag|= T_CALC_CHECKSUM;
|
param->testflag|= T_CALC_CHECKSUM;
|
||||||
@@ -2404,7 +2409,6 @@ static int initialize_variables_for_repair(HA_CHECK *param,
|
|||||||
set_data_file_type(sort_info, info->s);
|
set_data_file_type(sort_info, info->s);
|
||||||
sort_info->org_data_file_type= share->data_file_type;
|
sort_info->org_data_file_type= share->data_file_type;
|
||||||
|
|
||||||
bzero(&info->rec_cache, sizeof(info->rec_cache));
|
|
||||||
info->rec_cache.file= info->dfile.file;
|
info->rec_cache.file= info->dfile.file;
|
||||||
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||||
|
|
||||||
@@ -2891,9 +2895,13 @@ err:
|
|||||||
_ma_reset_state(info);
|
_ma_reset_state(info);
|
||||||
|
|
||||||
end_io_cache(¶m->read_cache);
|
end_io_cache(¶m->read_cache);
|
||||||
|
if (sort_info.new_info)
|
||||||
|
{
|
||||||
end_io_cache(&sort_info.new_info->rec_cache);
|
end_io_cache(&sort_info.new_info->rec_cache);
|
||||||
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
|
||||||
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||||
|
}
|
||||||
|
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||||
|
|
||||||
sort_param.sort_info->info->in_check_table= 0;
|
sort_param.sort_info->info->in_check_table= 0;
|
||||||
/* this below could fail, shouldn't we detect error? */
|
/* this below could fail, shouldn't we detect error? */
|
||||||
if (got_error)
|
if (got_error)
|
||||||
@@ -4110,10 +4118,13 @@ err:
|
|||||||
maria_scan_end(sort_info.info);
|
maria_scan_end(sort_info.info);
|
||||||
_ma_reset_state(info);
|
_ma_reset_state(info);
|
||||||
|
|
||||||
|
if (sort_info.new_info)
|
||||||
|
{
|
||||||
end_io_cache(&sort_info.new_info->rec_cache);
|
end_io_cache(&sort_info.new_info->rec_cache);
|
||||||
|
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||||
|
}
|
||||||
end_io_cache(¶m->read_cache);
|
end_io_cache(¶m->read_cache);
|
||||||
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||||
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
|
||||||
if (got_error)
|
if (got_error)
|
||||||
{
|
{
|
||||||
if (! param->error_printed)
|
if (! param->error_printed)
|
||||||
@@ -4642,10 +4653,13 @@ err:
|
|||||||
the share by remove_io_thread() or it was not yet started (if the
|
the share by remove_io_thread() or it was not yet started (if the
|
||||||
error happend before creating the thread).
|
error happend before creating the thread).
|
||||||
*/
|
*/
|
||||||
|
if (sort_info.new_info)
|
||||||
|
{
|
||||||
end_io_cache(&sort_info.new_info->rec_cache);
|
end_io_cache(&sort_info.new_info->rec_cache);
|
||||||
|
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||||
|
}
|
||||||
end_io_cache(¶m->read_cache);
|
end_io_cache(¶m->read_cache);
|
||||||
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||||
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
|
||||||
/*
|
/*
|
||||||
Destroy the new data cache in case of non-quick repair. All slave
|
Destroy the new data cache in case of non-quick repair. All slave
|
||||||
threads did either detach from the share by remove_io_thread()
|
threads did either detach from the share by remove_io_thread()
|
||||||
|
@@ -30,6 +30,7 @@ int maria_delete_table(const char *name)
|
|||||||
{
|
{
|
||||||
MARIA_HA *info;
|
MARIA_HA *info;
|
||||||
myf sync_dir;
|
myf sync_dir;
|
||||||
|
int got_error= 0, error;
|
||||||
DBUG_ENTER("maria_delete_table");
|
DBUG_ENTER("maria_delete_table");
|
||||||
|
|
||||||
#ifdef EXTRA_DEBUG
|
#ifdef EXTRA_DEBUG
|
||||||
@@ -41,9 +42,13 @@ int maria_delete_table(const char *name)
|
|||||||
Unfortunately it is necessary to open the table just to check this. We use
|
Unfortunately it is necessary to open the table just to check this. We use
|
||||||
'open_for_repair' to be able to open even a crashed table.
|
'open_for_repair' to be able to open even a crashed table.
|
||||||
*/
|
*/
|
||||||
|
my_errno= 0;
|
||||||
if (!(info= maria_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR, 0)))
|
if (!(info= maria_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR, 0)))
|
||||||
{
|
{
|
||||||
sync_dir= 0;
|
sync_dir= 0;
|
||||||
|
/* Ignore not found errors and wrong symlink errors */
|
||||||
|
if (my_errno != ENOENT && my_errno != HA_WRONG_CREATE_OPTION)
|
||||||
|
got_error= my_errno;;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -78,7 +83,9 @@ int maria_delete_table(const char *name)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(maria_delete_table_files(name, 0, sync_dir | MY_WME));
|
if (!(error= maria_delete_table_files(name, 0, sync_dir | MY_WME)))
|
||||||
|
error= got_error;
|
||||||
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1476,7 +1476,7 @@ static void setup_key_functions(register MARIA_KEYDEF *keyinfo)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Function to save and store the header in the index file (.MYI)
|
@brief Function to save and store the header in the index file (.MAI)
|
||||||
|
|
||||||
Operates under MARIA_SHARE::intern_lock if requested.
|
Operates under MARIA_SHARE::intern_lock if requested.
|
||||||
Sets MARIA_SHARE::MARIA_STATE_INFO::is_of_horizon if transactional table.
|
Sets MARIA_SHARE::MARIA_STATE_INFO::is_of_horizon if transactional table.
|
||||||
|
Submodule wsrep-lib updated: 2da6e4894e...41a6e9dad7
Reference in New Issue
Block a user