Merge 10.3 into 10.4
This commit is contained in:
commit
0aa02567dd
@ -1177,9 +1177,6 @@ get_options(int *argc,char ***argv)
|
|||||||
if (debug_check_flag)
|
if (debug_check_flag)
|
||||||
my_end_arg= MY_CHECK_ERROR;
|
my_end_arg= MY_CHECK_ERROR;
|
||||||
|
|
||||||
if (!user)
|
|
||||||
user= (char *)"root";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If something is created and --no-drop is not specified, we drop the
|
If something is created and --no-drop is not specified, we drop the
|
||||||
schema.
|
schema.
|
||||||
|
@ -6020,12 +6020,9 @@ static bool xtrabackup_prepare_func(char** argv)
|
|||||||
srv_shutdown_bg_undo_sources();
|
srv_shutdown_bg_undo_sources();
|
||||||
srv_purge_shutdown();
|
srv_purge_shutdown();
|
||||||
buf_flush_sync_all_buf_pools();
|
buf_flush_sync_all_buf_pools();
|
||||||
innodb_shutdown();
|
|
||||||
innobase_space_shutdown();
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
innodb_shutdown();
|
|
||||||
|
|
||||||
|
innodb_shutdown();
|
||||||
innodb_free_param();
|
innodb_free_param();
|
||||||
|
|
||||||
/* output to metadata file */
|
/* output to metadata file */
|
||||||
|
@ -452,8 +452,8 @@ TIME,HOSTNAME,plug,localhost,ID,0,DISCONNECT,,,0
|
|||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT PROXY ON plug_dest TO plug',0
|
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT PROXY ON plug_dest TO plug',0
|
||||||
TIME,HOSTNAME,plug,localhost,ID,0,PROXY_CONNECT,test,`plug_dest`@`%`,0
|
|
||||||
TIME,HOSTNAME,plug,localhost,ID,0,CONNECT,test,,0
|
TIME,HOSTNAME,plug,localhost,ID,0,CONNECT,test,,0
|
||||||
|
TIME,HOSTNAME,plug,localhost,ID,0,PROXY_CONNECT,test,`plug_dest`@`%`,0
|
||||||
TIME,HOSTNAME,plug,localhost,ID,0,DISCONNECT,test,,0
|
TIME,HOSTNAME,plug,localhost,ID,0,DISCONNECT,test,,0
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db,
|
||||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv,
|
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv,
|
||||||
|
@ -666,7 +666,7 @@ create temporary sequence s;
|
|||||||
drop temporary table s;
|
drop temporary table s;
|
||||||
create temporary table s (i int);
|
create temporary table s (i int);
|
||||||
drop temporary sequence s;
|
drop temporary sequence s;
|
||||||
ERROR 42S02: Unknown SEQUENCE: 'test.s'
|
ERROR 42S02: 'test.s' is not a SEQUENCE
|
||||||
drop table s;
|
drop table s;
|
||||||
#
|
#
|
||||||
# MDEV-15115 Assertion failure in CREATE SEQUENCE...ROW_FORMAT=REDUNDANT
|
# MDEV-15115 Assertion failure in CREATE SEQUENCE...ROW_FORMAT=REDUNDANT
|
||||||
|
@ -489,7 +489,7 @@ drop table s;
|
|||||||
create temporary sequence s;
|
create temporary sequence s;
|
||||||
drop temporary table s;
|
drop temporary table s;
|
||||||
create temporary table s (i int);
|
create temporary table s (i int);
|
||||||
--error ER_UNKNOWN_SEQUENCES
|
--error ER_NOT_SEQUENCE2
|
||||||
drop temporary sequence s;
|
drop temporary sequence s;
|
||||||
drop table s;
|
drop table s;
|
||||||
|
|
||||||
|
@ -300,4 +300,63 @@ update t1 set p_first_name='Yunxi' where p_id=1;
|
|||||||
drop view v2;
|
drop view v2;
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
drop sequence s1;
|
drop sequence s1;
|
||||||
|
#
|
||||||
|
# MDEV-19273:Server crash in MDL_ticket::has_stronger_or_equal_type or
|
||||||
|
# Assertion `thd->mdl_context.is_lock_owner(MDL_key::TABLE,
|
||||||
|
# table->db.str, table->table_name.str, MDL_SHARED)' failed
|
||||||
|
# in mysql_rm_table_no_locks
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
CREATE TEMPORARY TABLE tmp (b INT);
|
||||||
|
LOCK TABLE t1 READ;
|
||||||
|
DROP SEQUENCE tmp;
|
||||||
|
ERROR 42S02: 'test.tmp' is not a SEQUENCE
|
||||||
|
DROP TEMPORARY SEQUENCE tmp;
|
||||||
|
ERROR 42S02: 'test.tmp' is not a SEQUENCE
|
||||||
|
DROP SEQUENCE t1;
|
||||||
|
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
|
||||||
|
DROP TEMPORARY SEQUENCE t1;
|
||||||
|
ERROR 42S02: Unknown SEQUENCE: 'test.t1'
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP SEQUENCE t1;
|
||||||
|
ERROR 42S02: 'test.t1' is not a SEQUENCE
|
||||||
|
DROP TEMPORARY SEQUENCE t1;
|
||||||
|
ERROR 42S02: Unknown SEQUENCE: 'test.t1'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t (a INT);
|
||||||
|
CREATE TEMPORARY TABLE s (f INT);
|
||||||
|
CREATE SEQUENCE s;
|
||||||
|
LOCK TABLE t WRITE;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
ERROR 42S02: 'test.s' is not a SEQUENCE
|
||||||
|
DROP TEMPORARY SEQUENCE s;
|
||||||
|
ERROR 42S02: 'test.s' is not a SEQUENCE
|
||||||
|
UNLOCK TABLES;
|
||||||
|
CREATE TEMPORARY SEQUENCE s;
|
||||||
|
LOCK TABLE t WRITE;
|
||||||
|
DROP TEMPORARY SEQUENCE s;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TEMPORARY TABLE s;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
create table s(a INT);
|
||||||
|
CREATE TEMPORARY TABLE s (f INT);
|
||||||
|
LOCK TABLE t WRITE;
|
||||||
|
DROP TEMPORARY TABLE s;
|
||||||
|
CREATE TEMPORARY TABLE s (f INT);
|
||||||
|
DROP TABLE s;
|
||||||
|
DROP TABLE s;
|
||||||
|
ERROR HY000: Table 's' was not locked with LOCK TABLES
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TABLE s;
|
||||||
|
CREATE VIEW v1 as SELECT * FROM t;
|
||||||
|
CREATE SEQUENCE s;
|
||||||
|
DROP SEQUENCE IF EXISTS v1;
|
||||||
|
Warnings:
|
||||||
|
Note 4091 Unknown SEQUENCE: 'test.v1'
|
||||||
|
DROP VIEW IF EXISTS s;
|
||||||
|
Warnings:
|
||||||
|
Note 4092 Unknown VIEW: 'test.s'
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP TABLE t;
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
|
@ -315,4 +315,68 @@ drop view v2;
|
|||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
drop sequence s1;
|
drop sequence s1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-19273:Server crash in MDL_ticket::has_stronger_or_equal_type or
|
||||||
|
--echo # Assertion `thd->mdl_context.is_lock_owner(MDL_key::TABLE,
|
||||||
|
--echo # table->db.str, table->table_name.str, MDL_SHARED)' failed
|
||||||
|
--echo # in mysql_rm_table_no_locks
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
CREATE TEMPORARY TABLE tmp (b INT);
|
||||||
|
LOCK TABLE t1 READ;
|
||||||
|
--error ER_NOT_SEQUENCE2
|
||||||
|
DROP SEQUENCE tmp;
|
||||||
|
--error ER_NOT_SEQUENCE2
|
||||||
|
DROP TEMPORARY SEQUENCE tmp;
|
||||||
|
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||||
|
DROP SEQUENCE t1;
|
||||||
|
--error ER_UNKNOWN_SEQUENCES
|
||||||
|
DROP TEMPORARY SEQUENCE t1;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
--error ER_NOT_SEQUENCE2
|
||||||
|
DROP SEQUENCE t1;
|
||||||
|
--error ER_UNKNOWN_SEQUENCES
|
||||||
|
DROP TEMPORARY SEQUENCE t1;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t (a INT);
|
||||||
|
CREATE TEMPORARY TABLE s (f INT);
|
||||||
|
CREATE SEQUENCE s;
|
||||||
|
LOCK TABLE t WRITE;
|
||||||
|
--error ER_NOT_SEQUENCE2
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
--error ER_NOT_SEQUENCE2
|
||||||
|
DROP TEMPORARY SEQUENCE s;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
CREATE TEMPORARY SEQUENCE s;
|
||||||
|
LOCK TABLE t WRITE;
|
||||||
|
DROP TEMPORARY SEQUENCE s;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TEMPORARY TABLE s;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
|
||||||
|
create table s(a INT);
|
||||||
|
CREATE TEMPORARY TABLE s (f INT);
|
||||||
|
LOCK TABLE t WRITE;
|
||||||
|
DROP TEMPORARY TABLE s;
|
||||||
|
CREATE TEMPORARY TABLE s (f INT);
|
||||||
|
DROP TABLE s;
|
||||||
|
--error ER_TABLE_NOT_LOCKED
|
||||||
|
DROP TABLE s;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TABLE s;
|
||||||
|
|
||||||
|
CREATE VIEW v1 as SELECT * FROM t;
|
||||||
|
CREATE SEQUENCE s;
|
||||||
|
|
||||||
|
DROP SEQUENCE IF EXISTS v1;
|
||||||
|
DROP VIEW IF EXISTS s;
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP TABLE t;
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
@ -70,6 +70,11 @@ returns int
|
|||||||
deterministic
|
deterministic
|
||||||
return sys_trx_end = $sys_datatype_max;
|
return sys_trx_end = $sys_datatype_max;
|
||||||
|
|
||||||
|
eval create or replace function current_row_ts(sys_trx_end timestamp(6))
|
||||||
|
returns int
|
||||||
|
deterministic
|
||||||
|
return convert_tz(sys_trx_end, '+00:00', @@time_zone) = TIMESTAMP'2038-01-19 03:14:07.999999';
|
||||||
|
|
||||||
delimiter ~~;
|
delimiter ~~;
|
||||||
eval create or replace function check_row(row_start $sys_datatype_expl, row_end $sys_datatype_expl)
|
eval create or replace function check_row(row_start $sys_datatype_expl, row_end $sys_datatype_expl)
|
||||||
returns varchar(255)
|
returns varchar(255)
|
||||||
@ -86,4 +91,20 @@ begin
|
|||||||
end~~
|
end~~
|
||||||
delimiter ;~~
|
delimiter ;~~
|
||||||
|
|
||||||
|
delimiter ~~;
|
||||||
|
eval create or replace function check_row_ts(row_start timestamp(6), row_end timestamp(6))
|
||||||
|
returns varchar(255)
|
||||||
|
deterministic
|
||||||
|
begin
|
||||||
|
if row_end < row_start then
|
||||||
|
return "ERROR: row_end < row_start";
|
||||||
|
elseif row_end = row_start then
|
||||||
|
return "ERROR: row_end == row_start";
|
||||||
|
elseif current_row_ts(row_end) then
|
||||||
|
return "CURRENT ROW";
|
||||||
|
end if;
|
||||||
|
return "HISTORICAL ROW";
|
||||||
|
end~~
|
||||||
|
delimiter ;~~
|
||||||
|
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
@ -4,5 +4,7 @@ drop procedure if exists verify_trt;
|
|||||||
drop procedure if exists verify_trt_dummy;
|
drop procedure if exists verify_trt_dummy;
|
||||||
drop function if exists current_row;
|
drop function if exists current_row;
|
||||||
drop function if exists check_row;
|
drop function if exists check_row;
|
||||||
|
drop function if exists current_row_ts;
|
||||||
|
drop function if exists check_row_ts;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
@ -130,3 +130,22 @@ ERROR 42S02: Table 'test.xx' doesn't exist
|
|||||||
drop procedure pr;
|
drop procedure pr;
|
||||||
drop trigger tr;
|
drop trigger tr;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-21138 Assertion `col->ord_part' or `f.col->ord_part' failed in row_build_index_entry_low
|
||||||
|
#
|
||||||
|
create table t1 (
|
||||||
|
f1 int, f2 text, f3 int, fulltext (f2), key(f1), key(f3),
|
||||||
|
foreign key r (f3) references t1 (f1) on delete set null)
|
||||||
|
with system versioning engine innodb;
|
||||||
|
insert into t1 values (1, repeat('a', 8193), 1), (1, repeat('b', 8193), 1);
|
||||||
|
select f1, f3, check_row_ts(row_start, row_end) from t1;
|
||||||
|
f1 f3 check_row_ts(row_start, row_end)
|
||||||
|
1 1 CURRENT ROW
|
||||||
|
1 1 CURRENT ROW
|
||||||
|
delete from t1;
|
||||||
|
select f1, f3, check_row_ts(row_start, row_end) from t1 for system_time all;
|
||||||
|
f1 f3 check_row_ts(row_start, row_end)
|
||||||
|
1 1 HISTORICAL ROW
|
||||||
|
1 NULL ERROR: row_end == row_start
|
||||||
|
1 1 HISTORICAL ROW
|
||||||
|
drop table t1;
|
||||||
|
@ -400,6 +400,8 @@ Warning 1265 Data truncated for column 'f12' at row 7
|
|||||||
SET timestamp = 9;
|
SET timestamp = 9;
|
||||||
REPLACE INTO t2 SELECT * FROM t2;
|
REPLACE INTO t2 SELECT * FROM t2;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
set timestamp= default;
|
||||||
|
set time_zone='+00:00';
|
||||||
#
|
#
|
||||||
# MDEV-16210 FK constraints on versioned tables use historical rows, which may cause constraint violation
|
# MDEV-16210 FK constraints on versioned tables use historical rows, which may cause constraint violation
|
||||||
#
|
#
|
||||||
@ -429,3 +431,17 @@ insert into t2 values (1), (1);
|
|||||||
# DELETE from foreign table is allowed
|
# DELETE from foreign table is allowed
|
||||||
delete from t2;
|
delete from t2;
|
||||||
drop tables t2, t1;
|
drop tables t2, t1;
|
||||||
|
#
|
||||||
|
# MDEV-23644 Assertion on evaluating foreign referential action for self-reference in system versioned table
|
||||||
|
#
|
||||||
|
create table t1 (pk int primary key, f1 int,f2 int, f3 text,
|
||||||
|
key(f1), fulltext(f3), key(f3(10)),
|
||||||
|
foreign key (f2) references t1 (f1) on delete set null
|
||||||
|
) engine=innodb with system versioning;
|
||||||
|
insert into t1 values (1, 8, 8, 'SHORT'), (2, 8, 8, repeat('LONG', 8071));
|
||||||
|
delete from t1;
|
||||||
|
select pk, f1, f2, left(f3, 4), check_row_ts(row_start, row_end) from t1 for system_time all order by pk;
|
||||||
|
pk f1 f2 left(f3, 4) check_row_ts(row_start, row_end)
|
||||||
|
1 8 8 SHOR HISTORICAL ROW
|
||||||
|
2 8 8 LONG HISTORICAL ROW
|
||||||
|
drop table t1;
|
||||||
|
@ -691,6 +691,13 @@ create table t1 (a int) with system versioning partition by system_time
|
|||||||
alter table t1 add partition (partition p2);
|
alter table t1 add partition (partition p2);
|
||||||
ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME`
|
ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME`
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS
|
||||||
|
#
|
||||||
|
create or replace table t1 (a int) with system versioning;
|
||||||
|
alter table t1 partition by system_time (partition pn current);
|
||||||
|
ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT
|
||||||
|
drop table t1;
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
# MDEV-22283 Server crashes in key_copy or unexpected error 156: The table already existed in the storage engine
|
# MDEV-22283 Server crashes in key_copy or unexpected error 156: The table already existed in the storage engine
|
||||||
|
@ -5,7 +5,15 @@ sys_trx_start bigint(20) unsigned as row start invisible,
|
|||||||
sys_trx_end bigint(20) unsigned as row end invisible,
|
sys_trx_end bigint(20) unsigned as row end invisible,
|
||||||
period for system_time (sys_trx_start, sys_trx_end)
|
period for system_time (sys_trx_start, sys_trx_end)
|
||||||
) with system versioning;
|
) with system versioning;
|
||||||
|
# No history inside the transaction
|
||||||
|
start transaction;
|
||||||
insert into t1 (x) values (1);
|
insert into t1 (x) values (1);
|
||||||
|
update t1 set x= x + 1;
|
||||||
|
update t1 set x= x + 1;
|
||||||
|
commit;
|
||||||
|
select *, sys_trx_start > 1, sys_trx_end from t1 for system_time all;
|
||||||
|
x sys_trx_start > 1 sys_trx_end
|
||||||
|
3 1 18446744073709551615
|
||||||
# ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry
|
# ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry
|
||||||
set @@system_versioning_alter_history=keep;
|
set @@system_versioning_alter_history=keep;
|
||||||
create or replace table t1 (x int);
|
create or replace table t1 (x int);
|
||||||
|
@ -241,6 +241,26 @@ B2 salary
|
|||||||
1 2500
|
1 2500
|
||||||
drop table t1;
|
drop table t1;
|
||||||
drop table t2;
|
drop table t2;
|
||||||
|
# Ensure FTS retains correct history
|
||||||
|
create table t1 (
|
||||||
|
x int, y text, fulltext (y),
|
||||||
|
row_start SYS_DATATYPE as row start invisible,
|
||||||
|
row_end SYS_DATATYPE as row end invisible,
|
||||||
|
period for system_time (row_start, row_end))
|
||||||
|
with system versioning engine innodb;
|
||||||
|
insert into t1 values (1, repeat('LONG', 2048));
|
||||||
|
update t1 set x= x + 1;
|
||||||
|
select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y;
|
||||||
|
x left(y, 4) length(y) check_row(row_start, row_end)
|
||||||
|
1 LONG 8192 HISTORICAL ROW
|
||||||
|
2 LONG 8192 CURRENT ROW
|
||||||
|
update t1 set y= 'SHORT';
|
||||||
|
select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y;
|
||||||
|
x left(y, 4) length(y) check_row(row_start, row_end)
|
||||||
|
1 LONG 8192 HISTORICAL ROW
|
||||||
|
2 LONG 8192 HISTORICAL ROW
|
||||||
|
2 SHOR 5 CURRENT ROW
|
||||||
|
drop tables t1;
|
||||||
### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row)
|
### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row)
|
||||||
create or replace table t1 (a int primary key, b int)
|
create or replace table t1 (a int primary key, b int)
|
||||||
with system versioning engine myisam;
|
with system versioning engine myisam;
|
||||||
@ -350,3 +370,32 @@ insert into t1 (a) values (1), (2);
|
|||||||
update ignore t1 set a= 3;
|
update ignore t1 set a= 3;
|
||||||
delete history from t1;
|
delete history from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-23446 UPDATE does not insert history row if the row is not changed
|
||||||
|
#
|
||||||
|
create table t1 (
|
||||||
|
a int,
|
||||||
|
row_start SYS_DATATYPE as row start invisible,
|
||||||
|
row_end SYS_DATATYPE as row end invisible,
|
||||||
|
period for system_time (row_start, row_end)) with system versioning;
|
||||||
|
insert into t1 values (1);
|
||||||
|
update t1 set a= 1;
|
||||||
|
select *, check_row(row_start, row_end) from t1 for system_time all order by row_end;
|
||||||
|
a check_row(row_start, row_end)
|
||||||
|
1 HISTORICAL ROW
|
||||||
|
1 CURRENT ROW
|
||||||
|
# multi-update
|
||||||
|
create or replace table t2 like t1;
|
||||||
|
create or replace table t3 like t1;
|
||||||
|
insert into t2 values (1);
|
||||||
|
insert into t3 values (1);
|
||||||
|
update t2, t3 set t2.a= 1, t3.a= 1 where t2.a = t3.a;
|
||||||
|
select *, check_row(row_start, row_end) from t2 for system_time all order by row_end;
|
||||||
|
a check_row(row_start, row_end)
|
||||||
|
1 HISTORICAL ROW
|
||||||
|
1 CURRENT ROW
|
||||||
|
select *, check_row(row_start, row_end) from t2 for system_time all order by row_end;
|
||||||
|
a check_row(row_start, row_end)
|
||||||
|
1 HISTORICAL ROW
|
||||||
|
1 CURRENT ROW
|
||||||
|
drop tables t1, t2, t3;
|
||||||
|
@ -94,4 +94,19 @@ drop procedure pr;
|
|||||||
drop trigger tr;
|
drop trigger tr;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-21138 Assertion `col->ord_part' or `f.col->ord_part' failed in row_build_index_entry_low
|
||||||
|
--echo #
|
||||||
|
create table t1 (
|
||||||
|
f1 int, f2 text, f3 int, fulltext (f2), key(f1), key(f3),
|
||||||
|
foreign key r (f3) references t1 (f1) on delete set null)
|
||||||
|
with system versioning engine innodb;
|
||||||
|
insert into t1 values (1, repeat('a', 8193), 1), (1, repeat('b', 8193), 1);
|
||||||
|
select f1, f3, check_row_ts(row_start, row_end) from t1;
|
||||||
|
delete from t1;
|
||||||
|
select f1, f3, check_row_ts(row_start, row_end) from t1 for system_time all;
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--source suite/versioning/common_finish.inc
|
--source suite/versioning/common_finish.inc
|
||||||
|
@ -421,6 +421,8 @@ REPLACE INTO t2 SELECT * FROM t2;
|
|||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
set timestamp= default;
|
||||||
|
set time_zone='+00:00';
|
||||||
--let $datadir= `select @@datadir`
|
--let $datadir= `select @@datadir`
|
||||||
--remove_file $datadir/test/t1.data
|
--remove_file $datadir/test/t1.data
|
||||||
--remove_file $datadir/test/t1.data.2
|
--remove_file $datadir/test/t1.data.2
|
||||||
@ -458,4 +460,20 @@ insert into t2 values (1), (1);
|
|||||||
delete from t2;
|
delete from t2;
|
||||||
drop tables t2, t1;
|
drop tables t2, t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-23644 Assertion on evaluating foreign referential action for self-reference in system versioned table
|
||||||
|
--echo #
|
||||||
|
create table t1 (pk int primary key, f1 int,f2 int, f3 text,
|
||||||
|
key(f1), fulltext(f3), key(f3(10)),
|
||||||
|
foreign key (f2) references t1 (f1) on delete set null
|
||||||
|
) engine=innodb with system versioning;
|
||||||
|
|
||||||
|
insert into t1 values (1, 8, 8, 'SHORT'), (2, 8, 8, repeat('LONG', 8071));
|
||||||
|
|
||||||
|
delete from t1;
|
||||||
|
select pk, f1, f2, left(f3, 4), check_row_ts(row_start, row_end) from t1 for system_time all order by pk;
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--source suite/versioning/common_finish.inc
|
--source suite/versioning/common_finish.inc
|
||||||
|
@ -643,6 +643,15 @@ alter table t1 add partition (partition p2);
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS
|
||||||
|
--echo #
|
||||||
|
create or replace table t1 (a int) with system versioning;
|
||||||
|
--error ER_VERS_WRONG_PARTS
|
||||||
|
alter table t1 partition by system_time (partition pn current);
|
||||||
|
# Cleanup
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -14,7 +14,13 @@ create or replace table t1 (
|
|||||||
period for system_time (sys_trx_start, sys_trx_end)
|
period for system_time (sys_trx_start, sys_trx_end)
|
||||||
) with system versioning;
|
) with system versioning;
|
||||||
|
|
||||||
|
--echo # No history inside the transaction
|
||||||
|
start transaction;
|
||||||
insert into t1 (x) values (1);
|
insert into t1 (x) values (1);
|
||||||
|
update t1 set x= x + 1;
|
||||||
|
update t1 set x= x + 1;
|
||||||
|
commit;
|
||||||
|
select *, sys_trx_start > 1, sys_trx_end from t1 for system_time all;
|
||||||
|
|
||||||
--echo # ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry
|
--echo # ALTER ADD SYSTEM VERSIONING should write to mysql.transaction_registry
|
||||||
set @@system_versioning_alter_history=keep;
|
set @@system_versioning_alter_history=keep;
|
||||||
|
@ -147,6 +147,21 @@ select @tmp2 = sys_trx_start as B2, salary from t2;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
drop table t2;
|
drop table t2;
|
||||||
|
|
||||||
|
--echo # Ensure FTS retains correct history
|
||||||
|
replace_result $sys_datatype_expl SYS_DATATYPE;
|
||||||
|
eval create table t1 (
|
||||||
|
x int, y text, fulltext (y),
|
||||||
|
row_start $sys_datatype_expl as row start invisible,
|
||||||
|
row_end $sys_datatype_expl as row end invisible,
|
||||||
|
period for system_time (row_start, row_end))
|
||||||
|
with system versioning engine innodb;
|
||||||
|
insert into t1 values (1, repeat('LONG', 2048));
|
||||||
|
update t1 set x= x + 1;
|
||||||
|
select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y;
|
||||||
|
update t1 set y= 'SHORT';
|
||||||
|
select x, left(y, 4), length(y), check_row(row_start, row_end) from t1 for system_time all order by x, y;
|
||||||
|
drop tables t1;
|
||||||
|
|
||||||
--echo ### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row)
|
--echo ### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row)
|
||||||
create or replace table t1 (a int primary key, b int)
|
create or replace table t1 (a int primary key, b int)
|
||||||
with system versioning engine myisam;
|
with system versioning engine myisam;
|
||||||
@ -286,4 +301,29 @@ delete history from t1;
|
|||||||
# cleanup
|
# cleanup
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-23446 UPDATE does not insert history row if the row is not changed
|
||||||
|
--echo #
|
||||||
|
replace_result $sys_datatype_expl SYS_DATATYPE;
|
||||||
|
eval create table t1 (
|
||||||
|
a int,
|
||||||
|
row_start $sys_datatype_expl as row start invisible,
|
||||||
|
row_end $sys_datatype_expl as row end invisible,
|
||||||
|
period for system_time (row_start, row_end)) with system versioning;
|
||||||
|
insert into t1 values (1);
|
||||||
|
update t1 set a= 1;
|
||||||
|
select *, check_row(row_start, row_end) from t1 for system_time all order by row_end;
|
||||||
|
|
||||||
|
--echo # multi-update
|
||||||
|
create or replace table t2 like t1;
|
||||||
|
create or replace table t3 like t1;
|
||||||
|
insert into t2 values (1);
|
||||||
|
insert into t3 values (1);
|
||||||
|
update t2, t3 set t2.a= 1, t3.a= 1 where t2.a = t3.a;
|
||||||
|
select *, check_row(row_start, row_end) from t2 for system_time all order by row_end;
|
||||||
|
select *, check_row(row_start, row_end) from t2 for system_time all order by row_end;
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
drop tables t1, t2, t3;
|
||||||
|
|
||||||
source suite/versioning/common_finish.inc;
|
source suite/versioning/common_finish.inc;
|
||||||
|
@ -115,6 +115,7 @@ static int prepare_for_fill(TABLE_LIST *tables)
|
|||||||
|
|
||||||
tables->init_one_table(&INFORMATION_SCHEMA_NAME, &tbl_name, 0, TL_READ);
|
tables->init_one_table(&INFORMATION_SCHEMA_NAME, &tbl_name, 0, TL_READ);
|
||||||
tables->schema_table= i_s_feedback;
|
tables->schema_table= i_s_feedback;
|
||||||
|
tables->schema_table_reformed= 1;
|
||||||
tables->select_lex= thd->lex->first_select_lex();
|
tables->select_lex= thd->lex->first_select_lex();
|
||||||
DBUG_ASSERT(tables->select_lex);
|
DBUG_ASSERT(tables->select_lex);
|
||||||
tables->table= create_schema_table(thd, tables);
|
tables->table= create_schema_table(thd, tables);
|
||||||
|
@ -2070,13 +2070,9 @@ static void update_connection_info(struct connection_info *cn,
|
|||||||
{
|
{
|
||||||
case MYSQL_AUDIT_CONNECTION_CONNECT:
|
case MYSQL_AUDIT_CONNECTION_CONNECT:
|
||||||
setup_connection_connect(cn, event);
|
setup_connection_connect(cn, event);
|
||||||
if (event->status == 0 && event->proxy_user && event->proxy_user[0])
|
|
||||||
log_proxy(cn, event);
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_AUDIT_CONNECTION_CHANGE_USER:
|
case MYSQL_AUDIT_CONNECTION_CHANGE_USER:
|
||||||
*after_action= AA_CHANGE_USER;
|
*after_action= AA_CHANGE_USER;
|
||||||
if (event->proxy_user && event->proxy_user[0])
|
|
||||||
log_proxy(cn, event);
|
|
||||||
break;
|
break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
@ -2194,6 +2190,8 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev)
|
|||||||
{
|
{
|
||||||
case MYSQL_AUDIT_CONNECTION_CONNECT:
|
case MYSQL_AUDIT_CONNECTION_CONNECT:
|
||||||
log_connection(cn, event, event->status ? "FAILED_CONNECT": "CONNECT");
|
log_connection(cn, event, event->status ? "FAILED_CONNECT": "CONNECT");
|
||||||
|
if (event->status == 0 && event->proxy_user && event->proxy_user[0])
|
||||||
|
log_proxy(cn, event);
|
||||||
break;
|
break;
|
||||||
case MYSQL_AUDIT_CONNECTION_DISCONNECT:
|
case MYSQL_AUDIT_CONNECTION_DISCONNECT:
|
||||||
if (use_event_data_for_disconnect)
|
if (use_event_data_for_disconnect)
|
||||||
@ -2203,6 +2201,8 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev)
|
|||||||
break;
|
break;
|
||||||
case MYSQL_AUDIT_CONNECTION_CHANGE_USER:
|
case MYSQL_AUDIT_CONNECTION_CHANGE_USER:
|
||||||
log_connection(cn, event, "CHANGEUSER");
|
log_connection(cn, event, "CHANGEUSER");
|
||||||
|
if (event->proxy_user && event->proxy_user[0])
|
||||||
|
log_proxy(cn, event);
|
||||||
break;
|
break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1149,7 @@ bool JOIN_TAB::fix_splitting(SplM_plan_info *spl_plan,
|
|||||||
bool JOIN::fix_all_splittings_in_plan()
|
bool JOIN::fix_all_splittings_in_plan()
|
||||||
{
|
{
|
||||||
table_map prev_tables= 0;
|
table_map prev_tables= 0;
|
||||||
table_map all_tables= (1 << table_count) - 1;
|
table_map all_tables= (table_map(1) << table_count) - 1;
|
||||||
for (uint tablenr= 0; tablenr < table_count; tablenr++)
|
for (uint tablenr= 0; tablenr < table_count; tablenr++)
|
||||||
{
|
{
|
||||||
POSITION *cur_pos= &best_positions[tablenr];
|
POSITION *cur_pos= &best_positions[tablenr];
|
||||||
|
@ -293,7 +293,15 @@ int TABLE::delete_row()
|
|||||||
|
|
||||||
store_record(this, record[1]);
|
store_record(this, record[1]);
|
||||||
vers_update_end();
|
vers_update_end();
|
||||||
return file->ha_update_row(record[1], record[0]);
|
int err= file->ha_update_row(record[1], record[0]);
|
||||||
|
/*
|
||||||
|
MDEV-23644: we get HA_ERR_FOREIGN_DUPLICATE_KEY iff we already got history
|
||||||
|
row with same trx_id which is the result of foreign key action, so we
|
||||||
|
don't need one more history row.
|
||||||
|
*/
|
||||||
|
if (err == HA_ERR_FOREIGN_DUPLICATE_KEY)
|
||||||
|
return file->ha_delete_row(record[0]);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2701,7 +2701,7 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
|
|||||||
delayed_row *row= 0;
|
delayed_row *row= 0;
|
||||||
Delayed_insert *di=thd->di;
|
Delayed_insert *di=thd->di;
|
||||||
const Discrete_interval *forced_auto_inc;
|
const Discrete_interval *forced_auto_inc;
|
||||||
size_t user_len, host_len, ip_len;
|
size_t user_len, host_len, ip_length;
|
||||||
DBUG_ENTER("write_delayed");
|
DBUG_ENTER("write_delayed");
|
||||||
DBUG_PRINT("enter", ("query = '%s' length %lu", query.str,
|
DBUG_PRINT("enter", ("query = '%s' length %lu", query.str,
|
||||||
(ulong) query.length));
|
(ulong) query.length));
|
||||||
@ -2735,7 +2735,7 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
user_len= host_len= ip_len= 0;
|
user_len= host_len= ip_length= 0;
|
||||||
row->user= row->host= row->ip= NULL;
|
row->user= row->host= row->ip= NULL;
|
||||||
if (thd->security_ctx)
|
if (thd->security_ctx)
|
||||||
{
|
{
|
||||||
@ -2744,11 +2744,11 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
|
|||||||
if (thd->security_ctx->host)
|
if (thd->security_ctx->host)
|
||||||
host_len= strlen(thd->security_ctx->host) + 1;
|
host_len= strlen(thd->security_ctx->host) + 1;
|
||||||
if (thd->security_ctx->ip)
|
if (thd->security_ctx->ip)
|
||||||
ip_len= strlen(thd->security_ctx->ip) + 1;
|
ip_length= strlen(thd->security_ctx->ip) + 1;
|
||||||
}
|
}
|
||||||
/* This can't be THREAD_SPECIFIC as it's freed in delayed thread */
|
/* This can't be THREAD_SPECIFIC as it's freed in delayed thread */
|
||||||
if (!(row->record= (char*) my_malloc(table->s->reclength +
|
if (!(row->record= (char*) my_malloc(table->s->reclength +
|
||||||
user_len + host_len + ip_len,
|
user_len + host_len + ip_length,
|
||||||
MYF(MY_WME))))
|
MYF(MY_WME))))
|
||||||
goto err;
|
goto err;
|
||||||
memcpy(row->record, table->record[0], table->s->reclength);
|
memcpy(row->record, table->record[0], table->s->reclength);
|
||||||
@ -2768,7 +2768,7 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
|
|||||||
if (thd->security_ctx->ip)
|
if (thd->security_ctx->ip)
|
||||||
{
|
{
|
||||||
row->ip= row->record + table->s->reclength + user_len + host_len;
|
row->ip= row->record + table->s->reclength + user_len + host_len;
|
||||||
memcpy(row->ip, thd->security_ctx->ip, ip_len);
|
memcpy(row->ip, thd->security_ctx->ip, ip_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row->query_id= thd->query_id;
|
row->query_id= thd->query_id;
|
||||||
|
@ -2304,8 +2304,11 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
{
|
{
|
||||||
bool is_trans= 0;
|
bool is_trans= 0;
|
||||||
bool table_creation_was_logged= 0;
|
bool table_creation_was_logged= 0;
|
||||||
|
bool real_table= FALSE;
|
||||||
LEX_CSTRING db= table->db;
|
LEX_CSTRING db= table->db;
|
||||||
handlerton *table_type= 0;
|
handlerton *table_type= 0;
|
||||||
|
// reset error state for this table
|
||||||
|
error= 0;
|
||||||
|
|
||||||
DBUG_PRINT("table", ("table_l: '%s'.'%s' table: %p s: %p",
|
DBUG_PRINT("table", ("table_l: '%s'.'%s' table: %p s: %p",
|
||||||
table->db.str, table->table_name.str, table->table,
|
table->db.str, table->table_name.str, table->table,
|
||||||
@ -2321,9 +2324,35 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
thd->find_temporary_table(table) &&
|
thd->find_temporary_table(table) &&
|
||||||
table->mdl_request.ticket != NULL));
|
table->mdl_request.ticket != NULL));
|
||||||
|
|
||||||
if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table) ||
|
if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table))
|
||||||
(drop_sequence && table->table->s->table_type != TABLE_TYPE_SEQUENCE))
|
real_table= TRUE;
|
||||||
|
else if (drop_sequence &&
|
||||||
|
table->table->s->table_type != TABLE_TYPE_SEQUENCE)
|
||||||
|
{
|
||||||
|
was_table= (table->table->s->table_type == TABLE_TYPE_NORMAL);
|
||||||
|
was_view= (table->table->s->table_type == TABLE_TYPE_VIEW);
|
||||||
|
if (if_exists)
|
||||||
|
{
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
String tbl_name(buff, sizeof(buff), system_charset_info);
|
||||||
|
tbl_name.length(0);
|
||||||
|
tbl_name.append(&db);
|
||||||
|
tbl_name.append('.');
|
||||||
|
tbl_name.append(&table->table_name);
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||||
|
ER_NOT_SEQUENCE2, ER_THD(thd, ER_NOT_SEQUENCE2),
|
||||||
|
tbl_name.c_ptr_safe());
|
||||||
|
|
||||||
|
/*
|
||||||
|
Our job is done here. This statement was added to avoid executing
|
||||||
|
unnecessary code farther below which in some strange corner cases
|
||||||
|
caused the server to crash (see MDEV-17896).
|
||||||
|
*/
|
||||||
|
goto log_query;
|
||||||
|
}
|
||||||
error= 1;
|
error= 1;
|
||||||
|
goto non_critical_err;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table_creation_was_logged= table->table->s->table_creation_was_logged;
|
table_creation_was_logged= table->table->s->table_creation_was_logged;
|
||||||
@ -2332,29 +2361,28 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
error= 1;
|
error= 1;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
error= 0;
|
|
||||||
table->table= 0;
|
table->table= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((drop_temporary && if_exists) || !error)
|
if ((drop_temporary && if_exists) || !real_table)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This handles the case of temporary tables. We have the following cases:
|
This handles the case of temporary tables. We have the following cases:
|
||||||
|
|
||||||
. "DROP TEMPORARY" was executed and a temporary table was affected
|
. "DROP TEMPORARY" was executed and a temporary table was affected
|
||||||
(i.e. drop_temporary && !error) or the if_exists was specified (i.e.
|
(i.e. drop_temporary && !real_table) or the
|
||||||
drop_temporary && if_exists).
|
if_exists was specified (i.e. drop_temporary && if_exists).
|
||||||
|
|
||||||
. "DROP" was executed but a temporary table was affected (.i.e
|
. "DROP" was executed but a temporary table was affected (.i.e
|
||||||
!error).
|
!real_table).
|
||||||
*/
|
*/
|
||||||
if (!dont_log_query && table_creation_was_logged)
|
if (!dont_log_query && table_creation_was_logged)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
If there is an error, we don't know the type of the engine
|
If there is an real_table, we don't know the type of the engine
|
||||||
at this point. So, we keep it in the trx-cache.
|
at this point. So, we keep it in the trx-cache.
|
||||||
*/
|
*/
|
||||||
is_trans= error ? TRUE : is_trans;
|
is_trans= real_table ? TRUE : is_trans;
|
||||||
if (is_trans)
|
if (is_trans)
|
||||||
trans_tmp_table_deleted= TRUE;
|
trans_tmp_table_deleted= TRUE;
|
||||||
else
|
else
|
||||||
@ -2381,7 +2409,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
is no need to proceed with the code that tries to drop a regular
|
is no need to proceed with the code that tries to drop a regular
|
||||||
table.
|
table.
|
||||||
*/
|
*/
|
||||||
if (!error) continue;
|
if (!real_table) continue;
|
||||||
}
|
}
|
||||||
else if (!drop_temporary)
|
else if (!drop_temporary)
|
||||||
{
|
{
|
||||||
@ -2397,7 +2425,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
reg_ext, 0);
|
reg_ext, 0);
|
||||||
}
|
}
|
||||||
DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
|
DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
|
||||||
error= 0;
|
|
||||||
if (drop_temporary ||
|
if (drop_temporary ||
|
||||||
(ha_table_exists(thd, &db, &alias, &table_type, &is_sequence) == 0 &&
|
(ha_table_exists(thd, &db, &alias, &table_type, &is_sequence) == 0 &&
|
||||||
table_type == 0) ||
|
table_type == 0) ||
|
||||||
@ -2437,6 +2464,11 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
{
|
{
|
||||||
non_tmp_error = (drop_temporary ? non_tmp_error : TRUE);
|
non_tmp_error = (drop_temporary ? non_tmp_error : TRUE);
|
||||||
error= 1;
|
error= 1;
|
||||||
|
/*
|
||||||
|
non critical error (only for this table), so we continue.
|
||||||
|
Next we write it to wrong_tables and continue this loop
|
||||||
|
The same as "goto non_critical_err".
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2530,7 +2562,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
}
|
}
|
||||||
non_tmp_error|= MY_TEST(error);
|
non_tmp_error|= MY_TEST(error);
|
||||||
}
|
}
|
||||||
|
non_critical_err:
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
if (wrong_tables.length())
|
if (wrong_tables.length())
|
||||||
@ -10031,6 +10063,7 @@ do_continue:;
|
|||||||
|
|
||||||
tmp_disable_binlog(thd);
|
tmp_disable_binlog(thd);
|
||||||
create_info->options|=HA_CREATE_TMP_ALTER;
|
create_info->options|=HA_CREATE_TMP_ALTER;
|
||||||
|
create_info->alias= alter_ctx.table_name;
|
||||||
error= create_table_impl(thd, alter_ctx.db, alter_ctx.table_name,
|
error= create_table_impl(thd, alter_ctx.db, alter_ctx.table_name,
|
||||||
alter_ctx.new_db, alter_ctx.tmp_name,
|
alter_ctx.new_db, alter_ctx.tmp_name,
|
||||||
alter_ctx.get_tmp_path(),
|
alter_ctx.get_tmp_path(),
|
||||||
|
@ -8633,11 +8633,18 @@ LEX_CSTRING Charset::collation_specific_name() const
|
|||||||
for character sets and collations, so a collation
|
for character sets and collations, so a collation
|
||||||
name not necessarily starts with the character set name.
|
name not necessarily starts with the character set name.
|
||||||
*/
|
*/
|
||||||
|
LEX_CSTRING retval;
|
||||||
size_t csname_length= strlen(m_charset->csname);
|
size_t csname_length= strlen(m_charset->csname);
|
||||||
if (strncmp(m_charset->name, m_charset->csname, csname_length))
|
if (strncmp(m_charset->name, m_charset->csname, csname_length))
|
||||||
return {NULL, 0};
|
{
|
||||||
|
retval.str= NULL;
|
||||||
|
retval.length= 0;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
const char *ptr= m_charset->name + csname_length;
|
const char *ptr= m_charset->name + csname_length;
|
||||||
return {ptr, strlen(ptr) };
|
retval.str= ptr;
|
||||||
|
retval.length= strlen(ptr);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,8 +52,9 @@
|
|||||||
compare_record(TABLE*).
|
compare_record(TABLE*).
|
||||||
*/
|
*/
|
||||||
bool records_are_comparable(const TABLE *table) {
|
bool records_are_comparable(const TABLE *table) {
|
||||||
return ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) ||
|
return !table->versioned(VERS_TRX_ID) &&
|
||||||
bitmap_is_subset(table->write_set, table->read_set);
|
(((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) ||
|
||||||
|
bitmap_is_subset(table->write_set, table->read_set));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1081,20 +1082,9 @@ update_begin:
|
|||||||
}
|
}
|
||||||
else if (likely(!error))
|
else if (likely(!error))
|
||||||
{
|
{
|
||||||
if (has_vers_fields && table->versioned())
|
if (has_vers_fields && table->versioned(VERS_TRX_ID))
|
||||||
{
|
rows_inserted++;
|
||||||
if (table->versioned(VERS_TIMESTAMP))
|
updated++;
|
||||||
{
|
|
||||||
store_record(table, record[2]);
|
|
||||||
table->mark_columns_per_binlog_row_image();
|
|
||||||
error= vers_insert_history_row(table);
|
|
||||||
restore_record(table, record[2]);
|
|
||||||
}
|
|
||||||
if (likely(!error))
|
|
||||||
rows_inserted++;
|
|
||||||
}
|
|
||||||
if (likely(!error))
|
|
||||||
updated++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(!error) && !record_was_same && table_list->has_period())
|
if (likely(!error) && !record_was_same && table_list->has_period())
|
||||||
@ -1110,6 +1100,19 @@ update_begin:
|
|||||||
if (unlikely(error) &&
|
if (unlikely(error) &&
|
||||||
(!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL)))
|
(!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL)))
|
||||||
{
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (likely(!error) && has_vers_fields && table->versioned(VERS_TIMESTAMP))
|
||||||
|
{
|
||||||
|
store_record(table, record[2]);
|
||||||
|
table->mark_columns_per_binlog_row_image();
|
||||||
|
error= vers_insert_history_row(table);
|
||||||
|
restore_record(table, record[2]);
|
||||||
|
if (unlikely(error))
|
||||||
|
{
|
||||||
|
error:
|
||||||
/*
|
/*
|
||||||
If (ignore && error is ignorable) we don't have to
|
If (ignore && error is ignorable) we don't have to
|
||||||
do anything; otherwise...
|
do anything; otherwise...
|
||||||
@ -1120,10 +1123,11 @@ update_begin:
|
|||||||
flags|= ME_FATAL; /* Other handler errors are fatal */
|
flags|= ME_FATAL; /* Other handler errors are fatal */
|
||||||
|
|
||||||
prepare_record_for_error_message(error, table);
|
prepare_record_for_error_message(error, table);
|
||||||
table->file->print_error(error,MYF(flags));
|
table->file->print_error(error,MYF(flags));
|
||||||
error= 1;
|
error= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
rows_inserted++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->triggers &&
|
if (table->triggers &&
|
||||||
@ -2548,6 +2552,7 @@ int multi_update::send_data(List<Item> ¬_used_values)
|
|||||||
if (!ignore ||
|
if (!ignore ||
|
||||||
table->file->is_fatal_error(error, HA_CHECK_ALL))
|
table->file->is_fatal_error(error, HA_CHECK_ALL))
|
||||||
{
|
{
|
||||||
|
error:
|
||||||
/*
|
/*
|
||||||
If (ignore && error == is ignorable) we don't have to
|
If (ignore && error == is ignorable) we don't have to
|
||||||
do anything; otherwise...
|
do anything; otherwise...
|
||||||
@ -2569,19 +2574,8 @@ int multi_update::send_data(List<Item> ¬_used_values)
|
|||||||
error= 0;
|
error= 0;
|
||||||
updated--;
|
updated--;
|
||||||
}
|
}
|
||||||
else if (has_vers_fields && table->versioned())
|
else if (has_vers_fields && table->versioned(VERS_TRX_ID))
|
||||||
{
|
{
|
||||||
if (table->versioned(VERS_TIMESTAMP))
|
|
||||||
{
|
|
||||||
store_record(table, record[2]);
|
|
||||||
if (vers_insert_history_row(table))
|
|
||||||
{
|
|
||||||
restore_record(table, record[2]);
|
|
||||||
error= 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
restore_record(table, record[2]);
|
|
||||||
}
|
|
||||||
updated_sys_ver++;
|
updated_sys_ver++;
|
||||||
}
|
}
|
||||||
/* non-transactional or transactional table got modified */
|
/* non-transactional or transactional table got modified */
|
||||||
@ -2595,6 +2589,17 @@ int multi_update::send_data(List<Item> ¬_used_values)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (has_vers_fields && table->versioned(VERS_TIMESTAMP))
|
||||||
|
{
|
||||||
|
store_record(table, record[2]);
|
||||||
|
if (vers_insert_history_row(table))
|
||||||
|
{
|
||||||
|
restore_record(table, record[2]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
restore_record(table, record[2]);
|
||||||
|
updated_sys_ver++;
|
||||||
|
}
|
||||||
if (table->triggers &&
|
if (table->triggers &&
|
||||||
unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
||||||
TRG_ACTION_AFTER, TRUE)))
|
TRG_ACTION_AFTER, TRUE)))
|
||||||
|
@ -767,7 +767,7 @@ void
|
|||||||
dtuple_convert_back_big_rec(
|
dtuple_convert_back_big_rec(
|
||||||
/*========================*/
|
/*========================*/
|
||||||
dict_index_t* index MY_ATTRIBUTE((unused)), /*!< in: index */
|
dict_index_t* index MY_ATTRIBUTE((unused)), /*!< in: index */
|
||||||
dtuple_t* entry, /*!< in: entry whose data was put to vector */
|
dtuple_t* entry, /*!< in/out: entry whose data was put to vector */
|
||||||
big_rec_t* vector) /*!< in, own: big rec vector; it is
|
big_rec_t* vector) /*!< in, own: big rec vector; it is
|
||||||
freed in this function */
|
freed in this function */
|
||||||
{
|
{
|
||||||
|
@ -3473,10 +3473,12 @@ ha_innobase::init_table_handle_for_HANDLER(void)
|
|||||||
reset_template();
|
reset_template();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Free tablespace resources allocated. */
|
/*********************************************************************//**
|
||||||
void innobase_space_shutdown()
|
Free any resources that were allocated and return failure.
|
||||||
|
@return always return 1 */
|
||||||
|
static int innodb_init_abort()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("innobase_space_shutdown");
|
DBUG_ENTER("innodb_init_abort");
|
||||||
|
|
||||||
if (fil_system.temp_space) {
|
if (fil_system.temp_space) {
|
||||||
fil_system.temp_space->close();
|
fil_system.temp_space->close();
|
||||||
@ -3491,16 +3493,6 @@ void innobase_space_shutdown()
|
|||||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||||
os_event_destroy(srv_allow_writes_event);
|
os_event_destroy(srv_allow_writes_event);
|
||||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Free any resources that were allocated and return failure.
|
|
||||||
@return always return 1 */
|
|
||||||
static int innodb_init_abort()
|
|
||||||
{
|
|
||||||
DBUG_ENTER("innodb_init_abort");
|
|
||||||
innobase_space_shutdown();
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4309,7 +4301,6 @@ innobase_end(handlerton*, ha_panic_function)
|
|||||||
}
|
}
|
||||||
|
|
||||||
innodb_shutdown();
|
innodb_shutdown();
|
||||||
innobase_space_shutdown();
|
|
||||||
|
|
||||||
mysql_mutex_destroy(&commit_cond_m);
|
mysql_mutex_destroy(&commit_cond_m);
|
||||||
mysql_cond_destroy(&commit_cond);
|
mysql_cond_destroy(&commit_cond);
|
||||||
@ -8779,6 +8770,20 @@ ha_innobase::update_row(
|
|||||||
MySQL that the row is not really updated and it
|
MySQL that the row is not really updated and it
|
||||||
should not increase the count of updated rows.
|
should not increase the count of updated rows.
|
||||||
This is fix for http://bugs.mysql.com/29157 */
|
This is fix for http://bugs.mysql.com/29157 */
|
||||||
|
if (m_prebuilt->versioned_write
|
||||||
|
&& thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE
|
||||||
|
/* Multiple UPDATE of same rows in single transaction create
|
||||||
|
historical rows only once. */
|
||||||
|
&& trx->id != table->vers_start_id()) {
|
||||||
|
error = row_insert_for_mysql((byte*) old_row,
|
||||||
|
m_prebuilt,
|
||||||
|
ROW_INS_HISTORICAL);
|
||||||
|
if (error != DB_SUCCESS) {
|
||||||
|
goto func_exit;
|
||||||
|
}
|
||||||
|
innobase_srv_conc_exit_innodb(m_prebuilt);
|
||||||
|
innobase_active_small();
|
||||||
|
}
|
||||||
DBUG_RETURN(HA_ERR_RECORD_IS_THE_SAME);
|
DBUG_RETURN(HA_ERR_RECORD_IS_THE_SAME);
|
||||||
} else {
|
} else {
|
||||||
const bool vers_set_fields = m_prebuilt->versioned_write
|
const bool vers_set_fields = m_prebuilt->versioned_write
|
||||||
|
@ -968,6 +968,3 @@ which is in the prepared state
|
|||||||
|
|
||||||
@return 0 or error number */
|
@return 0 or error number */
|
||||||
int innobase_rollback_by_xid(handlerton* hton, XID* xid);
|
int innobase_rollback_by_xid(handlerton* hton, XID* xid);
|
||||||
|
|
||||||
/** Free tablespace resources allocated. */
|
|
||||||
void innobase_space_shutdown();
|
|
||||||
|
@ -544,6 +544,17 @@ struct dtuple_t {
|
|||||||
@param[in] index index possibly with instantly added columns */
|
@param[in] index index possibly with instantly added columns */
|
||||||
void trim(const dict_index_t& index);
|
void trim(const dict_index_t& index);
|
||||||
|
|
||||||
|
bool vers_history_row() const
|
||||||
|
{
|
||||||
|
for (ulint i = 0; i < n_fields; i++) {
|
||||||
|
const dfield_t* field = &fields[i];
|
||||||
|
if (field->type.vers_sys_end()) {
|
||||||
|
return field->vers_history_row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@param info_bits the info_bits of a data tuple
|
@param info_bits the info_bits of a data tuple
|
||||||
@return whether this is a hidden metadata record
|
@return whether this is a hidden metadata record
|
||||||
|
@ -206,6 +206,7 @@ struct ins_node_t
|
|||||||
if this is NULL, entry list should be created
|
if this is NULL, entry list should be created
|
||||||
and buffers for sys fields in row allocated */
|
and buffers for sys fields in row allocated */
|
||||||
void vers_update_end(row_prebuilt_t *prebuilt, bool history_row);
|
void vers_update_end(row_prebuilt_t *prebuilt, bool history_row);
|
||||||
|
bool vers_history_row() const; /* true if 'row' is historical */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Create an insert object.
|
/** Create an insert object.
|
||||||
|
@ -2374,6 +2374,18 @@ row_ins_duplicate_error_in_clust(
|
|||||||
duplicate:
|
duplicate:
|
||||||
trx->error_info = cursor->index;
|
trx->error_info = cursor->index;
|
||||||
err = DB_DUPLICATE_KEY;
|
err = DB_DUPLICATE_KEY;
|
||||||
|
if (cursor->index->table->versioned()
|
||||||
|
&& entry->vers_history_row())
|
||||||
|
{
|
||||||
|
ulint trx_id_len;
|
||||||
|
byte *trx_id = rec_get_nth_field(
|
||||||
|
rec, offsets, n_unique,
|
||||||
|
&trx_id_len);
|
||||||
|
ut_ad(trx_id_len == DATA_TRX_ID_LEN);
|
||||||
|
if (trx->id == trx_read_trx_id(trx_id)) {
|
||||||
|
err = DB_FOREIGN_DUPLICATE_KEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3588,6 +3600,16 @@ row_ins_get_row_from_select(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool ins_node_t::vers_history_row() const
|
||||||
|
{
|
||||||
|
if (!table->versioned())
|
||||||
|
return false;
|
||||||
|
dfield_t* row_end = dtuple_get_nth_field(row, table->vers_end);
|
||||||
|
return row_end->vers_history_row();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************//**
|
/***********************************************************//**
|
||||||
Inserts a row to a table.
|
Inserts a row to a table.
|
||||||
@return DB_SUCCESS if operation successfully completed, else error
|
@return DB_SUCCESS if operation successfully completed, else error
|
||||||
@ -3626,12 +3648,31 @@ row_ins(
|
|||||||
ut_ad(node->state == INS_NODE_INSERT_ENTRIES);
|
ut_ad(node->state == INS_NODE_INSERT_ENTRIES);
|
||||||
|
|
||||||
while (node->index != NULL) {
|
while (node->index != NULL) {
|
||||||
if (node->index->type != DICT_FTS) {
|
dict_index_t *index = node->index;
|
||||||
|
/*
|
||||||
|
We do not insert history rows into FTS_DOC_ID_INDEX because
|
||||||
|
it is unique by FTS_DOC_ID only and we do not want to add
|
||||||
|
row_end to unique key. Fulltext field works the way new
|
||||||
|
FTS_DOC_ID is created on every fulltext UPDATE, so holding only
|
||||||
|
FTS_DOC_ID for history is enough.
|
||||||
|
*/
|
||||||
|
const unsigned type = index->type;
|
||||||
|
if (index->type & DICT_FTS) {
|
||||||
|
} else if (!(type & DICT_UNIQUE) || index->n_uniq > 1
|
||||||
|
|| !node->vers_history_row()) {
|
||||||
|
|
||||||
dberr_t err = row_ins_index_entry_step(node, thr);
|
dberr_t err = row_ins_index_entry_step(node, thr);
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
DBUG_RETURN(err);
|
DBUG_RETURN(err);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* Unique indexes with system versioning must contain
|
||||||
|
the version end column. The only exception is a hidden
|
||||||
|
FTS_DOC_ID_INDEX that InnoDB may create on a hidden or
|
||||||
|
user-created FTS_DOC_ID column. */
|
||||||
|
ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX_NAME));
|
||||||
|
ut_ad(!strcmp(index->fields[0].name, FTS_DOC_ID_COL_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
node->index = dict_table_get_next_index(node->index);
|
node->index = dict_table_get_next_index(node->index);
|
||||||
|
@ -2105,10 +2105,18 @@ row_mysql_unfreeze_data_dictionary(
|
|||||||
@param buf Buffer to hold start time data */
|
@param buf Buffer to hold start time data */
|
||||||
void thd_get_query_start_data(THD *thd, char *buf);
|
void thd_get_query_start_data(THD *thd, char *buf);
|
||||||
|
|
||||||
/** Function restores btr_pcur_t, creates dtuple_t from rec_t,
|
/** Insert history row when evaluating foreign key referential action.
|
||||||
sets row_end = CURRENT_TIMESTAMP/trx->id, inserts it to a table and updates
|
|
||||||
table statistics.
|
1. Create new dtuple_t 'row' from node->historical_row;
|
||||||
This is used in UPDATE CASCADE/SET NULL of a system versioning table.
|
2. Update its row_end to current timestamp;
|
||||||
|
3. Insert it to a table;
|
||||||
|
4. Update table statistics.
|
||||||
|
|
||||||
|
This is used in UPDATE CASCADE/SET NULL of a system versioned referenced table.
|
||||||
|
|
||||||
|
node->historical_row: dtuple_t containing pointers of row changed by refertial
|
||||||
|
action.
|
||||||
|
|
||||||
@param[in] thr current query thread
|
@param[in] thr current query thread
|
||||||
@param[in] node a node which just updated a row in a foreign table
|
@param[in] node a node which just updated a row in a foreign table
|
||||||
@return DB_SUCCESS or some error */
|
@return DB_SUCCESS or some error */
|
||||||
@ -2118,11 +2126,19 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node)
|
|||||||
dfield_t* row_end;
|
dfield_t* row_end;
|
||||||
char row_end_data[8];
|
char row_end_data[8];
|
||||||
dict_table_t* table = node->table;
|
dict_table_t* table = node->table;
|
||||||
|
const unsigned zip_size = table->space->zip_size();
|
||||||
ut_ad(table->versioned());
|
ut_ad(table->versioned());
|
||||||
|
|
||||||
dtuple_t* row = node->historical_row;
|
dtuple_t* row;
|
||||||
ut_ad(row);
|
const ulint n_cols = dict_table_get_n_cols(table);
|
||||||
node->historical_row = NULL;
|
const ulint n_v_cols = dict_table_get_n_v_cols(table);
|
||||||
|
|
||||||
|
ut_ad(n_cols == dtuple_get_n_fields(node->historical_row));
|
||||||
|
ut_ad(n_v_cols == dtuple_get_n_v_fields(node->historical_row));
|
||||||
|
|
||||||
|
row = dtuple_create_with_vcol(node->historical_heap, n_cols, n_v_cols);
|
||||||
|
|
||||||
|
dict_table_copy_types(row, table);
|
||||||
|
|
||||||
ins_node_t* insert_node =
|
ins_node_t* insert_node =
|
||||||
ins_node_create(INS_DIRECT, table, node->historical_heap);
|
ins_node_create(INS_DIRECT, table, node->historical_heap);
|
||||||
@ -2135,6 +2151,40 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node)
|
|||||||
insert_node->common.parent = thr;
|
insert_node->common.parent = thr;
|
||||||
ins_node_set_new_row(insert_node, row);
|
ins_node_set_new_row(insert_node, row);
|
||||||
|
|
||||||
|
ut_ad(n_cols > DATA_N_SYS_COLS);
|
||||||
|
// Exclude DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR
|
||||||
|
for (ulint i = 0; i < n_cols - DATA_N_SYS_COLS; i++) {
|
||||||
|
dfield_t *src= dtuple_get_nth_field(node->historical_row, i);
|
||||||
|
dfield_t *dst= dtuple_get_nth_field(row, i);
|
||||||
|
dfield_copy(dst, src);
|
||||||
|
if (dfield_is_ext(src)) {
|
||||||
|
byte *field_data
|
||||||
|
= static_cast<byte*>(dfield_get_data(src));
|
||||||
|
ulint ext_len;
|
||||||
|
ulint field_len = dfield_get_len(src);
|
||||||
|
|
||||||
|
ut_a(field_len >= BTR_EXTERN_FIELD_REF_SIZE);
|
||||||
|
|
||||||
|
ut_a(memcmp(field_data + field_len
|
||||||
|
- BTR_EXTERN_FIELD_REF_SIZE,
|
||||||
|
field_ref_zero,
|
||||||
|
BTR_EXTERN_FIELD_REF_SIZE));
|
||||||
|
|
||||||
|
byte *data = btr_copy_externally_stored_field(
|
||||||
|
&ext_len, field_data, zip_size, field_len,
|
||||||
|
node->historical_heap);
|
||||||
|
dfield_set_data(dst, data, ext_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ulint i = 0; i < n_v_cols; i++) {
|
||||||
|
dfield_t *dst= dtuple_get_nth_v_field(row, i);
|
||||||
|
dfield_t *src= dtuple_get_nth_v_field(node->historical_row, i);
|
||||||
|
dfield_copy(dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
node->historical_row = NULL;
|
||||||
|
|
||||||
row_end = dtuple_get_nth_field(row, table->vers_end);
|
row_end = dtuple_get_nth_field(row, table->vers_end);
|
||||||
if (dict_table_get_nth_col(table, table->vers_end)->vers_native()) {
|
if (dict_table_get_nth_col(table, table->vers_end)->vers_native()) {
|
||||||
mach_write_to_8(row_end_data, trx->id);
|
mach_write_to_8(row_end_data, trx->id);
|
||||||
|
@ -295,12 +295,14 @@ row_build_index_entry_low(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_ad(!(index->type & DICT_FTS));
|
||||||
|
|
||||||
ulint len = dfield_get_len(dfield);
|
ulint len = dfield_get_len(dfield);
|
||||||
|
|
||||||
if (f.prefix_len == 0
|
if (f.prefix_len == 0
|
||||||
&& (!dfield_is_ext(dfield)
|
&& (!dfield_is_ext(dfield)
|
||||||
|| dict_index_is_clust(index))) {
|
|| dict_index_is_clust(index))) {
|
||||||
/* The dfield_copy() above suffices for
|
/* The *dfield = *dfield2 above suffices for
|
||||||
columns that are stored in-page, or for
|
columns that are stored in-page, or for
|
||||||
clustered index record columns that are not
|
clustered index record columns that are not
|
||||||
part of a column prefix in the PRIMARY KEY. */
|
part of a column prefix in the PRIMARY KEY. */
|
||||||
|
@ -2546,6 +2546,17 @@ void innodb_shutdown()
|
|||||||
|
|
||||||
sync_check_close();
|
sync_check_close();
|
||||||
|
|
||||||
|
srv_sys_space.shutdown();
|
||||||
|
if (srv_tmp_space.get_sanity_check_status()) {
|
||||||
|
fil_system.temp_space->close();
|
||||||
|
srv_tmp_space.delete_files();
|
||||||
|
}
|
||||||
|
srv_tmp_space.shutdown();
|
||||||
|
|
||||||
|
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||||
|
os_event_destroy(srv_allow_writes_event);
|
||||||
|
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||||
|
|
||||||
if (srv_was_started && srv_print_verbose_log) {
|
if (srv_was_started && srv_print_verbose_log) {
|
||||||
ib::info() << "Shutdown completed; log sequence number "
|
ib::info() << "Shutdown completed; log sequence number "
|
||||||
<< srv_shutdown_lsn
|
<< srv_shutdown_lsn
|
||||||
|
Loading…
x
Reference in New Issue
Block a user