본문 바로가기

MySQL/R&D

MySQL Partition Key length 이슈 (in MySQL 5.7)

1. 배경

MySQL 버전 업그레이드를 진행하다가 특정 테이블 생성이 불가능해서 살펴봤었다.

 

월별 파티션 같은 테이블에서는 파티션 키를 date 관련 타입이 아닌, char 관련 타입으로 가져가는 경우가 있다.

 

이 때, MySQL 5.7 이전 (MySQL 5.6 이하) 버전에서는 파티션 키의 크기가 파티션 range 의 범위 크기 (ex. '201801' 의 경우 크기는 6) 보다 작아도 파티션 테이블이 만들어 졌다.

 

그러나 MySQL 5.7 부터는 "ERROR 1654 (HY000): Partition column values of incorrect type" 에러가 발생한다.

 

2. 테스트

1) MySQL 5.6

> CREATE TABLE `t1` (
`reg_month` varchar(6),
`content_id` int(11),
PRIMARY KEY (`content_id`, `reg_month`)
)
/*!50500 PARTITION BY RANGE COLUMNS(reg_month)
(PARTITION p201702 VALUES LESS THAN ('20170301') ENGINE = InnoDB,
PARTITION p201907 VALUES LESS THAN ('20190801') ENGINE = InnoDB) */;

Query OK, 0 rows affected (0.00 sec)

  • partition key column = varchar (6)
  • partition key length = '20190801' → 8
  • 정상 생성

2) MariaDB 5.5

> CREATE TABLE `t1` (
`reg_month` varchar(6),
`content_id` int(11),
PRIMARY KEY (`content_id`, `reg_month`)
)
/*!50500 PARTITION BY RANGE COLUMNS(reg_month)
(PARTITION p201702 VALUES LESS THAN ('20170301') ENGINE = InnoDB,
PARTITION p201907 VALUES LESS THAN ('20190801') ENGINE = InnoDB) */;

Query OK, 0 rows affected (0.00 sec)

  • partition key column = varchar (6)
  • partition key length = '20190801' → 8
  • 정상 생성

3) MySQL 5.7

# 파티션 키 = 6

> CREATE TABLE `t1` (
`reg_month` varchar(6),
`content_id` int(11),
PRIMARY KEY (`content_id`, `reg_month`)
)
/*!50500 PARTITION BY RANGE COLUMNS(reg_month)
(PARTITION p201702 VALUES LESS THAN ('20170301') ENGINE = InnoDB,
PARTITION p201907 VALUES LESS THAN ('20190801') ENGINE = InnoDB) */;

ERROR 1654 (HY000): Partition column values of incorrect type

 

  • partition key column = varchar (6)
  • partition key length = '20190801' -> 8 
  • 생성 실패

# 파티션 키 = 8
> CREATE TABLE `t1` (
`reg_month` varchar(8),
`content_id` int(11),
PRIMARY KEY (`content_id`, `reg_month`)
)
/*!50500 PARTITION BY RANGE COLUMNS(reg_month)
(PARTITION p201702 VALUES LESS THAN ('20170301') ENGINE = InnoDB,
PARTITION p201907 VALUES LESS THAN ('20190801') ENGINE = InnoDB) */;

Query OK, 0 rows affected (0.01 sec)

  • partition key column = varchar (8)
  • partition key length = '20190801' -> 8
  • partition key column 의 length 를 충족하기때문에 정상 생성

 

3. 결론

사실 5.6 일 때 만들어지는 경우가 논리적으로는 맞지 않다고 생각한다.

 

그리고 생성은 된다고 하더라도, 내부적으로 어떠한 비효율적인 처리가 들어갔을지는 소스 코드를 열어보지 않는 한 알 수 없다.

( 문득 파티션 프루닝이 잘 되지 않을 수도 있겠다는 생각이 들어 explain 을 확인해 본 결과, 그래도 파티션 프루닝은 잘 동작했다 )

 

따라서 5.7 에서는 생성되지 않는 것은 5.6 보다 더 strict 한 동작이지만, 정상적인 처리라는 생각이 든다.

 

해당 케이스는 mysql 5.6 version 의 서버를 dump 로 이관 시에 발견한 이슈인데,

5.7 이전 버전의 서버를 5.7 이상으로 업그레이드 시에는 해당 내용을 확인하는 것도 착오를 줄일 수 있는 방법이라고 생각한다.