stonedb
stonedb copied to clipboard
bug: pecified key was too long; max key length is 255 bytes(innodb does not report errors)
Describe the problem
create table t1 (
a varchar(112) charset utf8 collate utf8_bin not null,
primary key (a)
) select 'test' as a ;
ERROR 1071 (42000): Specified key was too long; max key length is 255 bytes
Expected behavior
create table t1 (
a varchar(112) charset utf8 collate utf8_bin not null,
primary key (a)
) select 'test' as a ;
How To Reproduce
Can be created without error
Environment
- StoneDB for mysql5.7(release)
- Ubuntu 20.04.4
Are you interested in submitting a PR to solve the problem?
- [ ] Yes, I will!
I think we should check the length in primary key just innodb does.
ACK
it seems the function handler::max_supported_key_part_length results in the difference . innodb inherit the function,while tianmu/stonedb enginer didn't.
- in myrocks5.6,storage\rocksdb\ha_rocksdb.cc
uint ha_rocksdb::max_supported_key_part_length() const {
DBUG_ENTER_FUNC();
DBUG_RETURN(rocksdb_large_prefix ? MAX_INDEX_COL_LEN_LARGE
: MAX_INDEX_COL_LEN_SMALL);
}
#define MAX_INDEX_COL_LEN_LARGE 3072 #define MAX_INDEX_COL_LEN_SMALL 767 rocksdb_large_prefix default value is 0
- in innodb, the function is :
uint
ha_innobase::max_supported_key_part_length(HA_CREATE_INFO *create_info) const
/*==============================================*/
{
/* A table format specific index column length check will be performed
at ha_innobase::add_index() and row_create_index_for_mysql() */
switch (create_info->row_type) {
case ROW_TYPE_REDUNDANT:
case ROW_TYPE_COMPACT:
return (REC_ANTELOPE_MAX_INDEX_COL_LEN - 1);
break;
default:
if (innobase_large_prefix)
return (REC_VERSION_56_MAX_INDEX_COL_LEN);
else
return (REC_ANTELOPE_MAX_INDEX_COL_LEN - 1);
}
}
#define REC_ANTELOPE_MAX_INDEX_COL_LEN 768 #define REC_VERSION_56_MAX_INDEX_COL_LEN 3072 #define REC_ANTELOPE_MAX_INDEX_COL_LEN 768
- We can conclude that: 3.1. innodb is key-part-length default is 768-1; if set the innobase_large_prefix variables to ture(default is false), key-part-length can be 3072; 3.2. rocksdb's key-part-length default is 767(768-1); if set rocksdb_large_prefix variables to ture(default is false) , key-part-length can be 3072;
So, should we add a system variable(default values is false,and key-part-length is 767).if the system variable is true, key-part-length is 3072-1 ? @hustjieke @RingsC @isredstar
max_supported_key_length in tianmu is 1024, this limit the key length, innodb's value is 3500, myrocks's value is 161024; tianmu use rocksdb as storage, so use the value 161024;
- innodb's max_supported_key_length
ha_innobase::max_supported_key_length() const
/*=========================================*/
{
/* An InnoDB page must store >= 2 keys; a secondary key record
must also contain the primary key value. Therefore, if both
the primary key and the secondary key are at this maximum length,
it must be less than 1/4th of the free space on a page including
record overhead.
MySQL imposes its own limit to this number; MAX_KEY_LENGTH = 3072.
For page sizes = 16k, InnoDB historically reported 3500 bytes here,
But the MySQL limit of 3072 was always used through the handler
interface. */
switch (UNIV_PAGE_SIZE) {
case 4096:
return(768);
case 8192:
return(1536);
default:
return(3500);
}
}
- myrock5.6's max_supported_key_length
uint max_supported_key_length() const override {
DBUG_ENTER_FUNC();
DBUG_RETURN(16 * 1024); /* just to return something*/
}