반응형

20분 내외면 수행이 끝났던 월배치 중 하나가

2시간이 넘게 걸리면 연관배치들이 지연처리되면 서비스에 문제가 발생하였다.

 

문제의 sql는 update 를 하는 구문이었고

 

이를 select로 변경하고 실행계획을 분석하던 중에 문제의 원인에 접근했다.

 

 

1.  슬로우쿼리 확인

 

 

#1) AS_IS

explain
select count(*) from TB_AAA T1
INNER JOIN TB_BBB T2            
ON T1.SEQ_NO = T2.SEQ_NO          
INNER JOIN TB_CCC T3 /* 24GB 파티션 테이블 */
ON T1.SEQ_NO = T3.SEQ_NO
WHERE T1.CHNG_DTTM BETWEEN DATE_FORMAT(CONCAT('202305', '01'),'%Y-%m-%d 00:00:00')                        
AND DATE_FORMAT(LAST_DAY(CONCAT('202305', '01')),'%Y-%m-%d 23:59:59')
;

value)
1	SIMPLE	T2	index	IDX_BBB_01		IDX_BBB_01	11			1314006		Using where; Using index
1	SIMPLE	T1	eq_ref	PRIMARY,IDX_AAA_06	PRIMARY		8	XXX.T2.SEQ_NO	1		Using where
1	SIMPLE	T3	ref	IDX_CCC_07		IDX_CCC_07	9	XXX.T2.SEQ_NO	1		Using index

 

# 인덱스 스캔 방법 중 index 란?
인덱스를 처음부터 끝까지 탐색하여 데이터를 찾는 방식 (Index Full scan)

-> index 라고 인덱스 스캔이 잘 된다고 생각하면 안된다 인덱스 스캔을 하는 방식 중에 성능이 매우 떨어지는 방식이다.

 

update문에서 where 조건절 T1.TB_AAA의 컬럼 CHNG_DTTM은

IDX_AAA_06 이라는 인덱스가 있는데

 

조건값 '2023-05-01 00:00:00 ~ 2023-05-31 23:59:59' 가 인덱스를 사용할 수 있는 범위에 해당함에도

이것을 옵티마이져가 제대로 활용하지 못하는 것을 알게 되었다.

 

 

 

옵티마이져가 정말 멍청했는지 직접 인덱스를 할당해서 확인해본다.

 

# TO_BE)

explain
select count(*) from TB_AAA T1 force index (IDX_AAA_06)
INNER JOIN TB_BBB T2            
ON T1.SEQ_NO = T2.SEQ_NO          
INNER JOIN TB_CCC T3 /* 24GB 파티션 테이블 */
ON T1.SEQ_NO = T3.SEQ_NO
WHERE T1.CHNG_DTTM BETWEEN DATE_FORMAT(CONCAT('202305', '01'),'%Y-%m-%d 00:00:00')                        
AND DATE_FORMAT(LAST_DAY(CONCAT('202305', '01')),'%Y-%m-%d 23:59:59')
;

value)
1	SIMPLE	T1	range	IDX_AAA_06	IDX_AAA_06	6			135160		Using index condition
1	SIMPLE	T2	ref	IDX_BBB_01	IDX_BBB_01	9	XXX.T1.SEQ_NO	1		Using index
1	SIMPLE	T3	ref	IDX_CCC_07	IDX_CCC_07	9	XXX.T1.SEQ_NO	1		Using index

 

실행계획으로 보았을 때는 인덱스가 range 스캔으로 풀리는 것으로 보아 더 나은 방식으로 보인다.

 

# 인덱스 스캔 방법 중 ragne 란?

특정 범위 내에서 인덱스를 사용하여 원하는 데이터를 추출한다.

-> ref나 eq_ref보다는 느리지만 그래도 쓸만한 인덱스 검색방식이다. (range_optimizer_max_mem_size 변수와 연관있음)

 

하지만 옵티마이져는 최종 sql 실행시 가장 빠른 방식을 스스로 검색해서 실행계획을 세우기 때문에

반드시 위 인덱스 스캔이 더 빠르다고 판단할 수 없다.

 

실제로 select 문을 실행해 보아야한다.

 

#1) AS_IS 수행시간  ->  22초

#2) TO_BE 수행시간 -> 16초

 

음...

 

 

실제로 옵티마이져가 제대로 실행계획을 세우지 못한 것을 확인했다.

이번에는 옵티마이져가 영리하지 못했다.

 

 

 

2. 원인분석

 

 

그럼 왜 이런 일이 발생한 것일까?

 

그것은 update를 처리하는 테이블과 join 된 파티션 테이블의 용량이 문제였다

파티션 테이블에 별도의 조건값이 없어 파티션 푸르닝이나

파티션의 인덱스를 제대로 활용하지 못하고

통째로 join을 하다보니

 

버그인지는 모르겠지만 ( mariadb ver 10.4.18)
옵티마이져가 조건절의 값이 인덱스가 있음에도 제대로 활용하지 못하는 현상이 발생했다.

 

그럼 24GB나 되는 파티션 테이블을 조인해서 사용도 안하는데

 

왜 조인했나?

 

 

대부분의 화면에서 조회하는 sql은 보통 동적쿼리다.

 

이것이 DBA 입장에서는 상당히 머리가 아파질 수 있는 부분인데

 

예를 들어 신규 개발 SQL을 검수할 때 (동적쿼리라면)

서비스환경을 적대적으로 가정하고 그것에 대한 경우의 수를 생각해

실행계획이나 추가인덱스 설정등..SQL을 더 꼼꼼하게 확인해야하는 어려움이 있다.

 

이번 발생한 슬로우 쿼리 또한

웹페이지에서 조회시 TB_CCC(파티션 테이블)와 관련된 검색조건은 빼고 검색을 해도

조회가 되도록 되어있을 것이다.

 

 

 

3. 해결방법

 

 

 

가장 좋은 해결방법은 TB_CCC(파티션 테이블)에

파티션 푸르닝을 사용할 수 있게 조건값을 추가하거나

아니면 TB_CCC(파티션 테이블)의 용량 자체를 줄여서
옵티마이져가 멍때리지 않고 제대로 역할을 할 수 있게 환경을 만들어 주는 것

 

 

여기서 궁금한 게 생겨 테스트를 해봄!


Test) 

대용량 테이블(TB_CCC)의 파티션을 삭제하면서
언제쯤 옵티마이져가 정상적으로 조건절의 인덱스 값을 가져다 플랜을 만드는지 확인해 보았다.

월별 파티션을 하나씩 지우면서 플랜을 뜨다보니

TB_CCC의 용량이 24GB에서 22GB 로 줄었을 때!

드디어 옵티마이져가 where 조건절의 인덱스 IDX_AAA_06 가져다 실행계획을 세우는 것을 확인함

(아. 그래서 얼마전까지는 발생안했고 이번에 발생했구나...^^;)

 

explain)
1 SIMPLE T1 range	PRIMARY,IDX_AAA_06 	IDX_AAA_06 6 			134702 	Using where; Using index
1 SIMPLE T2 ref 	IDX_BBB_01 		IDX_BBB_01 9 	XXX.T1.SEQ_NO 	1 	Using index
1 SIMPLE T3 ref		IDX_CCC_07 		IDX_CCC_07 9 	XXX.T1.SEQ_NO 	1 	Using index


TB_CCC(파티션 테이블) 의 조인 컬럼 SEQ_NO 의 인덱스를 메모리에 올려 실행계획을 세울 때

옵티마이져가 판단하는데도 MAX 가 있는 것으로 보임

 

 24GB가 넘어가면서 문제가 생겼는데..
이것이 22GB 줄었을 때는 옵티마이저가 다시 재정신을 차림

 

검증은 끝났고 

화면에서 파티션 푸르닝 기능을 사용할 수 있는지 개발과 협의해 봐야겠고,

TB_CCC(파티션 테이블)의 데이터 용량은 삭제 주기를 정해서 6개월 이내의 데이터는 삭제하는 것으로 사업부서와 협의해봐야겠다.

force index까지는 사용하지 않고 끝났으면 좋겠다.

 

 

4.결론

 

대용량 파티션 테이블 join 사용법

1) 가능하면 파티션 푸르닝이 포함된 컬럼을 where 조건절에 넣는다.

2) 그것이 안되면 파티션 삭제주기를 정해서 주기적으로 파티션 테이블 용량을 관리한다.

3) 이것도 안될시에는 파티션 테이블을 사용하는 sql을 주기적으로 모니터링하면서
인덱스 스캔이 불가능해지면 forec index로 인덱스를 강제로 할당한다.

 


#파티션 푸르닝이란?
파티션 프루닝(pruning)은 MySQL 에서 WHEHE 구문에 사용된 조회 조건에 만족한 파티션만 추출하는 기능이다.
최적화 단계에서 필요한 파티션만 골라내고 불필요한 것들은 배제하는 것 입니다.
파티션 프루닝은 SELECT, DELETE, UPDATE 구문에서만 가능합니다.

 

 

끝.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 / 직업은 MYSQL과 함께 일하는 DBA / 즐거운 엔지니어의 끝나지 않는 이야기

,
반응형

mariadb 10.4 이전에는 아래구문으로 일반 user도 테이블의 데이터를 FILE로 만들수 있게 업데이트가 가능했다.

 

update mysql.global_priv
SET File_priv = 'Y'
where user = 'xxxadm';

 

하지만 MariaDB 10.4/mysql 8.0 이상에서 실제 테이블이 아니고 view로 대체되어 바로 업데이트가 불가하다.
보안조치라고 하는데 상세 내용은 아래와 같다.

1) mysql에서 설명
다음 작업 및 서버 동작에 영향을 줍니다.
LOAD DATA 및 SELECT를 사용하여 서버 호스트에서 파일을 읽고 작성할 수 있습니다. 

OUTFILE 문 과 LOAD_FILE() 함수로.
FILE 권한이 있는 사용자는 MySQL 서버에서 읽을 수 있거나 읽을 수 있는 서버 호스트의 모든 파일을 읽을 수 있습니다. 

(이는 서버가 해당 파일에 액세스할 수 있기 때문에 사용자가 모든 데이터베이스 디렉터리에서 모든 파일을 읽을 수 있음을 의미합니다.)

MySQL 서버가 쓰기 액세스 권한이 있는 모든 디렉터리에서 새 파일을 만들 수 있습니다. 여기에는 권한 테이블을 구현하는 파일이 포함된 서버의 데이터 디렉터리가 포함됩니다.
테이블 만들기 문에 대한 또는 테이블 옵션을 사용할 수 있습니다. 
DATA DIRECTORYINDEX DIRECTORY 보안 조치로 서버는 기존 파일을 덮어쓰지 않습니다<-- update 안된다

 

* mysql.user 테이블의 컬럼 설명
   Select_priv   : select문을 수행할 수 있는 권한
   Insert_priv   : insert문을 수행할 수 있는 권한
   Update_priv   : update문을 수행할 수 있는 권한
   Delete_priv   : delete문을 수행할 수 있는 권한
   Create_priv   : create문을 수행하거나 테이블을 생성할 수 있는 권한
   Drop_priv     : drop문을 수행하거나 데이타베이스를 삭제할 수 있는 권한
   Reload_priv   : mysqladmin reload명령을 이용하여 접근정보를 다시 읽을 수 있는 권한
   Shutdown_priv : mysqladmin shutdown명령을 이용하여 서버를 종료시킬 수 있는 권한
   Process_priv  : 서버 프로세스를 관리할 수 있는 권한
   File_priv     : select into outfile과 load data infile과 같은 명령을 이용하여 파일에 읽고 쓸 수 있는 권한
   Grant_priv    : 자신의 권한을 남에게 부여할 수 있는 권한
   References_priv : 사용하지 않음
   Index_priv    : 인덱스를 만들거나 삭제할 수 있는 권한 
   Alter_priv    : alter table문을 수행할 수 있는 권한
https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html

2) MariaDB에서 설명
MariaDB 10.4 이후부터는 mysql.global_priv 테이블이 테이블을 대체했으며 이제 뷰(VIEW)가 됩니다.
MariaDB 10.4.13에서 전용 사용자는 뷰(VIEW)의 정의자로 만들어집니다. 이전에는 정의자였으며, 이 사용자 이름이 변경되었을 때 권한 문제가 발생했습니다.(MDEV-19650).mysql.usermysql.usermariadb.sysroot

 

3) 일반 user에게 outfile 권한 할당

 

MariaDB [mysql]> GRANT SELECT, FILE ON `mysql`.* TO 'xxxadm'@'%';
ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
//mysql에 권한을 주려고 했는데 실패했다. 좀 더 확인해보니 아래와 같은 이유로 권한생성이 되지 않았다.

 

FILE 권한은 LOAD DATA INFILE 및 SELECT를 사용하여 서버 호스트에서 파일을 읽고 쓸 수 있는 권한을 제공합니다. 
OUTFILE 문과 LOAD_FILE() 함수로. FILE 권한이 있는 사용자는 MySQL 서버에서 읽을 수 있거나 읽을 수 있는 서버 호스트의 모든 파일을 읽을 수 있습니다. 
(이는 서버가 해당 파일에 액세스할 수 있기 때문에 사용자가 모든 데이터베이스 디렉터리에서 모든 파일을 읽을 수 있음을 의미합니다.)

따라서 FILE 권한은 전역 권한입니다. <-- 전역권한이다. 그렅다면 특정스키마만 별도로 할당할 수 없다는 얘기다.
서버의 모든 파일에 영향을 미치고 데이터베이스범위에 포함되지 않은 전역 명령(예: 등)에만 액세스할 수 있습니다. 
FILE 권한을 부여하는 유일한 방법은 이 구문을 사용하여 모든 데이터베이스에 있습니다.

 

전역권한이라면 일반 user에 outfile 권한을 주는 것이기 때문에 

tool이나 api로 접근할 수 있는 %는 보안상 문제가 있을 것으로 보인다.
localhost에서만 가능하도록 권한을 할당한다.

 

GRANT FILE ON *.* TO 'xxxadm'@'localhost';
flush privileges;

//확인
MariaDB [(none)]> SELECT Host, File_priv FROM mysql.user WHERE user = 'xxxadm' \G;
*************************** 1. row ***************************
     Host: localhost
File_priv: Y
*************************** 2. row ***************************
     Host: %
File_priv: N
2 rows in set (0.002 sec)

localhost에 file_priv권한Y 로 변경된 것을 확인할 수 있다.

 

 

4) 테스트

[admin@maria-db ~]$ mysql -uxxxadm -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 1478
Server version: 10.4.18-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use xxxDB;
Database changed
MariaDB [xxxDB]> select * from TMP_LOAD_20210604 limit 200 into outfile '/data/mariadb_tmp/TMP_LOAD_20210604.out';
Query OK, 200 rows affected, 1 warning (0.003 sec)

끝~

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 / 직업은 MYSQL과 함께 일하는 DBA / 즐거운 엔지니어의 끝나지 않는 이야기

,
반응형

[ERROR] [FATAL] InnoDB: Semaphore wait has lasted > 600 seconds. We intentionally crash the server because it appears to be hung.
[ERROR] mysqld got signal 6 ;

 

DB는 얼마지나지 않아 다시 내려갔다.
눈앞이 캄캄해진다.
--> 며칠전에 오라클에서 마리아DB로 마이그레이션후 수많은 장애로 다시는 마리아DB를 쳐다보고 싶지 않다는 블로그에 글을 읽으며 속으로는 그러게 준비를 잘했어야지 RDB라고 다 같은 줄 아나? 라고 속으로 웃었는데.. 사람은 착하게 살아야; 막상 당해보니 너무 아프네

 

이제 방법은 2가지 문제를 해결하거나 아니면 MariaDB 10.2.15 로 롤백하는 방법뿐이다.
결정은 롤백에 소요되는 시간을 고려하면 남은시간은 15시간 뿐이다.

문뜩 그런생각이 들었다

이 일을 막을 수 있었나?
--> 막을 수 있었다. 서비스 DB와 동일한 환경에서 테스트를 더 했더라면 충분히 막을 수 있었다. 하지만 대용량DB라 그럴만한 서버가 없었다...아니다 그것을 설득하지 못한 DBA의 핑계일지도..

 

갑자기 요즘 즐겨보던 유튜브 중 한편이 생각난다.

www.youtube.com/watch?v=DsOUEAbzaIA

 

 

#경영효율화로 인한 희생 알래스카 항공 261편 ... 기장은 최선을 다했고 마지막까지 배면비행을 하며 사투를 벌였지만 살아남지 못했다... 나는 살아남을 수 있을까?

그냥그렇다.. 아무생각도 들지않고 멍하니 로그와 구글링 페이지만 30분째 보고 있었다.
하지만 시간은 한정되어 있고 그 시간안에 해결할 방법을 찾아야한다.

일단 정신차리고 error로그 먼저 확인해 본다.

2021-02-27  1:28:41 284 [ERROR] mysqld: Table './xxxDB/TB_STA_xxx' is marked as crashed and last (automatic?) repair failed
2021-02-27  1:28:41 284 [ERROR] mysqld: Table './xxxDB/TB_STA_xxxxx' is marked as crashed and last (automatic?) repair failed

DB는 재시작하면서 복구를 했지만 MyISAM 테이블이 일부가 깨졌다. 수동복구를 진행한다.

 

MariaDB [xxxDB]> check table TB_STA_xxx;
+------------------+-------+----------+-------------------------------------------------------+
| Table            | Op    | Msg_type | Msg_text                                              |
+--------------------------+----------+-------------------------------------------------------+
| xxxDB.TB_STA_xxx | check | warning  | Table is marked as crashed and last repair failed     |
| xxxDB.TB_STA_xxx | check | warning  | 1 client is using or hasn't closed the table properly |
| xxxDB.TB_STA_xxx | check | warning  | Size of indexfile is: 167163904      Should be: 1024  |
| xxxDB.TB_STA_xxx | check | error    | Record-count is not ok; is 3159708   Should be: 0     |
| xxxDB.TB_STA_xxx | check | warning  | Found 3159715 key parts. Should be: 0                 |
| xxxDB.TB_STA_xxx | check | error    | Corrupt                                               |
+--------------------------+----------+-------------------------------------------------------+
6 rows in set (7.935 sec)

MariaDB [xxxDB]> repair table TB_STA_xxx;
+------------------+--------+----------+------------------------------------------+
| Table            | Op     | Msg_type | Msg_text                                 |
+------------------+--------+----------+------------------------------------------+
| xxxDB.TB_STA_xxx | repair | warning  | Number of rows changed from 0 to 3159708 |
| xxxDB.TB_STA_xxx | repair | status   | OK                                       |
+------------------+--------+----------+------------------------------------------+
2 rows in set (22.793 sec)'

 

테이블 복구후 DB가 내려간 부분을 확인해본다.

1 lock struct(s), heap size 1128, 0 row lock(s), undo log entries 218
MySQL thread id 21136, OS thread handle 140521381996288, query id 12716892 172.31.8.77 mdlbat Sending data
SELECT COUNT(*) FROM TB_xxx    WHERE ..

 

카운트하는데 락이 생겼다? 뭔가 이상하다.

MetaLock을 확인해본다.

MariaDB [(none)]> SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+-------------------------+---------------+----------------------+--------------+-----------------------+
| THREAD_ID | LOCK_MODE               | LOCK_DURATION | LOCK_TYPE            | TABLE_SCHEMA | TABLE_NAME            |
+-----------+-------------------------+---------------+----------------------+--------------+-----------------------+
|     44657 | xxx_BACKUP_DDL          | NULL          | Backup lock          |              |                       |
|     44657 | xxx_EXCLUSIVE           | NULL          | Table metadata lock  | xxxDB        | TB_TEMP_xxx 			|
|     44657 | xxx_INTENTION_EXCLUSIVE | NULL          | Schema metadata lock | xxxDB        |                       |
|     44657 | xxx_SHARED_READ         | NULL          | Table metadata lock  | xxxDB        | TB_TEMP_xxx		    |
|     44657 | xxx_SHARED_READ         | NULL          | Table metadata lock  | xxxDB        | TB_BAT_xxx      		|
+-----------+-------------------------+---------------+----------------------+--------------+-----------------------+

Schema metadata lock 이런 락은 처음보는데.. 뭔가 이상하다.
Tool로 접속해서 실제 테이블 데이터를 한번 봐야할 거 같다.

음?..Tool 자체 커넥션이 안된다. 다시 쉘로 돌아와서 보니 Meta LOCK이 잡혀있다.

| 45258 |  xxxxx   | 210.xxx.xxx.xxx:45944 | xxxDB | Query   |   29 | Waiting for table metadata lock | 
SELECT cc.CONSTRAINT_NAME, cc.CHECK_CLAUSE, tc.TABLE_NAME
FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS cc, INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
WHERE cc.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
AND cc.CONSTRAINT_SCHEMA ='xxxDB' AND tc.TABLE_NAME='TB_TEMP_xxx'
ORDER BY cc.CONSTRAINT_NAME ;

뭔가 이상하다. Create table로 대용량테이블에서 인댁스 걸린 일데이터만 쪼개서 생성하는 로직인데, 
Tool에서 접속시 information 스키마부분을 조회한다고 Metalock이 잡혀 Tool 접속이 안된다는 것이.. 

MyISAM도 아니고.. InnoDB인데..
이 떄부터 MariaDB 10.4.17 자체 버그를 의심했다.

 

구글링하면서 MairDB를 업그레이드하고 동일한 현상의 문제를 겪은 사람들의 블로그를 하나둘씩 찾을 수 있었다.
innodb_purge_threads 를 1로 변경하면 임시조치로 DB가 재시작되는 것은 막을수 있다는 얘기가 있어
일단 반영해보기로 하였다.

 

MariaDB [(none)]> show global variables like  'innodb_purge%';
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| innodb_purge_batch_size              | 300   |
| innodb_purge_rseg_truncate_frequency | 128   |
| innodb_purge_threads                 | 1     |
+--------------------------------------+-------+
3 rows in set (0.001 sec)

 

이제 끝났겠지라고 생각했지만 10시간후 DB는 재시작되었다.
이 방법은 아니다. 이제 남은시간은 4시간뿐;

 

MariaDB jira의 사례를 찾고 또 찾았다.

비슷한 사례의 글을 찾을 수 있었으나 해결했다는 글은 찾아볼 수 없었다. 

그러던 중 10.4.15에서 17로 올린 사람은 고통받다 롤백을 결정했다는 글에서 링크걸린 글을 찾다보니

10.4.14에서 17로 올리고 동일한 현상으로 고통받고 있는 사람의 글 맨아래 comment에서
10.5.8에서 10.5.9로 올리고 해결되었다는 글을 찾을 수 있었다. 10.5.9의 10.4.x 동일버전은 10.4.18이다.

 

jira.mariadb.org/browse/MDEV-24378

Comments: I have been using 10.5.8 ... the problem has been resolved after upgrading to 10.5.9

 

그렇다면 10.4.18로 올려볼만하다.
--> 하지만 이제 4시간밖에 남지 않았다. 한번 선택하면 끝이다. 

 

그리고 설득도 어려웠다. 업그레이드는 web/was를 내려야하기 때문에 윗선에 결제가 필요했다.

설득하고 또 설득했다. 롤백은 cold 백업후 중단시간이 길기 때문에 한번 해볼만한 시도라고...

(자세히 얘기하면 길어지고 설득하기 쉽지 않을 거 같아 간략하게 설명했지만

사실상 10.2.15로 롤백한다면 mariabackup shell도 xtrabackup으로 변경해야하고 redo log 파일변경부터해서, 10.3.x부터 mysql 부분 information 스키마, 계정관리등등..이 바뀌기 때문에 10.4.x의 mysql 스키마를 쓰지 못하고 이전 mysql 스키마만 다시 떠야하고.. 많이 복잡해진다.)

 

다행히 1시간만에  업그레이드가 결정되었고 내선택이 최선이길 바라며 MaiaDB 10.4.18로 업그레이드를 진행하였다.

 

mariadb.com/kb/en/mariadb-10418-release-notes/

Last month long-time MariaDB VP of Engineering, Rasmus Johansson, passed due to complications from cancer. 
His loss has been felt keenly by the whole MariaDB team. 
Our thoughts are with his family during this difficult time and this release is dedicated to his memory.
-->이번 release는 뭔가 좀 다르다. 마음이 먹먹해지는 글이다. 그를 위해 바치는 이 release가 나에게도 한줄기 빛이 되길 기대해본다 제발!!

 

[root@xxx-db bin]# service mysqld start
.......                                                    [  OK  ]

[admin@xxx-db bin]$ mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 20
Server version: 10.4.18-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show processlist;
+----+-------------+----------------------+-------+---------+------+--------------------------+------------------+----------+
| Id | User        | Host                 | db    | Command | Time | State                    | Info             | Progress |
+----+-------------+----------------------+-------+---------+------+--------------------------+------------------+----------+
|  4 | system user |                      | NULL  | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  2 | system user |                      | NULL  | Daemon  | NULL | InnoDB purge coordinator | NULL             |    0.000 |
|  1 | system user |                      | NULL  | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  3 | system user |                      | NULL  | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  5 | system user |                      | NULL  | Daemon  | NULL | InnoDB shutdown handler  | NULL             |    0.000 |
...
| 20 | root        | localhost            | NULL  | Query   |    0 | Init                     | show processlist |    0.000 |
+----+-------------+----------------------+-------+---------+------+--------------------------+------------------+----------+
17 rows in set (0.000 sec)

MariaDB [(none)]> exit
Bye

//10.4.18로 바뀐거 확인하고 데이터 업그레이드 진행하였다.

[root@xxx-db bin]# ./mysql_upgrade -uroot -p
Enter password: 
Phase 1/7: Checking and upgrading mysql database
Processing databases
mysql
mysql.column_stats                                 OK
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.global_priv                                  OK
mysql.gtid_slave_pos                               OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.index_stats                                  OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.plugin                                       OK
mysql.proc                                         OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.roles_mapping                                OK
mysql.servers                                      OK
mysql.table_stats                                  OK
mysql.tables_priv                                  OK
mysql.time_zone                                    OK
mysql.time_zone_leap_second                        OK
mysql.time_zone_name                               OK
mysql.time_zone_transition                         OK
mysql.time_zone_transition_type                    OK
mysql.transaction_registry                         OK
Phase 2/7: Installing used storage engines... Skipped
Phase 3/7: Fixing views
.....
information_schema
performance_schema
test
Phase 7/7: Running 'FLUSH PRIVILEGES'
OK

[root@xxx-db error]# service mysqld restart
Shutting down MariaDB..                                    [  OK  ]
Starting MariaDB.210227 14:39:24 mysqld_safe Logging to '/data/mariadb_logs/error/mysql.err'.
210227 14:39:24 mysqld_safe Starting mysqld daemon with databases from /data/mariadb_data
                                                           [  OK  ]

 

DB는 2021.3.15일 현재까지 정상적으로 잘 돌아가고 있다.
결과적으로 MariaDB 10.4.17 stable 버전을 설치했지만 자체버그이고

10.4.17을 10.4.18로 올리고 모든 문제는 해결되었다.
왜 무리하게 버전을 올리려고 했을까? 돌이켜 생각해보면 별도의 튜닝없이도 1시간 걸리는 배치가

40분내외로 줄어드는 성능향상을 확인했고, 
100개가 넘는 배치들과 현재DB의 수용능력이 포화상태라 생각해서 결정한 일이었는데, 

꼼꼼한 테스트를 하지 못해 악수가 되고 말았다.

 

DB 업그레이드는 많은 시간과 테스트를 해보고 좀 더 보수적으로 해야한다는 것을 다시한번 느끼게 해주는 경험이었다.
나의 주말은 2주째 치열했지만 누군가 MariaDB 업그레이드후 고통받고 있을 분에게 도움이 되길..

나는 살아남았다.

2차 대응 끝.

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 / 직업은 MYSQL과 함께 일하는 DBA / 즐거운 엔지니어의 끝나지 않는 이야기

,
반응형

마리아 그녀를 믿지 마세요..

 

MariaDB 10.2.15 to 10.4.17 로 올린 후 DB가 shutdown 되고 있다.
정확하게 얘기하면 내려갔다 다시 올라오고 있다.

로그를 확인해보면 
[FATAL] InnoDB: Semaphore wait has lasted > 600 seconds 에러가 나고 자체적으로 복구하고 재시작을 하고 있다.

 

2021-02-19 11:47:06 153730 [Warning] Aborted connection 153730 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got timeout reading communication packets)
2021-02-19 11:47:07 153996 [Warning] Aborted connection 153996 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:07 153995 [Warning] Aborted connection 153995 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:08 153735 [Warning] Aborted connection 153735 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got timeout reading communication packets)
2021-02-19 11:47:10 154001 [Warning] Aborted connection 154001 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:10 154000 [Warning] Aborted connection 154000 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:10 153741 [Warning] Aborted connection 153741 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got timeout reading communication packets)
2021-02-19 11:47:12 154007 [Warning] Aborted connection 154007 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:12 154006 [Warning] Aborted connection 154006 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:12 154005 [Warning] Aborted connection 154005 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:12 154004 [Warning] Aborted connection 154004 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:12 154003 [Warning] Aborted connection 154003 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:13 153747 [Warning] Aborted connection 153747 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got timeout reading communication packets)
2021-02-19 11:47:14 154012 [Warning] Aborted connection 154012 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:14 154011 [Warning] Aborted connection 154011 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:15 153753 [Warning] Aborted connection 153753 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got timeout reading communication packets)
InnoDB: ###### Diagnostic info printed to the standard error stream
2021-02-19 11:47:16 0 [ERROR] [FATAL] InnoDB: Semaphore wait has lasted > 600 seconds. We intentionally crash the server because it appears to be hung.
210219 11:47:16 [ERROR] mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.

To report this bug, see https://mariadb.com/kb/en/reporting-bugs

We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed, 
something is definitely wrong and this may fail.

Server version: 10.4.17-MariaDB-log
key_buffer_size=33554432
read_buffer_size=16777216
max_used_connections=142
max_threads=1002
thread_count=109
It is possible that mysqld could use up to 
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 24682647 K  bytes of memory
Hope that's ok; if not, decrease some variables in the equation.

Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x0 thread_stack 0x40000
/data/mariadb/bin/mysqld(my_print_stacktrace+0x2e)[0x5635b663de1e]
/data/mariadb/bin/mysqld(handle_fatal_signal+0x30f)[0x5635b604b3af]
/lib64/libpthread.so.0(+0x330de0f7e0)[0x7f0e427e47e0]
/lib64/libc.so.6(gsignal+0x35)[0x7f0e416a54f5]
/lib64/libc.so.6(abort+0x175)[0x7f0e416a6cd5]
2021-02-19 11:47:17 154018 [Warning] Aborted connection 154018 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:17 154017 [Warning] Aborted connection 154017 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:47:17 154016 [Warning] Aborted connection 154016 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
/data/mariadb/bin/mysqld(+0xc382f0)[0x5635b63412f0]
/data/mariadb/bin/mysqld(+0xbf07c2)[0x5635b62f97c2]
/lib64/libpthread.so.0(+0x330de07aa1)[0x7f0e427dcaa1]
2021-02-19 11:47:18 153758 [Warning] Aborted connection 153758 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got timeout reading communication packets)
/lib64/libc.so.6(clone+0x6d)[0x7f0e4175bc4d]
The manual page at https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/ contains
information that should help you find out what is causing the crash.
Writing a core file...
Working directory at /data/mariadb_data
Fatal signal 11 while backtracing
2021-02-19 11:47:27 0 [Note] InnoDB: Using Linux native AIO
2021-02-19 11:47:27 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2021-02-19 11:47:27 0 [Note] InnoDB: Uses event mutexes
2021-02-19 11:47:27 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2021-02-19 11:47:27 0 [Note] InnoDB: Number of pools: 1
2021-02-19 11:47:27 0 [Note] InnoDB: Using SSE2 crc32 instructions
2021-02-19 11:47:27 0 [Note] InnoDB: Initializing buffer pool, total size = 96G, instances = 8, chunk size = 128M
2021-02-19 11:47:31 0 [Note] InnoDB: Completed initialization of buffer pool
2021-02-19 11:47:32 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2021-02-19 11:47:33 0 [Note] InnoDB: Starting crash recovery from checkpoint LSN=12397809980512
2021-02-19 11:47:42 0 [Note] InnoDB: 1 transaction(s) which must be rolled back or cleaned up in total 861 row operations to undo
2021-02-19 11:47:42 0 [Note] InnoDB: Trx id counter is 119829882
2021-02-19 11:47:42 0 [Note] InnoDB: Starting final batch to recover 170415 pages from redo log.
2021-02-19 11:47:47 0 [Note] InnoDB: To recover: 168236 pages from log
2021-02-19 11:48:02 0 [Note] InnoDB: To recover: 154841 pages from log
2021-02-19 11:48:17 0 [Note] InnoDB: To recover: 146890 pages from log
2021-02-19 11:48:32 0 [Note] InnoDB: To recover: 139733 pages from log
2021-02-19 11:48:47 0 [Note] InnoDB: To recover: 132848 pages from log
2021-02-19 11:49:02 0 [Note] InnoDB: To recover: 125675 pages from log
2021-02-19 11:49:17 0 [Note] InnoDB: To recover: 118673 pages from log
2021-02-19 11:49:32 0 [Note] InnoDB: To recover: 111753 pages from log
2021-02-19 11:49:47 0 [Note] InnoDB: To recover: 104255 pages from log
2021-02-19 11:50:02 0 [Note] InnoDB: To recover: 97230 pages from log
2021-02-19 11:50:17 0 [Note] InnoDB: To recover: 89903 pages from log
2021-02-19 11:50:32 0 [Note] InnoDB: To recover: 82002 pages from log
2021-02-19 11:50:47 0 [Note] InnoDB: To recover: 74631 pages from log
2021-02-19 11:51:02 0 [Note] InnoDB: To recover: 68116 pages from log
2021-02-19 11:51:17 0 [Note] InnoDB: To recover: 61849 pages from log
2021-02-19 11:51:32 0 [Note] InnoDB: To recover: 54565 pages from log
2021-02-19 11:51:47 0 [Note] InnoDB: To recover: 43859 pages from log
2021-02-19 11:52:02 0 [Note] InnoDB: To recover: 37005 pages from log
2021-02-19 11:52:17 0 [Note] InnoDB: To recover: 30065 pages from log
2021-02-19 11:52:32 0 [Note] InnoDB: To recover: 23362 pages from log
2021-02-19 11:52:47 0 [Note] InnoDB: To recover: 16618 pages from log
2021-02-19 11:53:02 0 [Note] InnoDB: To recover: 9739 pages from log
2021-02-19 11:53:17 0 [Note] InnoDB: To recover: 1741 pages from log
2021-02-19 11:53:22 0 [Note] InnoDB: Last binlog file './mysql-bin.000001', position 7587824
2021-02-19 11:53:22 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
2021-02-19 11:53:22 0 [Note] InnoDB: Starting in background the rollback of recovered transactions
2021-02-19 11:53:22 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2021-02-19 11:53:22 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2021-02-19 11:53:22 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2021-02-19 11:53:22 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2021-02-19 11:53:22 0 [Note] InnoDB: Waiting for purge to start
2021-02-19 11:53:22 0 [Note] InnoDB: 10.4.17 started; log sequence number 12397810010280; transaction id 119829883
2021-02-19 11:53:22 0 [Note] InnoDB: Loading buffer pool(s) from /data/mariadb_data/ib_buffer_pool
2021-02-19 11:53:22 0 [Note] Plugin 'FEEDBACK' is disabled.
2021-02-19 11:53:22 0 [Warning] Plugin 'FEDERATED' is of maturity level gamma while the server is stable
2021-02-19 11:53:22 0 [Note] Server socket created on IP: '::'.
2021-02-19 11:53:22 0 [Warning] 'user' entry 'root@privacy-db' ignored in --skip-name-resolve mode.
2021-02-19 11:53:22 0 [Warning] 'proxies_priv' entry '@% root@privacy-db' ignored in --skip-name-resolve mode.
2021-02-19 11:53:22 0 [Note] Reading of all Master_info entries succeeded
2021-02-19 11:53:22 0 [Note] Added new Master_info '' to hash table
2021-02-19 11:53:22 0 [Note] /data/mariadb/bin/mysqld: ready for connections.
Version: '10.4.17-MariaDB-log'  socket: '/tmp/mysql.sock'  port: 3306  MariaDB Server
2021-02-19 11:53:26 0 [Note] InnoDB: Rolled back recovered transaction 119825411
2021-02-19 11:53:26 0 [Note] InnoDB: Rollback of non-prepared transactions completed
2021-02-19 11:53:30 34 [Warning] Aborted connection 34 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:30 33 [Warning] Aborted connection 33 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:30 32 [Warning] Aborted connection 32 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:30 31 [Warning] Aborted connection 31 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:30 30 [Warning] Aborted connection 30 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:30 28 [Warning] Aborted connection 28 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:32 35 [Warning] Aborted connection 35 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:32 36 [Warning] Aborted connection 36 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:32 49 [Warning] Aborted connection 49 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:32 38 [Warning] Aborted connection 38 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)
2021-02-19 11:53:32 37 [Warning] Aborted connection 37 to db: 'xxxDB' user: 'xxxuser' host: '192.168.10.77' (Got an error reading communication packets)'

발생로그를 확인해보니 특정 테이블에 insert를 할 때마다 DB가 요동치다가 결국 죽는 것으로 확인했다.
이 테이블은 파티션테이블로 전체데이터는 약 30억건 정도 있는 테이블인데..
인덱스는 깨진 것을 확인했다.

--> DB 업그레이드하다 인덱스가 깨진 것 같다. MyISAM에서는 흔한 증상인데 innoDB에서 발생하니 좀 의외이긴하다.

일단 기도하는 마음으로 count(*)를 날려본다. 조회가 안된다면 PK가 깨진것이다. --> 조회가 안되면... 아.. 오늘이 퇴사하는 날이네? 라고 생각하면 된다

(innodb엔진 테이블의 모든데이터는 pk를 기준으로 데이터를 쌓고 모든 데이터에 pk의 시퀀스가 있어 복구하기 쉽지 않다)

 

MariaDB [xxxDB]> select count(*) from TB_xxx partition (p202102);
+-----------+
| count(*)  |
+-----------+
| 295327224 |
+-----------+
1 row in set (11 min 40.089 sec)

 

다행 PK는 깨지지 않았다 ㅠ
그럼 second index 가 깨진 것이고 이것을 복구하는 방법은 
1) shutdown이 가능하다면 innodb 복구 1~6 중에 해서 복구가가능하고, 
2) shutdown이 불가능하면 테이블스키마를 새로파고 insert into~로 데이터만 가져다 복구하는 방법
3) .ibd 파일만가지고가서 tablespace 교체로 복구하는 방법이 있다.

 

데이터가 거의 3억건이라서 원래는 3)번을 해야하는데 파티션 테이블이고 생각보다 복잡해질 거 같아 2)으로 진행했다.
테이블 스키마를 새로생성하고 insert 를 진행하는데
그런데?... insert 가 되지 않았다;
어떤 문제인지 테이블에 데이터를 하나하나씩 검토중에 datetime 형식의 파일이 이상하게 들어가 있는 것을 확인했다;

 

5033-11-13 23:34:31 8675-08-18 08:29:33

 

데이터가 깨졌다. 
DB 버전업하고 데이터가 꺠진것이다.ㅠ 하지만 다행이다. 이미 통계쪽 백업은 배치로 만들어놓아서 당장 전전월의 raw 데이터가 필요하진 않다.
한달치만 살리면 된다.

일단 테이블을 교체해서 새로 들어오는 데이터는 정상적으로 쌓이는 거을 확인했다. 복구는 개발쪽과 협의해서 raw 파일은 있으니 월말 전까지만 다시 insert 하면 된다.

추가로 확인해보니 DB 10.4.17로 업그레이드후.. 나머지 테이블은 1000만건, 3000만건 등등.. 멀쩡한데, 

30억건 6억건 되는 테이블 2개만 datatime 컬럼 데이터가 깨졌다.ㅠ
이 정도 큰 대용량 테이블은 제대로 업그레이드 지원이 되지 않은 거 같다.

아.. 새벽 5시네 이제 별일 없기를..
1차 대응 끝.

 

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 / 직업은 MYSQL과 함께 일하는 DBA / 즐거운 엔지니어의 끝나지 않는 이야기

,
반응형

1. 업그레이드 준비

 

#마리아DB 10.4의 변화와 개선점
https://mariadb.com/kb/en/changes-improvements-in-mariadb-104/

 

1.인증에서 달라진 점

1) mysql.host 테이블이 더 이상 생성되지 않음
2) mysql.user 테이블이 폐기되고, 사용자 계정 및 글로벌 권한이 mysql.global_priv 테이블에 저장됨

 

2.엔진(InnoDB) 에서 달라진 점

1) Online DDL 알고리즘 algorithm=INSTANT 지원범위 추가됨 (MDEV-15562)
- Drop column, changing of the order of columns

2) 테이블 ROW_FORMAT=COMPACT, DYNAMIC or COMPRESSED 로 압축된 row형식이라도 제한적으로 instant 지원 (MDEV-15563)
- MariaDB 10.4.3 이상에서 InnoDB는 또한 ROW_FORMAT 테이블 옵션을 CONCOMPANT, DYNAMIC 또는 CONPRED로 설정한 경우에도 algorithm=INSTANT로 설정하면 VARCHAR 열의 길이를 더 제한적으로 늘릴 수 있도록 지원한다.
- 열의 원래 길이가 127바이트 이하, 열의 새 길이가 256바이트 이상이면 알고리즘을 INSTANT로 설정하면 길이를 늘릴 수 있다.
- 열의 원래 길이가 255바이트 이하인 경우, 열의 새 길이는 여전히 255바이트 이하인 경우 알고리즘을 INSTANT로 설정하면 길이를 늘릴 수 있다.
- 열의 원래 길이가 256바이트 이상이고, 열의 새 길이가 여전히 256바이트 이상이면 알고리즘을 INSTANT로 설정하면 길이를 늘릴 수 있다.
- 원래 길이가 128바이트에서 255바이트 사이였고, 새로운 길이가 256바이트 이상이면 알고리즘을 INSTANT로 설정한 상태에서 길이를 늘릴 수 없다.
- 자세한 내용은 MDEV-15563을 참조한다.

 

3) 인덱스 없는 컬럼에 instant로 정렬 or 문자셋 변경 (MDEV-15564)
4) undo tablespace를 초기화 하기위한 redo log 볼륨을 줄임 (MDEV-17138)
5) MariaDB 10.2.19 이전 truncate table 에 대한 crash-upgrade 지원을 제거 (MDEV-13564)
6) innodb_encrypt_log에 대한 key rotation 추가 (MDEV-12041)
7) innodb_checksum_algorithm=full_crc32 개선 (MDEV-12026)

 

3. 옵티마이져 달라진 점

1) Optimizer 트레이스 구현, 시스템 변수 Optimizer_trace를 활성화하여 Optimizer 트레이스를 활성화할 수 있음 (MDEV-6111)
2) 엔진 독립 테이블 통계는 이제 기본적으로 활성화되며, 새로운 default값은 use_stat_tables=PREFERABLY_FOR_QUERIES and optimizer_use_condition_selectivity=4 이다. (MDEV-15253)

 

통계는 mysql.table_stats, mysql.column_stats, mysql.index_stats의 세 가지 테이블에 저장된다.
위 테이블의 데이터 사용 또는 업데이트는 use_stat_tables 변수에 의해 제어된다. 가능한 값은 다음과 같다.

naver 최적기는 통계 테이블의 데이터를 사용하지 않는다. 마리아DB 10.4.0 이하에 대한 기본값.
complementary 스토리지 엔진에서 동일한 종류의 데이터를 제공하지 않는 경우 최적화 도구에서 통계 테이블의 데이터를 사용한다
preferably 통계 테이블의 데이터를 선호하며, 해당 테이블에서 사용할 수 없는 경우 스토리지 엔진의 데이터를 사용한다
complementary_for_queries complementary 와 동일하지만 (분석 표에 대해 불필요하게 수집하지 않도록) 쿼리 전용. 마리아DB 10.4.1에서
preferably_for_queries preferably와 동일하지만 (분석 표에 대해 불필요하게 수집하지 않도록) 쿼리 전용. 사용 가능 및 기본값은 MariaDB 10.4.1에서

https://mariadb.com/kb/en/engine-independent-table-statistics/

 

히스토그램은 현재 기본적으로 수집된다 (MDEV-18608)
analyze_sample_percentage 변수가 추가됨. 기본값은 100(Analyze가 전체 테이블을 사용함)이지만, 통계수집에 테이블 데이터의 샘플만 사용하도록 분석을 설정할 수도 있다.

 

3) 조건 푸시다운 최적화의 적용 범위가 확대됨
- materialized in 서브쿼리에 조건을 적용할 수 있음 (MDEV-12387)
- HAVING 절의 조건은 WHERE로 푸시될 수 있다. 이 동작은 최적기 스위치 플래그를 통해 제어된다.
condition_pushdown_from_having.

4) 옵티마이져 스위치 플래그 optimize_join_buffer_size가 이제 기본적으로 ON으로 설정됨(default) (MDEV-17903)
5) Rowid 필터링 최적화 추가 (MDEV-16188). 옵티마이저 스위치 플래그 rowid_filter를 통해 제어된다.

 

- Instant add column 이란?
기존 INPLACE 등의 방식에서 대용량 테이블에 add column default value 수행은
full scan 등을 유발하여 처리가 오래걸릴 뿐만 아니라 Master <-> slave 간 replication LAG 이 발생하기 때문에 데이터 동기화에도 문제가 생김
이를 해결하고자 나온 것이 INSTANT algorithm 으로 mysql 8.0.12 / MariaDB 10.3.7 버전에서 default 로 사용됨
원리는 ORACLE에서 LOB 데이터를 테이블 segment 처럼 따로 저장하는 것과 같이
instant add column으로 생성된 컬럼을 테이블과 따로 저장하고 meta data 만 연결시켜주는 방식
https://sarc.io/index.php/mariadb/1459-mariadb-instant-add-column

 

2. DB 버전 업그레이드

 

1) MariaDB 가이드안 대로 10.2 to 10.3 로 올리고 10.3 to 10.4로 순차적으로 업그레이드한다.
https://mariadb.com/kb/en/upgrading/

 

2) Xtrabackup 으로 기존 DB 백업

/usr/bin/innobackupex \
--host=127.0.0.1 \
--user=root \
--password='비번' \
--ibbackup=xtrabackup \
--no-lock \
--stream=tar ./ | pigz -p 6 > DEV_20201123.tar.gz

--> pigz는 기존 tar 압축을 parallel로 지원한다. -p 옵션은 cpu core를 얼마나 쓸것인가 입력하는 값으로
예를들어 하이퍼스레딩 포함해서 24 core라면 상용 서버라면 4 정도 , 개발 서버는 6 정도가 적당한 듯하다. 그이상 할당해도 top 으로 확인해보면 600% 이상은 잘 안쓴다

 

# 압축해제
# tar -xizf DEV_20201123.tar.gz


3) MariaDB 10.2 binary 폴더백업 후 10.3.27 설치

downloads.mariadb.com/MariaDB/mariadb-10.3.27/bintar-linux-x86_64/

 

[root@localhost backup]# service mysqld stop
Shutting down MariaDB...                                   [  OK  ]

mv mariadb_data mariadb_data_bak
mkdir mariadb_data
chown -Rf mysql:mysql mariadb_data

mv mariadb-10.3.27-linux-x86_64 /svc/mariadb_engine/mariadb-10.3.27

[root@localhost svc]# rm mariadb
rm: remove 심볼릭 링크 `mariadb'? y'

ln -s /svc/mariadb_engine/mariadb-10.3.27 mariadb

chown -Rf mysql:mysql mariadb
 
rm -rf mariadb_logs
mkdir mariadb_logs
mkdir {binary,error,relay,slow}

mariadb-10.3.27버전 설치 방법[su]
[root@localhost scripts]# ./mysql_install_db --defaults-file=/etc/my.cnf --basedir=/svc/mariadb --datadir=/svc/mariadb_data --user=mysql
Installing MariaDB/MySQL system tables in '/svc/mariadb_data' ...
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system


PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !
To do so, start the server, then issue the following commands:

'/svc/mariadb/bin/mysqladmin' -u root password 'new-password'
'/svc/mariadb/bin/mysqladmin' -u root -h 127.0.0.1
127.0.0.1 password 'new-password'

Alternatively you can run:
'/svc/mariadb/bin/mysql_secure_installation'

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the MariaDB Knowledgebase at http://mariadb.com/kb or the
MySQL manual for more instructions.

You can start the MariaDB daemon with:
cd '/svc/mariadb' ; /svc/mariadb/bin/mysqld_safe --datadir='/svc/mariadb_data'

You can test the MariaDB daemon with mysql-test-run.pl
cd '/svc/mariadb/mysql-test' ; perl mysql-test-run.pl

Please report any problems at http://mariadb.org/jira

The latest information about MariaDB is available at http://mariadb.org/.
You can find additional information about the MySQL part at:
http://dev.mysql.com
Consider joining MariaDB's strong and vibrant community:'
https://mariadb.org/get-involved/

[root@localhost scripts]# 

[root@localhost support-files]# ls
binary-configure  magic  mysql-log-rotate  mysql.server  mysqld_multi.server  policy  wsrep.cnf  wsrep_notify
[root@localhost support-files]# cp -dpr mysql.server ../bin/

[root@localhost svc]# service mysqld start
Starting MariaDB.201112 17:49:51 mysqld_safe Logging to '/svc/mariadb_logs/error/mysql.err'.
201112 17:49:51 mysqld_safe Starting mysqld daemon with databases from /svc/mariadb_data
.                                                          [  OK  ]

[root@localhost bin]# ./mysql_secure_installation --basedir=/svc/mariadb --socket=/tmp/mysql.sock
print: /svc/mariadb/bin/my_print_defaults

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] y
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
[root@localhost bin]# 

[root@localhost bin]# service mysqld stop
Shutting down MariaDB..                                    [  OK  ]
[root@localhost bin]# service mysqld start
Starting MariaDB.201112 17:52:18 mysqld_safe Logging to '/svc/mariadb_logs/error/mysql.err'.
201112 17:52:18 mysqld_safe Starting mysqld daemon with databases from /svc/mariadb_data
.                                                          [  OK  ]
[root@localhost bin]# 
// 재시작 문제 없다.

cp my_print_defaults mysql mysql_config mysqladmin mysqlbinlog mysqlcheck mysqldump mysqlimport mysqlshow mysqlslap /usr/bin

cd /usr/bin
[root@mvno-db bin]# chown -Rf root.root my_print_defaults mysql mysql_config mysqladmin mysqlbinlog mysqlcheck mysqldump mysqlimport mysqlshow mysqlslap

[root@localhost svc]# service mysqld stop

[root@localhost svc]# mv mariadb_data mariadb_data_tmp
[root@localhost svc]# mv mariadb_data_bak mariadb_data
//현재 설치된 10.3.x버전 mariadb_data를 tmp로 mv 시키고 이전 10.2 버전의 실제 데이터 폴더를 mariadb_data로 변경한다.

[root@localhost svc]# service mysqld start
Starting MariaDB.201112 17:55:39 mysqld_safe Logging to '/svc/mariadb_logs/error/mysql.err'.
201112 17:55:39 mysqld_safe Starting mysqld daemon with databases from /svc/mariadb_data
.                                                          [  OK  ]

[root@localhost svc]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.3.27-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> exit
Bye
// 10.3.27로 바뀐거 확인

 

4) MariaDB 10.3.27 데이터 업그레이드

[root@localhost bin]# ./mysql_upgrade -uroot -p
Enter password: 

Phase 1/7: Checking and upgrading mysql database
Processing databases
mysql
mysql.column_stats                                 OK
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.gtid_slave_pos                               OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.host                                         OK
....
information_schema
performance_schema
Phase 7/7: Running 'FLUSH PRIVILEGES'
OK

// root로 쉘접속해서 정상적으로 뜨는지 다시 확인
[root@localhost bin]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 27
Server version: 10.3.27-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show processlist;
+----+-------------+----------------------+-------+---------+------+--------------------------+------------------+----------+
| Id | User        | Host                 | db    | Command | Time | State                    | Info             | Progress |
+----+-------------+----------------------+-------+---------+------+--------------------------+------------------+----------+
|  1 | system user |                      | NULL  | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  2 | system user |                      | NULL  | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  3 | system user |                      | NULL  | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  4 | system user |                      | NULL  | Daemon  | NULL | InnoDB purge coordinator | NULL             |    0.000 |
|  5 | system user |                      | NULL  | Daemon  | NULL | InnoDB shutdown handler  | NULL             |    0.000 |
| 24 | xxxxxx      | 192.168.10.100:56510 | MDLDB | Sleep   |   12 |                          | NULL             |    0.000 |
| 25 | xxxxxx      | 192.168.10.100:56511 | MDLDB | Sleep   |   12 |                          | NULL             |    0.000 |
| 26 | xxxxxx      | 192.168.10.100:56512 | MDLDB | Sleep   |   12 |                          | NULL             |    0.000 |
| 27 | root        | localhost            | NULL  | Query   |    0 | Init                     | show processlist |    0.000 |
+----+-------------+----------------------+-------+---------+------+--------------------------+------------------+----------+
9 rows in set (0.000 sec)

 

5) MariaDB 10.3 binary 폴더백업 후 10.4.17 설치

<--백업도 xtrabackup에서 Mariabackup으로 변경된다.

service mysqld stop

mv mariadb_data mariadb_data_bak
mkdir mariadb_data
chown -Rf mysql:mysql mariadb_data

mv mariadb-10.4.17-linux-x86_64 /svc/mariadb_engine/mariadb-10.4.17

[root@localhost svc]# rm mariadb
rm: remove 심볼릭 링크 `mariadb'? y'

ln -s /svc/mariadb_engine/mariadb-10.4.17 mariadb

chown -Rf mysql:mysql mariadb

mariadb-10.4.17버전 설치 방법[su]
[root@localhost scripts]# ./mysql_install_db --defaults-file=/etc/my.cnf --basedir=/svc/mariadb --datadir=/svc/mariadb_data --user=mysql
Installing MariaDB/MySQL system tables in '/svc/mariadb_data' ...
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system


Two all-privilege accounts were created.
One is root@localhost, it has no password, but you need to
be system 'root' user to connect. Use, for example, sudo mysql
The second is mysql@localhost, it has no password either, but
you need to be the system 'mysql' user to connect.
After connecting you can set the password, if you would need to be
able to connect as any of these users with a password and without sudo

See the MariaDB Knowledgebase at http://mariadb.com/kb or the
MySQL manual for more instructions.

You can start the MariaDB daemon with:
cd '/svc/mariadb' ; /svc/mariadb/bin/mysqld_safe --datadir='/svc/mariadb_data'

You can test the MariaDB daemon with mysql-test-run.pl
cd '/svc/mariadb/mysql-test' ; perl mysql-test-run.pl

Please report any problems at http://mariadb.org/jira

The latest information about MariaDB is available at http://mariadb.org/.
You can find additional information about the MySQL part at:
http://dev.mysql.com
Consider joining MariaDB's strong and vibrant community:'
https://mariadb.org/get-involved/

[root@localhost support-files]# cp -dpr mysql.server ../bin/

[root@localhost svc]# service mysqld start
Starting MariaDB.201113 13:50:40 mysqld_safe Logging to '/svc/mariadb_logs/error/mysql.err'.
201113 13:50:40 mysqld_safe Starting mysqld daemon with databases from /svc/mariadb_data
                                                           [  OK  ]

[root@localhost bin]# ./mysql_secure_installation --basedir=/svc/mariadb --socket=/tmp/mysql.sock
print: /svc/mariadb/bin/my_print_defaults

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] n
 ... skipping.

You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] y
New password: 
Re-enter new password: 
Sorry, passwords do not match.

New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
[root@localhost bin]# 


[root@localhost bin]# service mysqld stop
Shutting down MariaDB..                                    [  OK  ]

cp my_print_defaults mysql mysql_config mysqladmin mysqlbinlog mysqlcheck mysqldump mysqlimport mysqlshow mysqlslap /usr/bin

cd /usr/bin
[root@mvno-db bin]# chown -Rf root.root my_print_defaults mysql mysql_config mysqladmin mysqlbinlog mysqlcheck mysqldump mysqlimport mysqlshow mysqlslap
[root@localhost svc]# mv mariadb_data mariadb_data_tmp
[root@localhost svc]# mv mariadb_data_bak mariadb_data

[root@localhost svc]# service mysqld start
Starting MariaDB.201113 13:57:38 mysqld_safe Logging to '/svc/mariadb_logs/error/mysql.err'.
201113 13:57:38 mysqld_safe Starting mysqld daemon with databases from /svc/mariadb_data
                                                           [  OK  ]

[root@localhost svc]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.4.17-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
| Id | User        | Host      | db   | Command | Time | State                    | Info             | Progress |
+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
|  1 | system user |           | NULL | Daemon  | NULL | InnoDB purge coordinator | NULL             |    0.000 |
|  2 | system user |           | NULL | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  3 | system user |           | NULL | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  4 | system user |           | NULL | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  5 | system user |           | NULL | Daemon  | NULL | InnoDB shutdown handler  | NULL             |    0.000 |
|  9 | root        | localhost | NULL | Query   |    0 | Init                     | show processlist |    0.000 |
+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
6 rows in set (0.000 sec)

MariaDB [(none)]> exit
Bye
// 10.4.17로 바뀐거 확인

 

6) MariaDB 10.4.17  데이터 업그레이드

[root@localhost bin]# ./mysql_upgrade -uroot -p
Enter password: 
Phase 1/7: Checking and upgrading mysql database
Processing databases
mysql
mysql.column_stats                                 OK
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.gtid_slave_pos                               OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.host                                         OK
mysql.index_stats                                  OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.plugin                                       OK
....
information_schema
performance_schema
Phase 7/7: Running 'FLUSH PRIVILEGES'
OK

// root로 쉘접속해서 정상적으로 뜨는지 다시 확인
[root@localhost svc]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.4.17-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 MariaDB [(none)]> show processlist;
+----+-------------+-----------------+------+---------+------+--------------------------+------------------+----------+
| Id | User        | Host            | db   | Command | Time | State                    | Info             | Progress |
+----+-------------+-----------------+------+---------+------+--------------------------+------------------+----------+
|  1 | system user |                 | NULL | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  2 | system user |                 | NULL | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  3 | system user |                 | NULL | Daemon  | NULL | InnoDB purge worker      | NULL             |    0.000 |
|  4 | system user |                 | NULL | Daemon  | NULL | InnoDB purge coordinator | NULL             |    0.000 |
|  5 | system user |                 | NULL | Daemon  | NULL | InnoDB shutdown handler  | NULL             |    0.000 |
| 17 | root        | 127.0.0.1:38998 | NULL | Sleep   |   70 |                          | NULL             |    0.000 |
| 19 | root        | localhost       | NULL | Query   |    0 | Init                     | show processlist |    0.000 |
+----+-------------+-----------------+------+---------+------+--------------------------+------------------+----------+
7 rows in set (0.000 sec)

문제 없다 10.4 업그레이드 끝~

 

6) MariaDB 10.4 to 10.5 업그레이드?
하지 않는다. 오픈소스 특성상 최신버전은 예기치 못한 버그가 있을 수 있다.

가장 최신에 한단계 낮은 Stable 버전으로 설치한다.

 

#파티션 테이블 이관 참조
https://purumae.tistory.com/210

 

 

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 / 직업은 MYSQL과 함께 일하는 DBA / 즐거운 엔지니어의 끝나지 않는 이야기

,
반응형

파티션 관련 문의가 있어 정리해 놓는다.

 

아래와 같은 테이블 파티셔닝을 구성한다면 (RANGE는 보통 날짜를 많이 사용한다)

CREATE TABLE `TB_TEST` (
`SEQ` int(11) NOT NULL AUTO_INCREMENT,
`xxx_DATE` datetime NOT NULL,
`xxx_NO` bigint(15) unsigned NOT NULL,
`xxx_ID` varchar(20) NOT NULL,
`xxx__CD` varchar(2) DEFAULT NULL,
`xx_DATE` datetime DEFAULT NULL,
PRIMARY KEY (`SEQ`,`xxx_DATE`),
KEY `IDX_TEST_01` (`xxx_DATE`,`xxx_CD`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8
PARTITION BY RANGE (to_days(`xxx_DATE`))
(PARTITION `p201909` VALUES LESS THAN (737698) ENGINE = InnoDB,
PARTITION `p201910` VALUES LESS THAN (737729) ENGINE = InnoDB,
PARTITION `p201911` VALUES LESS THAN (737759) ENGINE = InnoDB,
PARTITION `p201912` VALUES LESS THAN (737790) ENGINE = InnoDB,
PARTITION `pExt` VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
;

위처럼 파티셔닝을 사용할 컬럼은 반드시 PK로 구성되어 있어야 한다.

그럼 테이블 자체에 PK가 없으면 파티션 구성이 안되나?

-> 아니다 파티셔닝을 할 수는 있다. MariaDB든 Mysql이든 pk가 없으면 옵티마이져가 후보군 컬럼중에 하나를 pk처럼 사용하기 때문이다. 하지만 제대로 성능이 나오지 않는다.

 

1) 파티션 추가

p201912 이후 신규로 파티션을 추가한다면 pExt를 삭제하고 p202001을 추가한 후 다시 pExt를 생성해야한다.

이것을 한번에 할수 있는 명령어는 REORGANIZE !

/* 파티션 추가 */
ALTER TABLE TB_TEST REORGANIZE PARTITION pExt INTO (
PARTITION p202001 VALUES LESS THAN (TO_DAYS('2020-02-01')),
PARTITION pExt VALUES LESS THAN MAXVALUE
);

파티션 추가는 기존파티션 사이에 넣을 수는 없고 가장 이후 파티션 뒤로 생성이 가능하다.

이런 점 때문에 혹시 파티션을 생성했는데.. range 범위를 잘못 생성했을 경우 삭제하고 재구성해야할 수도 있다.

 

2) 파티션 삭제

/* 파티션 삭제 */
ALTER TABLE TB_TEST DROP PARTITION pExt;

맨아래서부터 순서대로 삭제하고 잘못구성한 파티션까지 삭제후 재구성한다.

 

만약 p202001을 TO_DAY('2020-03-01')로 잘못구성했다고 가정하면 pExt, p202001 순으로 순차적으로 삭제하면된다.

이럴 경우 파티션 여러 개 한번에 삭제하려면?

<-- 서버에 한번에 삭제하도록 구성하고 싶다는 문의가 있었고 아래와 같이 명령어를 사용하면 적용가능했다.

ALTER TABLE TB_TEST DROP PARTITION pExt, p202001;

 

3) 파티션 생성

ALTER TABLE TB_TEST add PARTITION (
PARTITION p202001 VALUES LESS THAN (TO_DAYS('2020-02-01')),
PARTITION pExt VALUES LESS THAN MAXVALUE
);

MAXVAULE 는 사용하는 것이 좋다. 어떤 이유에서든 테이블에 데이터가 스키마구성에 의해 에러가 나서 쌓이지 않는 경우는 예방해야하기 때문이다.

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 / 직업은 MYSQL과 함께 일하는 DBA / 즐거운 엔지니어의 끝나지 않는 이야기

,
반응형

xtrabackup 을 사용하면 보통 innobackupex 명령어를 쓰게된다.
근데 최근 MariaDB 를 버전업하면서 백업한 것을 재생성하려는데

ib_logfile0 이 0이라고 복원시 리두로그가 깨지고 DB가 start되지 않는 이슈가 발생했다.

 

확인해보니 MariaDB 10.3부터는 xtrabackup이 아니라 mariabackup이라는 것을 사용해야 한다고 한다.

이것에 대해 알아본다.

 

1. xtrabackup에서 mariabackup으로 변경해야하는 이유

 

xtrabackup 에서 mariadb에서 변경된 redo log를 인식하지 못하기 때문에 mariadbackup을 사용해야 한다.

#참조:  mariadb.com/kb/en/percona-xtrabackup-overview/

 

In MariaDB 10.3, Percona XtraBackup is not supported. See Percona XtraBackup Overview: Compatibility with MariaDB for more information.
In MariaDB 10.2 and MariaDB 10.1, Percona XtraBackup is only partially supported. See Percona XtraBackup Overview: Compatibility with MariaDB for more information.

 

2. Percona XtraBackup과의 차이점

 

• Percona XtraBackup은 InnoDB 리두 로그 파일을 xtrabackup_logfile 파일로 복사하는 반면,

Mariabackup은 ib_logfile0 파일을 사용합니다.

• Percona XtraBackup의 libgcrypt 기반 백업 암호화는 Mariabackup에서 지원되지 않습니다.

• innobackupex 과 같이 innobackupex 에서 mariabackup 로의 심볼릭 링크는 없습니다.

대신 mariabackup 에는 innobackupex 호환 옵션을 활성화하는 --innobackupex 명령 줄 옵션이 있습니다.

• --compact 및 --rebuild_indexes 옵션은 지원되지 않습니다.

• MariaDB 10.1.24의 Mariabackup에서 --stream=tar 에 대한 지원이 제거되었습니다.

• xbstream 유틸리티 이름이 mbstream 으로 변경되었습니다. 그러나 백업을 생성 할 때이 출력 형식을 선택하기 위해 Mariabackup의 --stream 옵션은 여전히 xbstream 값을 예상합니다.
• Mariabackup은 잠금없는 binlog를 지원하지 않습니다.

 

 

3. 이제 xtrabackup은 사용못하나?

 

--innobackupex 옵션을 추가하면 당분간은 사용가능하다.

하지만 10.4부터는 이마저도 지원하지 않는다고 하니 Mariabackup으로 변경하는 게 낫겠다.

 

 

4. Mariabackup 스크립트 변경 및 테스트 (DB 버전 : Mariadb 10.4.15)

 

4-1) Mariabackup

[root@localhost backup]# mariabackup \
 --backup \
 --no-lock \
 --host=127.0.0.1 \
 --port=3306 \
 --user=root \
 --password='비번' \
 --target-dir=/backup/innobackup/20201028_17
 
 //스크립트 종료후 파일확인
 [root@localhost 20201028_17]# ls -lh
drwx------. 2 root root 4.0K 2020-10-28 16:49 TESTDB
-rw-r-----. 1 root root  72K 2020-10-28 16:49 aria_log.00000001
-rw-r-----. 1 root root   52 2020-10-28 16:49 aria_log_control
-rw-r-----. 1 root root  366 2020-10-28 16:49 backup-my.cnf
-rw-r-----. 1 root root  25K 2020-10-28 16:49 ib_buffer_pool
-rw-r-----. 1 root root 215M 2020-10-28 16:49 ib_logfile0 <--- 트렌젝션 데이터 쌓임
-rw-r-----. 1 root root 500M 2020-10-28 16:41 ibdata1
-rw-r-----. 1 root root 500M 2020-10-28 16:41 ibdata2
-rw-r-----. 1 root root 500M 2020-10-28 16:41 ibdata3
-rw-r-----. 1 root root 100M 2020-10-28 16:41 ibdata4
drwx------. 2 root root 4.0K 2020-10-28 16:49 mysql
drwx------. 2 root root 4.0K 2020-10-28 16:49 performance_schema
-rw-r-----. 1 root root   85 2020-10-28 16:49 xtrabackup_checkpoints
-rw-r-----. 1 root root  535 2020-10-28 16:49 xtrabackup_info

 

4-2) redo 로그파일 합치기(=xtrabackup에서는 apply log 적용)

mariabackup \
    --prepare \
	--user=root \
	--password='비번' \
	--target-dir=/backup/innobackup/20201028_17
    
//prepare 로그 확인
mariabackup based on MariaDB server 10.4.15-MariaDB Linux (x86_64)
[00] 2020-10-28 17:00:04 cd to /backup/innobackup/20201028_17/
[00] 2020-10-28 17:00:04 This target seems to be not prepared yet.
[00] 2020-10-28 17:00:04 mariabackup: using the following InnoDB configuration for recovery:
[00] 2020-10-28 17:00:04 innodb_data_home_dir = .
[00] 2020-10-28 17:00:04 innodb_data_file_path = ibdata1:500M;ibdata2:500M;ibdata3:500M;ibdata4:100M:autoextend
[00] 2020-10-28 17:00:04 innodb_log_group_home_dir = .
[00] 2020-10-28 17:00:04 InnoDB: Using Linux native AIO
[00] 2020-10-28 17:00:04 Starting InnoDB instance for recovery.
[00] 2020-10-28 17:00:04 mariabackup: Using 104857600 bytes for buffer pool (set by --use-memory parameter)
2020-10-28 17:00:04 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2020-10-28 17:00:04 0 [Note] InnoDB: Uses event mutexes
2020-10-28 17:00:04 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2020-10-28 17:00:04 0 [Note] InnoDB: Number of pools: 1
2020-10-28 17:00:04 0 [Note] InnoDB: Using SSE2 crc32 instructions
2020-10-28 17:00:04 0 [Note] InnoDB: Initializing buffer pool, total size = 100M, instances = 1, chunk size = 100M
2020-10-28 17:00:04 0 [Note] InnoDB: Completed initialization of buffer pool
2020-10-28 17:00:04 0 [Note] InnoDB: page_cleaner coordinator priority: -20
2020-10-28 17:00:04 0 [Note] InnoDB: Starting crash recovery from checkpoint LSN=14172663378
2020-10-28 17:00:12 0 [Note] InnoDB: Starting a batch to recover 1918 pages from redo log. <-- ib_logfile0에서 트랜젝션 파일 읽어서 합치기 작업중
2020-10-28 17:00:14 0 [Note] InnoDB: Starting a batch to recover 2135 pages from redo log.
2020-10-28 17:00:15 0 [Note] InnoDB: Starting a batch to recover 2551 pages from redo log.
2020-10-28 17:00:19 0 [Note] InnoDB: Read redo log up to LSN=14282567680
2020-10-28 17:00:20 0 [Note] InnoDB: Starting a batch to recover 2577 pages from redo log.
2020-10-28 17:00:24 0 [Note] InnoDB: Starting a batch to recover 3005 pages from redo log.
2020-10-28 17:00:28 0 [Note] InnoDB: Starting a batch to recover 3070 pages from redo log.
2020-10-28 17:00:33 0 [Note] InnoDB: Starting final batch to recover 1742 pages from redo log.
[00] 2020-10-28 17:00:33 Last binlog file , position 0
[00] 2020-10-28 17:00:34 completed OK!

//작업후 ib_logfile0 상태 확인
[root@localhost 20201028_17]# ls -lh
drwx------. 2 root root 4.0K 2020-10-28 16:49 TESTDB
-rw-r-----. 1 root root  72K 2020-10-28 16:49 aria_log.00000001
-rw-r-----. 1 root root   52 2020-10-28 16:49 aria_log_control
-rw-r-----. 1 root root  366 2020-10-28 16:49 backup-my.cnf
-rw-r-----. 1 root root  25K 2020-10-28 16:49 ib_buffer_pool
-rw-r-----. 1 root root    0 2020-10-28 17:00 ib_logfile0 <--- 트렌젝션 데이터 merge 끝
-rw-r-----. 1 root root 500M 2020-10-28 17:00 ibdata1
-rw-r-----. 1 root root 500M 2020-10-28 16:41 ibdata2
-rw-r-----. 1 root root 500M 2020-10-28 16:41 ibdata3
-rw-r-----. 1 root root 100M 2020-10-28 16:41 ibdata4
drwx------. 2 root root 4.0K 2020-10-28 16:49 mysql
drwx------. 2 root root 4.0K 2020-10-28 16:49 performance_schema
-rw-r-----. 1 root root   83 2020-10-28 17:00 xtrabackup_checkpoints
-rw-r-----. 1 root root  535 2020-10-28 16:49 xtrabackup_info

백업은 정상적으로 끝난 것을 확인했다. 이제 재생성 테스트를 해본다.

 

 

4-3) restore

#재생성
[mysql@localhost ~]$ service mysqld stop
Shutting down MariaDB..                                    [  OK  ]


[root@localhost dbtest]# mv mariadb_data mariadb_data_bak

[root@localhost dbtest]# mkdir mariadb_data
	
//copy-back or move-back 둘중 아무거나 하면 된다.

mariabackup \
	--move-back \
	--target-dir=/backup/innobackup/20201028_17 \
	--user=root \
	--password='비번' \
	--datadir=/dbtest/mariadb_data
    
// restore 로그
mariabackup based on MariaDB server 10.4.15-MariaDB Linux (x86_64)
[01] 2020-10-28 17:56:29 Moving ibdata1 to /dbtest/mariadb_data/ibdata1
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ibdata2 to /dbtest/mariadb_data/ibdata2
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ibdata3 to /dbtest/mariadb_data/ibdata3
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ibdata4 to /dbtest/mariadb_data/ibdata4
....
[01] 2020-10-28 17:56:29 Moving ./mysql/proc.MAD to /dbtest/mariadb_data/mysql/proc.MAD
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ./mysql/proxies_priv.MAI to /dbtest/mariadb_data/mysql/proxies_priv.MAI
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ./mysql/general_log.CSV to /dbtest/mariadb_data/mysql/general_log.CSV
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ./mysql/func.frm to /dbtest/mariadb_data/mysql/func.frm
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ./mysql/proc.MAI to /dbtest/mariadb_data/mysql/proc.MAI
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ./aria_log_control to /dbtest/mariadb_data/aria_log_control
[01] 2020-10-28 17:56:29         ...done
[01] 2020-10-28 17:56:29 Moving ./xtrabackup_info to /dbtest/mariadb_data/xtrabackup_info
[01] 2020-10-28 17:56:29         ...done
[00] 2020-10-28 17:56:29 completed OK!

// 파일확인 -> ib_logfile0 은 사라졌다.
[root@localhost mariadb_data]# ls -lh
drwx------. 2 root root 4.0K 2020-10-28 17:56 TESTDB
-rw-r-----. 1 root root  72K 2020-10-28 17:47 aria_log.00000001
-rw-r-----. 1 root root   52 2020-10-28 17:47 aria_log_control
-rw-r-----. 1 root root 1.1M 2020-10-28 17:47 ib_buffer_pool
-rw-r-----. 1 root root 500M 2020-10-28 17:51 ibdata1
-rw-r-----. 1 root root 500M 2020-10-28 17:39 ibdata2
-rw-r-----. 1 root root 500M 2020-10-28 17:39 ibdata3
-rw-r-----. 1 root root 100M 2020-10-28 17:39 ibdata4
drwx------. 2 root root 4.0K 2020-10-28 17:56 mysql
drwx------. 2 root root 4.0K 2020-10-28 17:56 performance_schema
-rw-r-----. 1 root root  535 2020-10-28 17:47 xtrabackup_info

[root@localhost mariadb_data]# chown -Rf mysql:mysql /dbtest/mariadb_data

[mysql@localhost ~]$ service mysqld start


재생성 제대로 되는 것을 확인했다.... mariabackup으로 쉘스크립트 수정하고 반영준비한다.

끝~

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 / 직업은 MYSQL과 함께 일하는 DBA / 즐거운 엔지니어의 끝나지 않는 이야기

,
반응형

1. 설치중 문제점 발견

MariaDB 최근버전으로 성능테스트를 하려고 virtualbox에서 10.4.13 버전을 받아 DB를 설치하고 start까지는 성공하였다.

[mysql@localhost bin]$ service mysqld start
Starting MariaDB.201021 16:14:13 mysqld_safe Logging to '/svc/mariadb_logs/error/mysql.err'.
201021 16:14:13 mysqld_safe Starting mysqld daemon with databases from /svc/mariadb_data
                                                           [  OK  ]

별로 달라진 건 없네..라고 생각하고 stop을 해보았는데 .. 어떤 로그도 없이 그냥 안된다. ???

 

[mysql@localhost bin]$ service mysqld stop 

//멍때리고 아무것도 안됨;; mysql.error 로그도 없음

 

ps -ef로 프로세스를 확인해보니 아래와 같다.

mysql    30913     1  0 11:12 pts/0    00:00:00 /bin/sh /svc/mariadb/bin/mysqld_safe --datadir=/svc/mariadb_data --pid
mysql    31151 30913  0 11:12 pts/0    00:00:00 /svc/mariadb/bin/mysqld --basedir=/svc/mariadb --datadir=/svc/mariadb_
mysql    31220  1957  0 11:12 pts/0    00:00:00 /bin/sh /sbin/service mysqld stop
mysql    31227 31220  0 11:12 pts/0    00:00:00 /bin/sh /etc/init.d/mysqld stop
root     31393 31227  0 11:12 pts/0    00:00:00 su - mysql -s /bin/sh -c kill -0 31151 // 음..su권한으로 하는데 mysql계정권한으로 실행해서 안되는 거였다.

이렇게 되면 스크립트를 까봐야하는데 수정범위가 크면 버그잡는게 더 시간이 많이 뺏길거 같아서..

가장최근 버전인 10.4.15 을 가져다 설치했지만, 동일한 현상이 발생했다.
그럼 정책적으로 shutdown은 su권한에서만 가능하도록 스크립트를 업데이트했다는건지?

보안강화? 근데 대부분 이중화하고..mysql계정으로 접속해서 처리하는데..
그냥 시간이 좀 걸리더라도 mysql 계정으로 shutdown이 가능하도록 수정하기로 했다.

 

2. 스크립트 수정

vi로 mysql.server 스크립트에서 stop 부분확인

su_kill() {
  if test "$USER" = "$user"; then
    kill $* >/dev/null 2>&1
  else
    su - $user -s /bin/sh -c "kill $*" >/dev/null 2>&1
  fi
}


  'stop')
    # Stop daemon. We use a signal here to avoid having to know the
    # root password.

    if test -s "$mysqld_pid_file_path"
    then
      mysqld_pid=`cat "$mysqld_pid_file_path"`

      if su_kill -0 $mysqld_pid ; then
        echo $echo_n "Shutting down MariaDB"
        su_kill $mysqld_pid
        # mysqld should remove the pid file when it exits, so wait for it.
        wait_for_gone $mysqld_pid "$mysqld_pid_file_path"; return_value=$?
      else
        log_failure_msg "MariaDB server process #$mysqld_pid is not running!"
        rm "$mysqld_pid_file_path"
      fi

      # Delete lock for RedHat / SuSE
      if test -f "$lock_file_path"
      then
        rm -f "$lock_file_path"
      fi
      exit $return_value
    else
      log_failure_msg "MariaDB server PID file could not be found!"
    fi
    ;;

10.3.x버전과 비교해보니 10.4.x버전에는 su_kill() 라는 함수가 추가되어있는데

if test "$USER" = "$user"; then 부분에서 $user는 mysql로 박혀있고 $USER는

basedir 에서 가져오도록 되어야 하는데 제대로 값을 못가지고 온다.

이 부분에 문제가 있어서 su_kill()이 else로 빠져서 su 권한으로만 실행되도록 해서 불편함이 있다.

수정될 때까지 su_kill()을 사용하는 부분 다 찾아서 주석처리하고 kill로 바꾼다.

 

수정파일

mysql.server
0.01MB

 

3. 테스트

[mysql@localhost bin]$ service mysqld stop
Shutting down MariaDB..                                    [  OK  ]

잘된다. 끝~

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 / 직업은 MYSQL과 함께 일하는 DBA / 즐거운 엔지니어의 끝나지 않는 이야기

,