diff options
author | kevg <claprix@yandex.ru> | 2017-02-17 15:11:15 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2017-05-05 20:36:28 +0300 |
commit | fb801289f314bee6e5b1864f3ef58f8f38a59278 (patch) | |
tree | 9073b2039e4f4b3a1b99d883b70784a9ba2eecf4 | |
parent | bcc8ba78bc89b075c169d4ab414f59922401ebeb (diff) | |
download | mariadb-git-fb801289f314bee6e5b1864f3ef58f8f38a59278.tar.gz |
IB, Tests: ALTER with ALGORITHM=INPLACE for InnoDB [closes #87]
-rw-r--r-- | mysql-test/suite/versioning/r/alter.result | 24 | ||||
-rw-r--r-- | mysql-test/suite/versioning/t/alter.test | 17 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 9 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 42 |
4 files changed, 73 insertions, 19 deletions
diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index d9353f957dd..7b0523d4e96 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -275,8 +275,6 @@ t CREATE TABLE `t` ( PERIOD FOR SYSTEM_TIME (`trx_start`, `trx_end`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING alter table t without system versioning; -alter table t with system versioning, algorithm=inplace; -ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY alter table t with system versioning, algorithm=copy; show create table t; Table Create Table @@ -345,8 +343,6 @@ select * from t for system_time all; a 2 1 -alter table t without system versioning, algorithm=inplace; -ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY alter table t without system versioning, algorithm=copy; show create table t; Table Create Table @@ -417,6 +413,26 @@ a b 2 -2 3 1 4 2 +create or replace table t (a int) engine innodb; +insert into t values (1); +alter table t with system versioning, algorithm=inplace; +select * from t for system_time all; +a +1 +update t set a=2; +select * from t for system_time all; +a +2 +1 +alter table t add column b int, algorithm=inplace; +select * from t for system_time all; +a b +2 NULL +1 NULL +alter table t without system versioning, algorithm=inplace; +select * from t; +a b +2 NULL call verify_vtq; No A B C D 1 1 1 1 1 diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 99d200c93f0..da780f6ca55 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -134,9 +134,6 @@ alter table t show create table t; alter table t without system versioning; ---error ER_ALTER_OPERATION_NOT_SUPPORTED -alter table t with system versioning, algorithm=inplace; - alter table t with system versioning, algorithm=copy; show create table t; @@ -159,9 +156,6 @@ alter table t drop column b, algorithm=inplace; show create table t; select * from t for system_time all; ---error ER_ALTER_OPERATION_NOT_SUPPORTED -alter table t without system versioning, algorithm=inplace; - alter table t without system versioning, algorithm=copy; show create table t; @@ -197,6 +191,17 @@ select * from t for system_time all; insert into t values (4, NULL); select * from t for system_time all; +create or replace table t (a int) engine innodb; +insert into t values (1); +alter table t with system versioning, algorithm=inplace; +select * from t for system_time all; +update t set a=2; +select * from t for system_time all; +alter table t add column b int, algorithm=inplace; +select * from t for system_time all; +alter table t without system versioning, algorithm=inplace; +select * from t; + call verify_vtq; drop table t; drop procedure verify_vtq; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 0e36bf04fde..672c3672c7c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -588,15 +588,6 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - // It looks like it's actually possible to do this INPLACE, but we - // disallow this for now. - if (ha_alter_info->create_info->vers_info - .declared_with_system_versioning || - ha_alter_info->create_info->vers_info - .declared_without_system_versioning) { - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - update_thd(); trx_assert_no_search_latch(m_prebuilt->trx); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 810e285da26..5f2ca6838e2 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -2301,6 +2301,48 @@ end_of_index: } } + if (DICT_TF2_FLAG_IS_SET(old_table, DICT_TF2_VERSIONED)) { + if (DICT_TF2_FLAG_IS_SET( + new_table, DICT_TF2_VERSIONED)) { + dfield_t *end = dtuple_get_nth_field( + row, new_table->vers_row_end); + byte *data = static_cast<byte *>( + dfield_get_data(end)); + ut_ad(data); + if (mach_read_from_8(data) == TRX_ID_MAX) { + dfield_t *start = dtuple_get_nth_field( + row, new_table->vers_row_start); + void *data = dfield_get_data(start); + ut_ad(data); + mach_write_to_8(data, trx->id); + } + } else { + const dict_col_t *col = + &old_table->cols + [old_table->vers_row_end]; + const ulint nfield = dict_col_get_clust_pos( + col, clust_index); + ulint len = 0; + const rec_t *sys_trx_end = rec_get_nth_field( + rec, offsets, nfield, &len); + ut_ad(len == 8); + if (mach_read_from_8(sys_trx_end) != TRX_ID_MAX) + continue; + } + } else if (DICT_TF2_FLAG_IS_SET( + new_table, DICT_TF2_VERSIONED)) { + void *sys_trx_start = mem_heap_alloc(row_heap, 8); + void *sys_trx_end = mem_heap_alloc(row_heap, 8); + mach_write_to_8(sys_trx_start, trx->id); + mach_write_to_8(sys_trx_end, TRX_ID_MAX); + dfield_t *start = dtuple_get_nth_field( + row, new_table->vers_row_start); + dfield_t *end = dtuple_get_nth_field( + row, new_table->vers_row_end); + dfield_set_data(start, sys_trx_start, 8); + dfield_set_data(end, sys_trx_end, 8); + } + write_buffers: /* Build all entries for all the indexes to be created in a single scan of the clustered index. */ |