MySQL에서 자동으로 파티션을 추가하기 위해 MySQL의 event와 procedure를 활용한다.
1) 프로시져 생성
2) event 생성
1. 프로시저 생성
파티션된 테이블에 maxvalue 파티션이 없는 경우와 maxvalue 파티션이 있는 경우에 대해 각각 파티션을 추가하는 프로시저이다.
1) maxvalue 가 없는 파티션인 경우
maxvalue가 없는 파티션 테이블
CREATE TABLE sales ( sale_id INT NOT NULL, sale_date DATETIME NOT NULL, customer_id INT NOT NULL, amount DECIMAL(10,2), PRIMARY KEY (sale_id, sale_date) ) PARTITION BY RANGE (TO_DAYS(sale_date)) ( PARTITION p_2025_01 VALUES LESS THAN (TO_DAYS('2025-02-01')), PARTITION p_2025_02 VALUES LESS THAN (TO_DAYS('2025-03-01')), PARTITION p_2025_03 VALUES LESS THAN (TO_DAYS('2025-04-01')), PARTITION p_2025_04 VALUES LESS THAN (TO_DAYS('2025-05-01')) );
자동으로 매월 새로운 파티션을 추가하는 프로시저
DELIMITER //
CREATE PROCEDURE pr_monthly_add_partition(IN partition_time DATETIME) BEGIN SET @sql = CONCAT( 'ALTER TABLE sales ADD PARTITION (', 'PARTITION p_', DATE_FORMAT(DATE_SUB(DATE_FORMAT(partition_time, '%Y%m%d'), interval 1 month), '%Y_%m'), ' VALUES LESS THAN (', TO_DAYS(partition_time), '));' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END //
DELIMITER ;
파티션 추가를 위한 프로시저 호출
CALL pr_monthly_add_partition('2025-06-01');
2) maxvalue 가 있는 파티션인 경우
maxvalue가 있는 파티션 테이블
CREATE TABLE sales_max ( sale_id INT NOT NULL, sale_date DATETIME NOT NULL, customer_id INT NOT NULL, amount DECIMAL(10,2), PRIMARY KEY (sale_id, sale_date) ) PARTITION BY RANGE (TO_DAYS(sale_date)) ( PARTITION p_2025_01 VALUES LESS THAN (TO_DAYS('2025-02-01')), PARTITION p_2025_02 VALUES LESS THAN (TO_DAYS('2025-03-01')), PARTITION p_2025_03 VALUES LESS THAN (TO_DAYS('2025-04-01')), PARTITION p_2025_04 VALUES LESS THAN (TO_DAYS('2025-05-01')), PARTITION p_maxvalue VALUES LESS THAN MAXVALUE );
DELIMITER //
CREATE PROCEDURE pr_monthly_add_partition_max(IN partition_time DATETIME) BEGIN SET @sql = CONCAT( 'ALTER TABLE sales_max REORGANIZE PARTITION p_maxvalue INTO(\n', 'PARTITION p_', DATE_FORMAT(partition_time, '%Y_%m'), ' VALUES LESS THAN (', TO_DAYS(partition_time), '),\n', 'PARTITION p_maxvalue', ' VALUES LESS THAN MAXVALUE);');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END //
DELIMITER ;
파티션 추가를 위한 프로시저 호출
CALL pr_monthly_add_partition_max('2025-06-01');
2. event 생성
위에서 생성한 프로시저를 event로 등록하여 필요한 시점에 수행되도록 한다.
event를 수행하기 위해서는 event_scheduler가 ON 으로 설정되어 있어야 한다.
이벤트 스케줄러 활성화
SET GLOBAL event_scheduler = ON;
매달 1일 자동 실행되는 EVENT 생성
매달 1일에 자동으로 파티션을 추가하는 event를 생성한다. event는 매달 1일 00:00:00 에 수행된다.
CREATE EVENT ev_monthly_add_partition ON SCHEDULE EVERY 1 MONTH STARTS TIMESTAMP(LAST_DAY(CURRENT_DATE() - INTERVAL 1 MONTH) + INTERVAL 1 DAY)
ON COMPLETION PRESERVE COMMENT '매달 1일에 파티션 추가 EVENT' DO CALL pr_monthly_add_partition(DATE_FORMAT(LAST_DAY(CURRENT_DATE() - INTERVAL 1 MONTH) + INTERVAL 1 DAY, '%Y-%m-%d'));
CREATE TABLE sales (
sale_id INT NOT NULL,
sale_date DATE NOT NULL,
customer_id INT NOT NULL,
amount DECIMAL(10,2),
PRIMARY KEY (sale_id, sale_date)
)
PARTITION BY RANGE (TO_DAYS(sale_date)) (
PARTITION p_2024_01 VALUES LESS THAN (TO_DAYS('2024-02-01')),
PARTITION p_2024_02 VALUES LESS THAN (TO_DAYS('2024-03-01')),
PARTITION p_2024_03 VALUES LESS THAN (TO_DAYS('2024-04-01')),
PARTITION p_2024_04 VALUES LESS THAN (TO_DAYS('2024-05-01')),
PARTITION p_maxvalue VALUES LESS THAN MAXVALUE
);
Range 파티션은 값으로 int 형 데이터가 와야 하기 때문에 TO_DAYS 함수를 사용.
설명:
TO_DAYS(sale_date) 함수는 분할을 위해 날짜를 숫자 값으로 변환
각 파티션은 특정 월(예: 2024년 1월, 2024년 2월 등)을 기준으로 정의
p_maxvalue 파티션은 2024년 4월보다 큰 모든 데이터를 적재
✔ TO_DAYS 함수를 사용하는 이유 : Range 파티션은 값으로 int 형 데이터가 와야 하기 때문
1-2) 날짜형식의 String으로 사용
DATE 또는 DATETIME 열을 분할 열로 사용하여 RANGE COLUMNS로 테이블을 분할합니다.
CREATE TABLE sales_1 (
sale_id INT NOT NULL,
sale_date DATE NOT NULL,
customer_id INT NOT NULL,
amount DECIMAL(10,2),
PRIMARY KEY (sale_id, sale_date)
)
PARTITION BY RANGE COLUMNS(sale_date) (
PARTITION p_2024_01 VALUES LESS THAN ('2024-02-01'),
PARTITION p_2024_02 VALUES LESS THAN ('2024-03-01'),
PARTITION p_2024_03 VALUES LESS THAN ('2024-04-01'),
PARTITION p_2024_04 VALUES LESS THAN ('2024-05-01'),
PARTITION p_maxvalue VALUES LESS THAN MAXVALUE
);
2) TIMESTAMP 컬럼으로 파티션
UNIX_TIMESTAMP() 함수를 사용해서 파티셔닝 한다.
MySQL 8.4에서는 UNIX_TIMESTAMP() 함수를 사용하여 TIMESTAMP 열의 값을 기준으로 RANGE로 테이블을 분할할 수 있다.
CREATE TABLE quarterly_report_status (
report_id INT NOT NULL,
report_status VARCHAR(20) NOT NULL,
report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),
PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),
PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),
PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
PARTITION p9 VALUES LESS THAN (MAXVALUE)
);
파티션 추가
1) 파티션 테이블이 MAXVALUE로 구성되어 있는 경우에는 REORGANIXE PRTITION 명령어로 기존 MAXVALUE 파티션을 나눈다.
ALTER TABLE sales REORGANIZE PARTITION p_maxvalue INTO(
PARTITION p_2024_05 VALUES LESS THAN (TO_DAYS('2024-06-01')),
PARTITION p_maxvalue VALUES LESS THAN MAXVALUE);
2) 파티션 테이블이 MAXVALUE로 구성되어 있지 않은 경우에는 ADD PRTITION 명령어로 파티션을 추가한다.
ALTER TABLE sales ADD PARTITION (
PARTITION p_2024_05 VALUES LESS THAN (TO_DAYS('2024-06-01'))
);
파티션 삭제
삭제하고자 하는 파티션을 DROP PARTITION 명령어로 삭제한다. 아래는 p_2024_01 파티션을 삭제하는 예제이다.
performance_schema.global_status 의 Uptime 값은 초로 표시되기 때문에 초를 시분으로 변환하여 조회
-- Uptime 을 시분 형식으로 표시 SELECT TIME_FORMAT(SEC_TO_TIME(variable_value ),'%H시간 %i분') as Uptime FROM performance_schema.global_status WHERE variable_name='Uptime'; [결과값] 40시간 16분
--Uptime 을 datetime 형식으로 표시 SELECT FROM_UNIXTIME(UNIX_TIMESTAMP() - variable_value) as Uptime FROM performance_schema.global_status WHERE variable_name='Uptime'; [결과값] 2025-03-25 07:31:29.000000
3) mysql 명령어로 확인
# mysql -u<user> -p<password> -e "status;" | grep -i "uptime" [결과값] Uptime: 2 days 26 min 56 sec
<user>, <password> 는 각자의 DB에서 사용하는 user와 패스워드를 입력
3) mysqladmin status 명령어로 확인
# mysqladmin status -u<user> -p<password> [결과값] Uptime: 145329 Threads: 9 Questions: 46314 Slow queries: 0 Opens: 478 Flush tables: 3 Open tables: 399 Queries per second avg: 0.318
<user>, <password> 는 각자의 DB에서 사용하는 user와 패스워드를 입력
4) mysqladmin version 명령어로 확인
# mysqladmin version -u<user> -p<password> | grep -i "uptime" [결과값] Uptime: 1 day 16 hours 24 min 51 sec
MySQL 이벤트는 일정에 따라 실행되는 작업입니다. 예약된 이벤트라고 합니다. 이벤트를 만들면 주기적인 간격으로 실행할 SQL 문이 포함된 데이터베이스 객체를 만들고, 특정 시간에 시작합니다. Unix crontab (일명 " cron job " ) 또는 Windows 작업 스케줄러와 유사합니다.
Event 관리 - 생성/수정/삭제
1) Event Scheduler 활성화
이벤트를 실행하려면 Event Scheduler가 활성화되어 있어야 합니다. Event Scheduler가 활성화되어 있지 않다면 아래 명령어로 활성화시킵니다.
SET GLOBAL event_scheduler = ON;
2) Event 생성 권한
이벤트가 생성될 스키마에 대한 권한이 필요합니다. Event 생성 권한이 없다면 아래와 같이 EVENT 권한을 부여합니다. 이벤트는 schema 레벨의 권한이므로 테이블 레벨로 권한을 부여할 수 없습니다.
GRANT EVENT ON schemaname.* TO username@'%";
3) Event 생성
아래는 Event 생성 예시입니다.
CREATE EVENT myevent
ON SCHEDULE AT TIMESTAMP(CURRENT_DATE) + INTERVAL 1 HOUR
DO
UPDATE myschema.mytable SET mycol = mycol + 1;
myevent라는 이름의 이벤트를 생성합니다 .
이 이벤트는1시간에 한 번씩 mytable 테이블의 mycol 컬럼값을1씩 증가시키는 SQL 명령문을 실행합니다.
4) 이벤트 수정
이벤트를 수정하려면 'ALTER EVENT' 명령을 사용합니다.
이벤트의 여러 특성을 변경할 수 있습니다.
이 예제에서는 에서 실행되는 SQL 명령문을 myevent에서 모든 레코드를 삭제하고 하루에 한 번(01 시) 실행되도록 변경합니다.
ALTER EVENT myevent
ON SCHEDULE
AT TIMESTAMP(CURRENT_DATE) + INTERVAL 1 DAY + INTERVAL 1 HOUR
DO
TRUNCATE TABLE myschema.mytable;
Global privileges: 전역 권한은 서버의 모든 데이터베이스에 적용됩니다. 관리 권한은 사용자가 MySQL 서버의 작업을 관리할 수 있게 하고 특정 데이터베이스에만 국한되지 않기 때문에 글로벌 그룹에 속합니다.(mysql.user, information_schema.user_privileges)
Database privileges : 데이터베이스 권한은 MySQL 인스턴스의 특정 데이터베이스와 해당 데이터베이스 내의 모든 개체(예: 테이블, 컬럼, 뷰)에 적용됩니다. 데이터베이스 권한을 전역적으로 부여할 수도 있습니다. (mysql.db)
Proxy privileges: 프록시 권한을 사용하면 사용자는 다른 사용자에게 부여된 권한을 갖고 있는 것처럼 행동할 수 있습니다.
Privileges for database objects: 데이터베이스 개체(테이블, 열, 저장 루틴, 뷰 등)에 대한 권한은 특정 데이터베이스 내의 한 유형의 모든 개체 또는 특정 테이블이나 뷰와 같은 특정 개체에 적용될 수 있습니다. 데이터베이스 개체 권한을 전역적으로 부여할 수도 있습니다.
. 실습예제 및 소스 다운로드 : https://github.com/wikibook/bigdata2nd/archive/master.zip
*** 최초 Ubuntu 24.04 LTS 에 설치하려니 지원하지 않는다는 메시지 출력. Ubuntu 20.04 LTS로 변경
*** 아래는 Cloudera Manager 7 이 설치되는 OS 버전임.
Cloudera Manager supports the following 64-bit operating systems:
* Red Hat Enterprise Linux 7 (Update 6 or later recommended)
* Red Hat Enterprise Linux 8 (Update 2 or later recommended)
* Oracle Enterprise Linux 7 (Update 4 or later recommended)
* CentOS 7 (Update 4 or later recommended)
* CentOS 8 (Update 2 or later recommended)
* Ubuntu 18.04 LTS
* Ubuntu 20.04 LTSType 'back' to go back.
4. VM 에 cloudera Manager 설치
1) /etc/hosts 파일에 서버 등록
각자의 서버 IP에 대한 hostname을 /etc/hosts 파일에 등록해 준다. FQDN 은 등록하지 않아도 된다.
단, 주의할 점은 계정과 패스워드에 특수문자는 반드시 퍼센트 인코딩(percent encoding) 문자로 변경해야 한다.
예를 들면, 계정이름이 name@email.com 이라면 '@' 특수문자는 '%40' 으로 퍼센트 인코딩 문자로 변경해야 한다.
# Cloudera Manager 7.11.3
# Changeme: change username and password below to match your license
deb [arch=amd64] https://myUsername:myPassword@archive.cloudera.com/p/cm7/7.11.3/ubuntu2004/apt bionic-cm7.11.3 contrib
Import the repository signing GPG key (substitute the correct URL):
- 위의 명령어에서 username, password, [**Cloudera Manager version**] 부분은 위와 동일하게 Cloudera URL의 계정과 패스워드 그리고 설치할 Cloudera Mnager 버전을 기입한다. 본 문서에서는 7.11.3 버전을 설치한다.