[Commits] 8dc011b9965: Support Create_time and Update_time in MyRocks table status
revision-id: 8dc011b99657ae3d25e44debdc4bbeaebbaecb52 (fb-prod201903-144-g8dc011b9965) parent(s): d97c0c628e5dc60abd725f6a7120a8d87b09321e author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2019-10-06 23:47:41 +0300 message: Support Create_time and Update_time in MyRocks table status (variant #3, with @@rocksdb_table_dictionary_format) - Create_time is stored in the MyRocks' internal data dictionary. - Update_time is in-memory only (like in InnoDB). @@rocksdb_table_dictionary_format is a global read-only variable (set it from my.cnf) which controls the on-disk data format. rocksdb_table_dictionary_format=1 means use the same data format is before. Create_time will always be NULL for all tables that are created. rocksdb_table_dictionary_format=2 (the default) means use the newer data format. All newly-created tables will have proper Create_time attribute. Downgrades are only possible if one hasn't run any DDL that re-creates a table. --- mysql-test/suite/rocksdb/include/bulk_load.inc | 4 +- .../suite/rocksdb/include/bulk_load_unsorted.inc | 4 +- mysql-test/suite/rocksdb/r/bulk_load.result | 12 +-- mysql-test/suite/rocksdb/r/bulk_load_rev_cf.result | 12 +-- .../rocksdb/r/bulk_load_rev_cf_and_data.result | 12 +-- .../suite/rocksdb/r/bulk_load_rev_data.result | 12 +-- .../suite/rocksdb/r/bulk_load_unsorted.result | 12 +-- .../suite/rocksdb/r/bulk_load_unsorted_rev.result | 12 +-- mysql-test/suite/rocksdb/r/issue255.result | 16 ++-- mysql-test/suite/rocksdb/r/rocksdb.result | 7 +- .../r/rocksdb_table_dictionary_format.result | 37 ++++++++++ .../suite/rocksdb/r/show_table_status.result | 85 +++++++++++++++++++++- mysql-test/suite/rocksdb/r/truncate_table.result | 8 +- mysql-test/suite/rocksdb/t/issue255.test | 17 +++-- mysql-test/suite/rocksdb/t/rocksdb.test | 4 +- .../rocksdb/t/rocksdb_table_dictionary_format.test | 67 +++++++++++++++++ mysql-test/suite/rocksdb/t/show_table_status.test | 81 ++++++++++++++++++++- mysql-test/suite/rocksdb/t/truncate_table.test | 8 +- .../r/rocksdb_table_dictionary_format_basic.result | 14 ++++ .../t/rocksdb_table_dictionary_format_basic.test | 16 ++++ storage/rocksdb/ha_rocksdb.cc | 53 ++++++++++++++ storage/rocksdb/ha_rocksdb.h | 1 + storage/rocksdb/rdb_datadic.cc | 57 ++++++++++++--- storage/rocksdb/rdb_datadic.h | 36 ++++++++- 24 files changed, 502 insertions(+), 85 deletions(-) diff --git a/mysql-test/suite/rocksdb/include/bulk_load.inc b/mysql-test/suite/rocksdb/include/bulk_load.inc index 1b79825e507..7e163602202 100644 --- a/mysql-test/suite/rocksdb/include/bulk_load.inc +++ b/mysql-test/suite/rocksdb/include/bulk_load.inc @@ -121,12 +121,12 @@ set rocksdb_bulk_load=0; --remove_file $file # Make sure row count index stats are correct ---replace_column 6 # 7 # 8 # 9 # +--replace_column 6 # 7 # 8 # 9 # 12 # 13 # SHOW TABLE STATUS WHERE name LIKE 't%'; ANALYZE TABLE t1, t2, t3; ---replace_column 6 # 7 # 8 # 9 # +--replace_column 6 # 7 # 8 # 9 # 12 # 13 # SHOW TABLE STATUS WHERE name LIKE 't%'; # Make sure all the data is there. diff --git a/mysql-test/suite/rocksdb/include/bulk_load_unsorted.inc b/mysql-test/suite/rocksdb/include/bulk_load_unsorted.inc index 5cdc76a32d4..812af0401aa 100644 --- a/mysql-test/suite/rocksdb/include/bulk_load_unsorted.inc +++ b/mysql-test/suite/rocksdb/include/bulk_load_unsorted.inc @@ -119,12 +119,12 @@ set rocksdb_bulk_load=0; --remove_file $file # Make sure row count index stats are correct ---replace_column 6 # 7 # 8 # 9 # +--replace_column 6 # 7 # 8 # 9 # 12 # 13 # SHOW TABLE STATUS WHERE name LIKE 't%'; ANALYZE TABLE t1, t2, t3; ---replace_column 6 # 7 # 8 # 9 # +--replace_column 6 # 7 # 8 # 9 # 12 # 13 # SHOW TABLE STATUS WHERE name LIKE 't%'; # Make sure all the data is there. diff --git a/mysql-test/suite/rocksdb/r/bulk_load.result b/mysql-test/suite/rocksdb/r/bulk_load.result index a36f99a7619..76db28e66bd 100644 --- a/mysql-test/suite/rocksdb/r/bulk_load.result +++ b/mysql-test/suite/rocksdb/r/bulk_load.result @@ -38,9 +38,9 @@ pk a b set rocksdb_bulk_load=0; SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL partitioned ANALYZE TABLE t1, t2, t3; Table Op Msg_type Msg_text test.t1 analyze status OK @@ -48,9 +48,9 @@ test.t2 analyze status OK test.t3 analyze status OK SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL partitioned select count(pk) from t1; count(pk) 5000000 diff --git a/mysql-test/suite/rocksdb/r/bulk_load_rev_cf.result b/mysql-test/suite/rocksdb/r/bulk_load_rev_cf.result index b5d3e252c5d..ae363f7ec0c 100644 --- a/mysql-test/suite/rocksdb/r/bulk_load_rev_cf.result +++ b/mysql-test/suite/rocksdb/r/bulk_load_rev_cf.result @@ -38,9 +38,9 @@ pk a b set rocksdb_bulk_load=0; SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL partitioned ANALYZE TABLE t1, t2, t3; Table Op Msg_type Msg_text test.t1 analyze status OK @@ -48,9 +48,9 @@ test.t2 analyze status OK test.t3 analyze status OK SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL partitioned select count(pk) from t1; count(pk) 5000000 diff --git a/mysql-test/suite/rocksdb/r/bulk_load_rev_cf_and_data.result b/mysql-test/suite/rocksdb/r/bulk_load_rev_cf_and_data.result index f46acd41080..dd8dd7e60a8 100644 --- a/mysql-test/suite/rocksdb/r/bulk_load_rev_cf_and_data.result +++ b/mysql-test/suite/rocksdb/r/bulk_load_rev_cf_and_data.result @@ -38,9 +38,9 @@ pk a b set rocksdb_bulk_load=0; SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL partitioned ANALYZE TABLE t1, t2, t3; Table Op Msg_type Msg_text test.t1 analyze status OK @@ -48,9 +48,9 @@ test.t2 analyze status OK test.t3 analyze status OK SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL partitioned select count(pk) from t1; count(pk) 5000000 diff --git a/mysql-test/suite/rocksdb/r/bulk_load_rev_data.result b/mysql-test/suite/rocksdb/r/bulk_load_rev_data.result index 3389968ef37..96738ae62e2 100644 --- a/mysql-test/suite/rocksdb/r/bulk_load_rev_data.result +++ b/mysql-test/suite/rocksdb/r/bulk_load_rev_data.result @@ -38,9 +38,9 @@ pk a b set rocksdb_bulk_load=0; SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL partitioned ANALYZE TABLE t1, t2, t3; Table Op Msg_type Msg_text test.t1 analyze status OK @@ -48,9 +48,9 @@ test.t2 analyze status OK test.t3 analyze status OK SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_bin NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_bin NULL partitioned select count(pk) from t1; count(pk) 5000000 diff --git a/mysql-test/suite/rocksdb/r/bulk_load_unsorted.result b/mysql-test/suite/rocksdb/r/bulk_load_unsorted.result index 924032549ac..87fc63af2da 100644 --- a/mysql-test/suite/rocksdb/r/bulk_load_unsorted.result +++ b/mysql-test/suite/rocksdb/r/bulk_load_unsorted.result @@ -70,9 +70,9 @@ LOAD DATA INFILE <input_file> INTO TABLE t3; set rocksdb_bulk_load=0; SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL partitioned ANALYZE TABLE t1, t2, t3; Table Op Msg_type Msg_text test.t1 analyze status OK @@ -80,9 +80,9 @@ test.t2 analyze status OK test.t3 analyze status OK SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL partitioned select count(a) from t1; count(a) 5000000 diff --git a/mysql-test/suite/rocksdb/r/bulk_load_unsorted_rev.result b/mysql-test/suite/rocksdb/r/bulk_load_unsorted_rev.result index 3cc9fb8e459..8e0914f0159 100644 --- a/mysql-test/suite/rocksdb/r/bulk_load_unsorted_rev.result +++ b/mysql-test/suite/rocksdb/r/bulk_load_unsorted_rev.result @@ -70,9 +70,9 @@ LOAD DATA INFILE <input_file> INTO TABLE t3; set rocksdb_bulk_load=0; SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL partitioned ANALYZE TABLE t1, t2, t3; Table Op Msg_type Msg_text test.t1 analyze status OK @@ -80,9 +80,9 @@ test.t2 analyze status OK test.t3 analyze status OK SHOW TABLE STATUS WHERE name LIKE 't%'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned +t1 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL +t2 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL +t3 ROCKSDB 10 Fixed 5000000 # # # # 0 NULL # # NULL latin1_swedish_ci NULL partitioned select count(a) from t1; count(a) 5000000 diff --git a/mysql-test/suite/rocksdb/r/issue255.result b/mysql-test/suite/rocksdb/r/issue255.result index c1ce3be2276..b45b3b5afc7 100644 --- a/mysql-test/suite/rocksdb/r/issue255.result +++ b/mysql-test/suite/rocksdb/r/issue255.result @@ -2,7 +2,7 @@ CREATE TABLE t1 (pk BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT); INSERT INTO t1 VALUES (5); SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB # Fixed # # # # # # 6 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB # Fixed # # # # # # 6 # # NULL latin1_swedish_ci NULL INSERT INTO t1 VALUES ('538647864786478647864'); Warnings: Warning 1264 Out of range value for column 'pk' at row 1 @@ -12,7 +12,7 @@ pk 9223372036854775807 SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 2 22 44 0 0 0 9223372036854775807 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB 10 Fixed 2 22 44 0 0 0 9223372036854775807 # # NULL latin1_swedish_ci NULL INSERT INTO t1 VALUES (); ERROR 23000: Duplicate entry '9223372036854775807' for key 'PRIMARY' SELECT * FROM t1; @@ -21,7 +21,7 @@ pk 9223372036854775807 SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB # Fixed # # # # # # 9223372036854775807 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB # Fixed # # # # # # 9223372036854775807 # # NULL latin1_swedish_ci NULL INSERT INTO t1 VALUES (); ERROR 23000: Duplicate entry '9223372036854775807' for key 'PRIMARY' SELECT * FROM t1; @@ -30,13 +30,13 @@ pk 9223372036854775807 SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB # Fixed # # # # # # 9223372036854775807 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB # Fixed # # # # # # 9223372036854775807 # # NULL latin1_swedish_ci NULL DROP TABLE t1; CREATE TABLE t1 (pk TINYINT NOT NULL PRIMARY KEY AUTO_INCREMENT); INSERT INTO t1 VALUES (5); SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB # Fixed # # # # # # 6 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB # Fixed # # # # # # 6 # # NULL latin1_swedish_ci NULL INSERT INTO t1 VALUES (1000); Warnings: Warning 1264 Out of range value for column 'pk' at row 1 @@ -46,7 +46,7 @@ pk 127 SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB # Fixed # # # # # # 127 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB # Fixed # # # # # # 127 # # NULL latin1_swedish_ci NULL INSERT INTO t1 VALUES (); ERROR 23000: Duplicate entry '127' for key 'PRIMARY' SELECT * FROM t1; @@ -55,7 +55,7 @@ pk 127 SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB # Fixed # # # # # # 127 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB # Fixed # # # # # # 127 # # NULL latin1_swedish_ci NULL INSERT INTO t1 VALUES (); ERROR 23000: Duplicate entry '127' for key 'PRIMARY' SELECT * FROM t1; @@ -64,5 +64,5 @@ pk 127 SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB # Fixed # # # # # # 127 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB # Fixed # # # # # # 127 # # NULL latin1_swedish_ci NULL DROP TABLE t1; diff --git a/mysql-test/suite/rocksdb/r/rocksdb.result b/mysql-test/suite/rocksdb/r/rocksdb.result index 088eb050f6f..c76f31afaab 100644 --- a/mysql-test/suite/rocksdb/r/rocksdb.result +++ b/mysql-test/suite/rocksdb/r/rocksdb.result @@ -979,6 +979,7 @@ rocksdb_store_row_debug_checksums OFF rocksdb_strict_collation_check OFF rocksdb_strict_collation_exceptions rocksdb_table_cache_numshardbits 6 +rocksdb_table_dictionary_format 2 rocksdb_table_stats_background_thread_nice_value 19 rocksdb_table_stats_max_num_rows_scanned 0 rocksdb_table_stats_recalc_threshold_count 100 @@ -1417,7 +1418,7 @@ create table t1 (i int primary key auto_increment) engine=RocksDB; insert into t1 values (null),(null); show table status like 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 1000 0 # 0 0 0 3 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB 10 Fixed 1000 0 # 0 0 0 3 # # NULL latin1_swedish_ci NULL drop table t1; # # Fix Issue #4: Crash when using pseudo-unique keys @@ -2612,7 +2613,7 @@ CREATE TABLE t1(a INT AUTO_INCREMENT KEY); INSERT INTO t1 VALUES(0),(-1),(0); SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 1000 0 0 0 0 0 3 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB 10 Fixed 1000 0 0 0 0 0 3 # # NULL latin1_swedish_ci NULL SELECT * FROM t1; a -1 @@ -2623,7 +2624,7 @@ CREATE TABLE t1(a INT AUTO_INCREMENT KEY); INSERT INTO t1 VALUES(0),(10),(0); SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 1000 0 0 0 0 0 12 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB 10 Fixed 1000 0 0 0 0 0 12 # # NULL latin1_swedish_ci NULL SELECT * FROM t1; a 1 diff --git a/mysql-test/suite/rocksdb/r/rocksdb_table_dictionary_format.result b/mysql-test/suite/rocksdb/r/rocksdb_table_dictionary_format.result new file mode 100644 index 00000000000..8f2fa96a04a --- /dev/null +++ b/mysql-test/suite/rocksdb/r/rocksdb_table_dictionary_format.result @@ -0,0 +1,37 @@ +select @@rocksdb_table_dictionary_format; +@@rocksdb_table_dictionary_format +2 +# +# Server restarted +# +select @@rocksdb_table_dictionary_format; +@@rocksdb_table_dictionary_format +1 +create table t1 (a int) engine=rocksdb; +insert into t1 values (1); +# Create_time will be NULL as the table doesn't support it +# Update_time will be non-null +select create_time, update_time is not null +from information_schema.tables +where table_schema=database() and table_name='t1'; +create_time update_time is not null +NULL 1 +# +# Server restarted +# +select @@rocksdb_table_dictionary_format; +@@rocksdb_table_dictionary_format +2 +select create_time, update_time is not null +from information_schema.tables +where table_schema=database() and table_name='t1'; +create_time update_time is not null +NULL 0 +set global rocksdb_compact_cf='default'; +select concat('00', '00', '00', '01', hex('test.t1')); +concat('00', '00', '00', '01', hex('test.t1')) +00000001746573742E7431 +Found the datadic entry +Value has format version 1, followed by 8 bytes describing one index +Done +drop table t1; diff --git a/mysql-test/suite/rocksdb/r/show_table_status.result b/mysql-test/suite/rocksdb/r/show_table_status.result index 29140f045e4..345882040ef 100644 --- a/mysql-test/suite/rocksdb/r/show_table_status.result +++ b/mysql-test/suite/rocksdb/r/show_table_status.result @@ -7,12 +7,12 @@ set global rocksdb_force_flush_memtable_now = true; CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=rocksdb CHARACTER SET utf8; SHOW TABLE STATUS WHERE name IN ( 't1', 't2', 't3' ); Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL NULL NULL NULL utf8_general_ci NULL +t1 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL # # NULL latin1_swedish_ci NULL +t2 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL # # NULL latin1_swedish_ci NULL +t3 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL # # NULL utf8_general_ci NULL SHOW TABLE STATUS WHERE name LIKE 't2'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t2 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 ROCKSDB 10 Fixed 1000 # # 0 0 0 NULL # # NULL latin1_swedish_ci NULL DROP TABLE t1, t2, t3; CREATE DATABASE `db_new..............................................end`; USE `db_new..............................................end`; @@ -22,3 +22,80 @@ SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.table_statistics WHERE T TABLE_SCHEMA db_new..............................................end TABLE_NAME t1_new..............................................end DROP DATABASE `db_new..............................................end`; +# +# MDEV-17171: Bug: RocksDB Tables do not have "Creation Date" +# +use test; +create table t1 (a int) engine=rocksdb; +select create_time is not null, update_time, check_time +from information_schema.tables where table_schema=database() and table_name='t1'; +create_time is not null update_time check_time +1 NULL NULL +insert into t1 values (1); +select create_time is not null, update_time is not null, check_time +from information_schema.tables where table_schema=database() and table_name='t1'; +create_time is not null update_time is not null check_time +1 1 NULL +flush tables; +select create_time is not null, update_time is not null, check_time +from information_schema.tables where table_schema=database() and table_name='t1'; +create_time is not null update_time is not null check_time +1 1 NULL +select create_time, update_time into @create_tm, @update_tm +from information_schema.tables +where table_schema=database() and table_name='t1'; +select sleep(3); +sleep(3) +0 +insert into t1 values (2); +select +create_time=@create_tm /* should not change */ , +timestampdiff(second, @update_tm, update_time) > 2, +check_time +from information_schema.tables +where table_schema=database() and table_name='t1'; +create_time=@create_tm 1 +timestampdiff(second, @update_tm, update_time) > 2 1 +check_time NULL +# +# Check how create_time survives ALTER TABLE. +# First, an ALTER TABLE that re-creates the table: +alter table t1 add b int; +select +create_time<>@create_tm /* should change */, +create_time IS NOT NULL, +update_time IS NULL +from information_schema.tables +where table_schema=database() and table_name='t1'; +create_time<>@create_tm 1 +create_time IS NOT NULL 1 +update_time IS NULL 1 +insert into t1 values (5,5); +select create_time, update_time into @create_tm, @update_tm +from information_schema.tables +where table_schema=database() and table_name='t1'; +# Then, an in-place ALTER TABLE: +alter table t1 add key (a); +select +create_time=@create_tm /* should not change */, +update_time +from information_schema.tables +where table_schema=database() and table_name='t1'; +create_time=@create_tm 1 +update_time NULL +# +# Check what is left after server restart +# +# Save t1's creation time +create table t2 as +select create_time +from information_schema.tables +where table_schema=database() and table_name='t1'; +select +create_time=(select create_time from t2) /* should change */, +update_time +from information_schema.tables +where table_schema=database() and table_name='t1'; +create_time=(select create_time from t2) 1 +update_time NULL +drop table t1, t2; diff --git a/mysql-test/suite/rocksdb/r/truncate_table.result b/mysql-test/suite/rocksdb/r/truncate_table.result index 1544256f194..79b266a2453 100644 --- a/mysql-test/suite/rocksdb/r/truncate_table.result +++ b/mysql-test/suite/rocksdb/r/truncate_table.result @@ -9,19 +9,19 @@ DROP TABLE t1; CREATE TABLE t1 (a INT KEY AUTO_INCREMENT, c CHAR(8)) ENGINE=rocksdb; SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed # # # 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB 10 Fixed # # # 0 0 0 1 # # NULL latin1_swedish_ci NULL INSERT INTO t1 (c) VALUES ('a'),('b'),('c'); SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed # # # 0 0 0 4 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB 10 Fixed # # # 0 0 0 4 # # NULL latin1_swedish_ci NULL TRUNCATE TABLE t1; SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed # # # 0 0 0 1 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB 10 Fixed # # # 0 0 0 1 # # NULL latin1_swedish_ci NULL INSERT INTO t1 (c) VALUES ('d'); SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ROCKSDB 10 Fixed # # # 0 0 0 2 NULL NULL NULL latin1_swedish_ci NULL +t1 ROCKSDB 10 Fixed # # # 0 0 0 2 # # NULL latin1_swedish_ci NULL SELECT a,c FROM t1; a c 1 d diff --git a/mysql-test/suite/rocksdb/t/issue255.test b/mysql-test/suite/rocksdb/t/issue255.test index 370dece0c6c..686f45b4056 100644 --- a/mysql-test/suite/rocksdb/t/issue255.test +++ b/mysql-test/suite/rocksdb/t/issue255.test @@ -3,24 +3,25 @@ CREATE TABLE t1 (pk BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT); INSERT INTO t1 VALUES (5); ---replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # +--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; INSERT INTO t1 VALUES ('538647864786478647864'); ---replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # +--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SELECT * FROM t1; +--replace_column 12 # 13 # SHOW TABLE STATUS LIKE 't1'; --error ER_DUP_ENTRY INSERT INTO t1 VALUES (); SELECT * FROM t1; ---replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # +--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; --error ER_DUP_ENTRY INSERT INTO t1 VALUES (); SELECT * FROM t1; ---replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # +--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; DROP TABLE t1; @@ -28,24 +29,24 @@ DROP TABLE t1; CREATE TABLE t1 (pk TINYINT NOT NULL PRIMARY KEY AUTO_INCREMENT); INSERT INTO t1 VALUES (5); ---replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # +--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; INSERT INTO t1 VALUES (1000); SELECT * FROM t1; ---replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # +--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; --error ER_DUP_ENTRY INSERT INTO t1 VALUES (); SELECT * FROM t1; ---replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # +--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; --error ER_DUP_ENTRY INSERT INTO t1 VALUES (); SELECT * FROM t1; ---replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # +--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; DROP TABLE t1; diff --git a/mysql-test/suite/rocksdb/t/rocksdb.test b/mysql-test/suite/rocksdb/t/rocksdb.test index 5eff0fbf38f..7dcae569c92 100644 --- a/mysql-test/suite/rocksdb/t/rocksdb.test +++ b/mysql-test/suite/rocksdb/t/rocksdb.test @@ -1198,7 +1198,7 @@ drop table t1; create table t1 (i int primary key auto_increment) engine=RocksDB; insert into t1 values (null),(null); ---replace_column 7 # +--replace_column 7 # 12 # 13 # show table status like 't1'; drop table t1; @@ -1903,11 +1903,13 @@ DROP TABLE t1; # value is 4 while MyRocks will show it as 3. CREATE TABLE t1(a INT AUTO_INCREMENT KEY); INSERT INTO t1 VALUES(0),(-1),(0); +--replace_column 12 # 13 # SHOW TABLE STATUS LIKE 't1'; SELECT * FROM t1; DROP TABLE t1; CREATE TABLE t1(a INT AUTO_INCREMENT KEY); INSERT INTO t1 VALUES(0),(10),(0); +--replace_column 12 # 13 # SHOW TABLE STATUS LIKE 't1'; SELECT * FROM t1; DROP TABLE t1; diff --git a/mysql-test/suite/rocksdb/t/rocksdb_table_dictionary_format.test b/mysql-test/suite/rocksdb/t/rocksdb_table_dictionary_format.test new file mode 100644 index 00000000000..3dedf6502ab --- /dev/null +++ b/mysql-test/suite/rocksdb/t/rocksdb_table_dictionary_format.test @@ -0,0 +1,67 @@ +--source include/have_rocksdb.inc + +select @@rocksdb_table_dictionary_format; + +# +# Check the upgrade from Rdb_key_def::DDL_ENTRY_INDEX_VERSION_1 to _2 +# + +--let $_mysqld_option=--rocksdb_table_dictionary_format=1 +--source include/restart_mysqld_with_option.inc + +--echo # +--echo # Server restarted +--echo # +select @@rocksdb_table_dictionary_format; + +create table t1 (a int) engine=rocksdb; +insert into t1 values (1); + +--echo # Create_time will be NULL as the table doesn't support it +--echo # Update_time will be non-null +select create_time, update_time is not null +from information_schema.tables +where table_schema=database() and table_name='t1'; + +--let $_mysqld_option=--rocksdb_table_dictionary_format=2 +--source include/restart_mysqld_with_option.inc +--echo # +--echo # Server restarted +--echo # +select @@rocksdb_table_dictionary_format; + +select create_time, update_time is not null +from information_schema.tables +where table_schema=database() and table_name='t1'; +set global rocksdb_compact_cf='default'; +# use: $MYSQLTEST_VARDIR $MYSQL_SST_DUMP +let MYSQL_DATADIR = `select @@datadir`; +let MYSQL_SST_DUMP = $MYSQL_SST_DUMP; + +select concat('00', '00', '00', '01', hex('test.t1')); + +# We are looking to find a record like this: +# '00000001746573742E7431' seq:0, type:1 => 00010000000000000104 +# that is: +# '00000001:746573742E7431' seq:0, type:1 => 0001: 0000000000000104 +# the key is: DDL_ENTRY_INDEX_START_NUMBER, "test.t1" +# the value is: DDL_ENTRY_INDEX_VERSION_1, {cf_id, index_id} +perl; + my $datadir = $ENV{'MYSQL_DATADIR'}; + my $sst_dump = $ENV{'MYSQL_SST_DUMP'}; + open(IN, "$sst_dump --command=scan --output_hex --file=$datadir/.rocksdb |"); + while(<IN>) { + if ($_ =~ /^\'00000001746573742E7431\'/) { + print "Found the datadic entry\n"; + if ($_ =~ / 0001[0-9]{16}$/) { + print "Value has format version 1, followed by 8 bytes describing one index\n" + } else { + print "Unexpected value. $_\n"; + } + } + } + print "Done\n"; + close(IN); +EOF +drop table t1; + diff --git a/mysql-test/suite/rocksdb/t/show_table_status.test b/mysql-test/suite/rocksdb/t/show_table_status.test index 29cc2ccfb5e..59effcc788c 100644 --- a/mysql-test/suite/rocksdb/t/show_table_status.test +++ b/mysql-test/suite/rocksdb/t/show_table_status.test @@ -24,7 +24,7 @@ set global rocksdb_force_flush_memtable_now = true; CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=rocksdb CHARACTER SET utf8; ---replace_column 6 # 7 # +--replace_column 6 # 7 # 12 # 13 # SHOW TABLE STATUS WHERE name IN ( 't1', 't2', 't3' ); # Some statistics don't get updated as quickly. The Data_length and @@ -48,7 +48,7 @@ set global rocksdb_force_flush_memtable_now = true; # We expect the number of rows to be 10000. Data_len and Avg_row_len # may vary, depending on built-in compression library. ---replace_column 6 # 7 # +--replace_column 6 # 7 # 12 # 13 # SHOW TABLE STATUS WHERE name LIKE 't2'; DROP TABLE t1, t2, t3; @@ -62,3 +62,80 @@ CREATE TABLE `t1_new..............................................end`(a int) en INSERT INTO `t1_new..............................................end` VALUES (1); --query_vertical SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.table_statistics WHERE TABLE_NAME = 't1_new..............................................end' DROP DATABASE `db_new..............................................end`; +--echo # +--echo # MDEV-17171: Bug: RocksDB Tables do not have "Creation Date" +--echo # +use test; +create table t1 (a int) engine=rocksdb; + +select create_time is not null, update_time, check_time +from information_schema.tables where table_schema=database() and table_name='t1'; + +insert into t1 values (1); +select create_time is not null, update_time is not null, check_time +from information_schema.tables where table_schema=database() and table_name='t1'; + +flush tables; +select create_time is not null, update_time is not null, check_time +from information_schema.tables where table_schema=database() and table_name='t1'; + +select create_time, update_time into @create_tm, @update_tm +from information_schema.tables +where table_schema=database() and table_name='t1'; + +select sleep(3); +insert into t1 values (2); + +--vertical_results +select + create_time=@create_tm /* should not change */ , + timestampdiff(second, @update_tm, update_time) > 2, + check_time +from information_schema.tables +where table_schema=database() and table_name='t1'; + +--echo # +--echo # Check how create_time survives ALTER TABLE. +--echo # First, an ALTER TABLE that re-creates the table: +alter table t1 add b int; +select + create_time<>@create_tm /* should change */, + create_time IS NOT NULL, + update_time IS NULL +from information_schema.tables +where table_schema=database() and table_name='t1'; + +insert into t1 values (5,5); + +select create_time, update_time into @create_tm, @update_tm +from information_schema.tables +where table_schema=database() and table_name='t1'; + +--echo # Then, an in-place ALTER TABLE: +alter table t1 add key (a); + +select + create_time=@create_tm /* should not change */, + update_time +from information_schema.tables +where table_schema=database() and table_name='t1'; + +--echo # +--echo # Check what is left after server restart +--echo # + +--echo # Save t1's creation time +create table t2 as +select create_time +from information_schema.tables +where table_schema=database() and table_name='t1'; + +--source include/restart_mysqld.inc + +select + create_time=(select create_time from t2) /* should change */, + update_time +from information_schema.tables +where table_schema=database() and table_name='t1'; + +drop table t1, t2; diff --git a/mysql-test/suite/rocksdb/t/truncate_table.test b/mysql-test/suite/rocksdb/t/truncate_table.test index a61488654a3..1001eeb6cde 100644 --- a/mysql-test/suite/rocksdb/t/truncate_table.test +++ b/mysql-test/suite/rocksdb/t/truncate_table.test @@ -29,22 +29,22 @@ DROP TABLE t1; CREATE TABLE t1 (a INT KEY AUTO_INCREMENT, c CHAR(8)) ENGINE=rocksdb; #--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # ---replace_column 5 # 6 # 7 # +--replace_column 5 # 6 # 7 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; INSERT INTO t1 (c) VALUES ('a'),('b'),('c'); #--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # ---replace_column 5 # 6 # 7 # +--replace_column 5 # 6 # 7 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; TRUNCATE TABLE t1; #--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # ---replace_column 5 # 6 # 7 # +--replace_column 5 # 6 # 7 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; INSERT INTO t1 (c) VALUES ('d'); #--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # ---replace_column 5 # 6 # 7 # +--replace_column 5 # 6 # 7 # 12 # 13 # SHOW TABLE STATUS LIKE 't1'; --sorted_result diff --git a/mysql-test/suite/rocksdb_sys_vars/r/rocksdb_table_dictionary_format_basic.result b/mysql-test/suite/rocksdb_sys_vars/r/rocksdb_table_dictionary_format_basic.result new file mode 100644 index 00000000000..825d7a7113a --- /dev/null +++ b/mysql-test/suite/rocksdb_sys_vars/r/rocksdb_table_dictionary_format_basic.result @@ -0,0 +1,14 @@ +CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam; +INSERT INTO valid_values VALUES(1); +INSERT INTO valid_values VALUES(2); +CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam; +INSERT INTO invalid_values VALUES('\'aaa\''); +SET @start_global_value = @@global.ROCKSDB_TABLE_DICTIONARY_FORMAT; +SELECT @start_global_value; +@start_global_value +2 +"Trying to set variable @@global.ROCKSDB_TABLE_DICTIONARY_FORMAT to 444. It should fail because it is readonly." +SET @@global.ROCKSDB_TABLE_DICTIONARY_FORMAT = 444; +ERROR HY000: Variable 'rocksdb_table_dictionary_format' is a read only variable +DROP TABLE valid_values; +DROP TABLE invalid_values; diff --git a/mysql-test/suite/rocksdb_sys_vars/t/rocksdb_table_dictionary_format_basic.test b/mysql-test/suite/rocksdb_sys_vars/t/rocksdb_table_dictionary_format_basic.test new file mode 100644 index 00000000000..2b8c6e81bf7 --- /dev/null +++ b/mysql-test/suite/rocksdb_sys_vars/t/rocksdb_table_dictionary_format_basic.test @@ -0,0 +1,16 @@ +--source include/have_rocksdb.inc + +CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam; +INSERT INTO valid_values VALUES(1); +INSERT INTO valid_values VALUES(2); + +CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam; +INSERT INTO invalid_values VALUES('\'aaa\''); + +--let $sys_var=ROCKSDB_TABLE_DICTIONARY_FORMAT +--let $read_only=1 +--let $session=0 +--source ../include/rocksdb_sys_var.inc + +DROP TABLE valid_values; +DROP TABLE invalid_values; diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index d6c89087bea..a0a344187cf 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -122,6 +122,8 @@ const std::string PER_INDEX_CF_NAME("$per_index_cf"); static std::vector<std::string> rdb_tables_to_recalc; +uint rocksdb_table_dictionary_format; + class Rdb_explicit_snapshot : public explicit_snapshot { public: static std::shared_ptr<Rdb_explicit_snapshot> create( @@ -2136,6 +2138,17 @@ static MYSQL_SYSVAR_ULONGLONG( "MultiGet", nullptr, nullptr, SIZE_T_MAX, /* min */ 0, /* max */ SIZE_T_MAX, 0); +static MYSQL_SYSVAR_UINT(table_dictionary_format, + rocksdb_table_dictionary_format, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Max Table Dictionary format version that the server " + "may create (use lower values for backward " + " compatibility, higher values for new features)", + nullptr, nullptr, + ROCKSDB_DATADIC_FORMAT_DEFAULT, + ROCKSDB_DATADIC_FORMAT_INITIAL, + ROCKSDB_DATADIC_FORMAT_MAX, 0); + static const int ROCKSDB_ASSUMED_KEY_VALUE_DISK_SIZE = 100; static struct st_mysql_sys_var *rocksdb_system_variables[] = { @@ -2309,6 +2322,8 @@ static struct st_mysql_sys_var *rocksdb_system_variables[] = { MYSQL_SYSVAR(select_bypass_log_rejected), MYSQL_SYSVAR(select_bypass_debug_row_delay), MYSQL_SYSVAR(select_bypass_multiget_min), + + MYSQL_SYSVAR(table_dictionary_format), nullptr}; static rocksdb::WriteOptions rdb_get_rocksdb_write_options( @@ -2456,6 +2471,8 @@ class Rdb_transaction { bool m_is_delayed_snapshot = false; bool m_is_two_phase = false; + std::unordered_set<Rdb_tbl_def*> modified_tables; + private: /* Number of write operations this transaction had when we took the last @@ -3139,6 +3156,25 @@ class Rdb_transaction { virtual void start_tx() = 0; virtual void start_stmt() = 0; + protected: + // Non-virtual functions with actions to be done on transaction start and + // commit. + void on_commit() { + time_t tm; + tm = time(nullptr); + for (auto &it : modified_tables) { + it->update_time = tm; + } + modified_tables.clear(); + } + void on_rollback() { + modified_tables.clear(); + } + public: + void log_table_write_op(Rdb_tbl_def *tbl) { + modified_tables.insert(tbl); + } + void set_initial_savepoint() { /* Set the initial savepoint. If the first statement in the transaction @@ -3322,7 +3358,9 @@ class Rdb_transaction_impl : public Rdb_transaction { goto error; } + on_commit(); error: + on_rollback(); /* Save the transaction object to be reused */ release_tx(); @@ -3338,6 +3376,7 @@ class Rdb_transaction_impl : public Rdb_transaction { public: void rollback() override { + on_rollback(); m_write_count = 0; m_insert_count = 0; m_update_count = 0; @@ -3659,7 +3698,9 @@ class Rdb_writebatch_impl : public Rdb_transaction { res = true; goto error; } + on_commit(); error: + on_rollback(); reset(); m_write_count = 0; @@ -3691,6 +3732,7 @@ class Rdb_writebatch_impl : public Rdb_transaction { } void rollback() override { + on_rollback(); m_write_count = 0; m_insert_count = 0; m_update_count = 0; @@ -7549,6 +7591,7 @@ int ha_rocksdb::create_table(const std::string &table_name, /* Create table/key descriptions and put them into the data dictionary */ m_tbl_def = new Rdb_tbl_def(table_name); + m_tbl_def->set_create_time(time(nullptr)); uint n_keys = table_arg->s->keys; @@ -10177,6 +10220,8 @@ int ha_rocksdb::update_write_row(const uchar *const old_data, row_info.tx->incr_insert_count(); } + row_info.tx->log_table_write_op(m_tbl_def); + if (do_bulk_commit(row_info.tx)) { DBUG_RETURN(HA_ERR_ROCKSDB_BULK_LOAD); } @@ -10648,6 +10693,7 @@ int ha_rocksdb::delete_row(const uchar *const buf) { } tx->incr_delete_count(); + tx->log_table_write_op(m_tbl_def); if (do_bulk_commit(tx)) { DBUG_RETURN(HA_ERR_ROCKSDB_BULK_LOAD); @@ -10802,6 +10848,12 @@ int ha_rocksdb::info(uint flag) { k->rec_per_key[j] = x; } } + + stats.create_time = m_tbl_def->get_create_time(); + } + + if (flag & HA_STATUS_TIME) { + stats.update_time = m_tbl_def->update_time; } if (flag & HA_STATUS_ERRKEY) { @@ -12603,6 +12655,7 @@ bool ha_rocksdb::prepare_inplace_alter_table( m_tbl_def->m_auto_incr_val.load(std::memory_order_relaxed); new_tdef->m_hidden_pk_val = m_tbl_def->m_hidden_pk_val.load(std::memory_order_relaxed); + new_tdef->set_create_time(m_tbl_def->get_create_time()); if (create_key_defs(altered_table, new_tdef, table, m_tbl_def)) { /* Delete the new key descriptors */ diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h index 9a250af40c7..c36c5c98e19 100644 --- a/storage/rocksdb/ha_rocksdb.h +++ b/storage/rocksdb/ha_rocksdb.h @@ -82,6 +82,7 @@ extern PSI_rwlock_key key_rwlock_read_free_rpl_tables; #endif extern Regex_list_handler rdb_read_free_regex_handler; +extern uint rocksdb_table_dictionary_format; /** @brief Rdb_table_handler is a reference-counted structure storing information for diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc index c0741a1ce9b..234f7a789ff 100644 --- a/storage/rocksdb/rdb_datadic.cc +++ b/storage/rocksdb/rdb_datadic.cc @@ -3514,8 +3514,21 @@ bool Rdb_tbl_def::put_dict(Rdb_dict_manager *const dict, const rocksdb::Slice &key) { StringBuffer<8 * Rdb_key_def::PACKED_SIZE> indexes; indexes.alloc(Rdb_key_def::VERSION_SIZE + + Rdb_key_def::TABLE_CREATE_TIMESTAMP_SIZE + m_key_count * Rdb_key_def::PACKED_SIZE * 2); - rdb_netstr_append_uint16(&indexes, Rdb_key_def::DDL_ENTRY_INDEX_VERSION); + + if (rocksdb_table_dictionary_format < + ROCKSDB_DATADIC_FORMAT_CREATE_TIMESTAMP) { + rdb_netstr_append_uint16(&indexes, Rdb_key_def::DDL_ENTRY_INDEX_VERSION_1); + // We are using old data format, which means we cannot save Create_time + // Set it to be shown as unknown right away, so that the behavior before + // server restart and after is the same. + set_create_time(0); + } + else { + rdb_netstr_append_uint16(&indexes, Rdb_key_def::DDL_ENTRY_INDEX_VERSION_2); + rdb_netstr_append_uint64(&indexes, create_time); + } for (uint i = 0; i < m_key_count; i++) { const Rdb_key_def &kd = *m_key_descr_arr[i]; @@ -4015,27 +4028,52 @@ bool Rdb_ddl_manager::init(Rdb_dict_manager *const dict_arg, Rdb_tbl_def *const tdef = new Rdb_tbl_def(key, Rdb_key_def::INDEX_NUMBER_SIZE); - // Now, read the DDLs. - const int real_val_size = val.size() - Rdb_key_def::VERSION_SIZE; - if (real_val_size % Rdb_key_def::PACKED_SIZE * 2 > 0) { + if (val.size() < Rdb_key_def::VERSION_SIZE) { // NO_LINT_DEBUG sql_print_error("RocksDB: Table_store: invalid keylist for table %s", tdef->full_tablename().c_str()); return true; } - tdef->m_key_count = real_val_size / (Rdb_key_def::PACKED_SIZE * 2); - tdef->m_key_descr_arr = new std::shared_ptr<Rdb_key_def>[tdef->m_key_count]; ptr = reinterpret_cast<const uchar *>(val.data()); const int version = rdb_netbuf_read_uint16(&ptr); - if (version != Rdb_key_def::DDL_ENTRY_INDEX_VERSION) { + + if (version != Rdb_key_def::DDL_ENTRY_INDEX_VERSION_1 && + version != Rdb_key_def::DDL_ENTRY_INDEX_VERSION_2) { // NO_LINT_DEBUG sql_print_error( "RocksDB: DDL ENTRY Version was not expected." - "Expected: %d, Actual: %d", - Rdb_key_def::DDL_ENTRY_INDEX_VERSION, version); + "Expected: %d..%d, Actual: %d", + Rdb_key_def::DDL_ENTRY_INDEX_VERSION_1, + Rdb_key_def::DDL_ENTRY_INDEX_VERSION_2, version); return true; } + int real_val_size = val.size() - Rdb_key_def::VERSION_SIZE; + + if (version == Rdb_key_def::DDL_ENTRY_INDEX_VERSION_2) { + if (real_val_size < Rdb_key_def::TABLE_CREATE_TIMESTAMP_SIZE) { + // NO_LINT_DEBUG + sql_print_error( "RocksDB: DDL ENTRY V2 doesn't have timestamp"); + delete tdef; + return true; + } + tdef->set_create_time(rdb_netbuf_read_uint64(&ptr)); + real_val_size -= Rdb_key_def::TABLE_CREATE_TIMESTAMP_SIZE; + } + else + tdef->set_create_time(0); // shown as SQL NULL. + + // Now, read the DDLs. + if (real_val_size % Rdb_key_def::PACKED_SIZE * 2 > 0) { + // NO_LINT_DEBUG + sql_print_error("RocksDB: Table_store: invalid keylist for table %s", + tdef->full_tablename().c_str()); + return true; + } + tdef->m_key_count = real_val_size / (Rdb_key_def::PACKED_SIZE * 2); + tdef->m_key_descr_arr = new std::shared_ptr<Rdb_key_def>[tdef->m_key_count]; + + ptr_end = ptr + real_val_size; for (uint keyno = 0; ptr < ptr_end; keyno++) { GL_INDEX_ID gl_index_id; @@ -4471,6 +4509,7 @@ bool Rdb_ddl_manager::rename(const std::string &from, const std::string &to, rec->m_hidden_pk_val.load(std::memory_order_relaxed); new_rec->m_tbl_stats = rec->m_tbl_stats; + new_rec->set_create_time(rec->get_create_time()); // so that it's not free'd when deleting the old rec rec->m_key_descr_arr = nullptr; diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h index 416857cad38..9c2a96e77b7 100644 --- a/storage/rocksdb/rdb_datadic.h +++ b/storage/rocksdb/rdb_datadic.h @@ -203,6 +203,22 @@ enum { UNPACK_FAILURE = 1, }; + +/* + Global user-visible data dictionary format version. + The server will read the data of any version, but will not write data + structures that were introduced after the version in + rocksdb_table_dictionary_format. + This way, one can keep the on-disk data backward-compatible. +*/ +const uint ROCKSDB_DATADIC_FORMAT_INITIAL = 1; +const uint ROCKSDB_DATADIC_FORMAT_CREATE_TIMESTAMP = 2; + +// Maximum possible value: +const uint ROCKSDB_DATADIC_FORMAT_MAX = 2; +const uint ROCKSDB_DATADIC_FORMAT_DEFAULT = ROCKSDB_DATADIC_FORMAT_MAX; + + /* An object of this class represents information about an index in an SQL table. It provides services to encode and decode index tuples. @@ -465,6 +481,7 @@ class Rdb_key_def { CF_NUMBER_SIZE = 4, CF_FLAG_SIZE = 4, PACKED_SIZE = 4, // one int + TABLE_CREATE_TIMESTAMP_SIZE = 8, }; // bit flags for combining bools when writing to disk @@ -506,7 +523,10 @@ class Rdb_key_def { // Data dictionary schema version. Introduce newer versions // if changing schema layout enum { - DDL_ENTRY_INDEX_VERSION = 1, + DDL_ENTRY_INDEX_VERSION_1 = 1, + // this includes a 64-bit table_creation_time at the end. + // Allowed since ROCKSDB_DATADIC_FORMAT_CREATE_TIMESTAMP. + DDL_ENTRY_INDEX_VERSION_2 = 2, CF_DEFINITION_VERSION = 1, BINLOG_INFO_INDEX_NUMBER_VERSION = 1, DDL_DROP_INDEX_ONGOING_VERSION = 1, @@ -1116,6 +1136,12 @@ class Rdb_tbl_def { ~Rdb_tbl_def(); + // time values are shown in SHOW TABLE STATUS + void set_create_time(time_t val) { create_time = val; } + time_t get_create_time() { return create_time; } + + time_t update_time = 0; // in-memory only value, maintained right here + void check_and_set_read_free_rpl_table(); /* Number of indexes */ @@ -1161,6 +1187,9 @@ class Rdb_tbl_def { const std::string &base_tablename() const { return m_tablename; } const std::string &base_partition() const { return m_partition; } GL_INDEX_ID get_autoincr_gl_index_id(); + + private: + time_t create_time = 0; }; /* @@ -1341,8 +1370,11 @@ class Rdb_binlog_manager { 1. Table Name => internal index id mappings key: Rdb_key_def::DDL_ENTRY_INDEX_START_NUMBER(0x1) + dbname.tablename - value: version, {cf_id, index_id}*n_indexes_of_the_table + value: DDL_ENTRY_INDEX_VERSION_1, {cf_id, index_id}*n_indexes_of_the_table + or value: DDL_ENTRY_INDEX_VERSION_2, create_timestamp, {cf_id, index_id}* + n_indexes_of_the_table version is 2 bytes. cf_id and index_id are 4 bytes. + create_timestamp is 8 bytes. 2. internal cf_id, index id => index information key: Rdb_key_def::INDEX_INFO(0x2) + cf_id + index_id
participants (1)
-
psergey