반응형

데이터 타입을 선언할 때 int, bigint가 뭔지는 알겠는데 뒤에 () 괄호에 대해 애매하다는 얘기가 있어서
이번에 정리한다.

 

1. 결론


()는 자리수를 선언하는 것이다. (10)이면 10자리, (20)이면 20자리까지 넣겠다는 의미
하지만 int나 bigint에서 괄호 ()안에 숫자는 Zerofill 이라는 옵션을 추가로 사용할 때만
의미가 있고 그것이 아니라면 큰 의미없다.

2. 이유

 

괄호안의 숫자는 디스플레이 너비 속성 display width attribute 
즉, 자릿수를 나타내는데 zorefill 속성을 사용할 경우 자릿수 만큼 유효숫자 0을 채우는 것이다.
자릿수를 지정하지 않았을 경우에는 INT의 기본값은 11, BIGINT의 기본값은 20으로 자릿수가 자동 설정된다. 

예컨대 INT(3)으로 zerofill속성을 사용해 id컬럼을 생성하면

id값으로 1, 2, 3, … 998, 999, 1000, 1001을 저장했을 때, 

데이터베이스에는 001, 002, 003, … 998, 999, 1000, 1001로 기록이 된다. 

 

즉, 숫자형뒤의 괄호안의 숫자만큼 자릿수에 유효숫자가 채워진다. 
그리고 괄호안의 숫자를 넘는 자릿수의 수에 대해서는 상관없이 기록이되고, 숫자형이 허용하는 범위까지 값을 저장할 수 있다. 

헷갈리면 안되는 것이 괄호안의 숫자가 자릿수를 규정하는 것은 아니라는 것이다. 
즉, zerofill 속성을 사용하지 않는 경우라면 괄호안의 숫자는 의미가 없다
그리고 zerofill 속성을 사용하는 것은 양수에만 가능하므로, 자동으로 unsigned속성이 적용된다.

 

 

3. 테스트


괄호안에 별다른 선언을 하지 않으면 default가 int(11), bigint(20)이 된다고 한다.
그럼 만약 int(11)을 초과해서 int(20)을 선언한다면 이것은 문제가 될까?

#테이블 생성
CREATE TABLE TMP_LOAD_20220816 (
 x INT(20) NOT NULL,
 y INT(20) ZEROFILL NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='zerofill 테스트';

#데이터 insert
INSERT INTO TMP_LOAD_20220816 (x,y) VALUES
(1, 1),
(12, 12),
(123, 123),
(1234, 1234),
(123456789, 123456789);
commit;

#데이터 확인
SELECT x, y FROM TMP_LOAD_20220816;

 

result)


-> int(20)으로 선언한 대로라면 00000000000123456789 이렇게 출력될것이라고 생각했지만 
int의 최대허용범위는 10자리이므로 그 이상은 출력하지 않았다.

별의미가 없다.

 


#번외 테스트

#int형 최대치로 넣어보기
INSERT INTO TMP_LOAD_20220816 (x,y) VALUES
(2147483647, 4294967295);
commit;

SELECT x, y FROM TMP_LOAD_20220816;

result)

-> zerofill 일때 unsigned로 자동변환이라고 하여 실제로 값을 넣어보니

최대허용치 4294967295 까지 insert 되는것을 확인함



# unsigned 최대치에서 1만 더 올려볼까? 4294967295-> 4294967296 
INSERT INTO TMP_LOAD_20220816 (x,y) VALUES
(2147483647, 4294967296);

SQL Error [1264] [22001]: Data truncation: Out of range value for column 'y' at row 1
Data truncation: Out of range value for column 'y' at row 1
Data truncation: Out of range value for column 'y' at row 1

 

 

컬럼에 약 43억 이상의 수가 들어간다면 int보단 bigint를 선언하는 것이 좋겠다.

# 큰의미는 없지만 int(10) vs int(11) 보통 혼용하는데 둘 중 뭘 써야할까?

-> 괄호 ()에 아무런 선언을 하지 않으면 mysql default 옵션은 int(11) 이다.

 

#int는 10자리로 알고있는데 왜 default는 11자리 일까?
-> 음수까지 표현하기 위함

int 값은 -2147483648일 수 있으며 11자리이므로 기본 표시 크기는 11입니다 .
unsigned int는 음수를 허용하지 않으므로 기본적으로 표시 크기 10 만 필요합니다. 
아래 문서에서 볼 수 있듯이 SIGNED INT 및 UNSIGNED INT를 저장하는 데 필요한 비트 수는 동일하고 저장 가능한 숫자의 범위는 이동됩니다.
참조 : https://stackoverflow.com/questions/5256560/mysql-datatype-int11-whereas-unsigned-int10

 

 

 

4. mysql 8 특정버전부터는 ZEROFILL 옵션 종료

 

mysql 8.0.17부터 Zerofill 속성은 사용되지 않는다 
zerofill속성이 제외되면 LPAD()함수를 사용하여 원하는 자릿수만큼 0으로 채우거나, 형식이 지정된 숫자를 CHAR형 컬럼에 저장하면 된다.
혼란만 가중시키는 옵션이라 걍 제거하고 LPAD() 함수 쓰도록 유도하는 것으로 보인다.

참조:
https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
https://dogleg.co.kr/?p=163

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 직업은 MYSQL과 함께 일하는 DBA의 소소한 일상 이야기

,
반응형

온라인으로 ARCH 로그 삭제하기

 

0. 오라클 설치환경 확인
OS환경 : Oracle Linux6.8(64bit)
DB 환경 : Oracle Database 11.2.0.4

SQL> archive log list  
Database log mode        No Archive Mode
Automatic archival        Disabled
Archive destination        USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     1020
Current log sequence        1022

 

 

 

1. 아카이브 로그 경로 및 파일 확장자 확인

SQL> show parameter log_archvie_dest_1
NAME                     TYPE   VALUE
----------------------   ------   -------------------------------
log_archvie_dest_1     string  location=/archive/orcl


SQL> show parameter log_archvie_format
NAME                     TYPE   VALUE
----------------------   ------   -------------------------------
log_archvie_format     string  arch_%s_%t_%r.arc

2. 해당경로로 이동

cd /archive/orcl

 

3. 20일 지난 파일 삭제

find . -name "*.arc" -mtime +20 -exec rm {} \;

 

4. 자동삭제 ( crontab 등록 )

crontab -e 로 들어가서 아래 추가

00 20 * * * /usr/bin/find /archive/orcl -name "*.arc" -mtime +20 -exec /bin/rm {} \;

 


  

반응형

'RDB > oracle' 카테고리의 다른 글

오라클 DB 디스크 용량 비우기 1  (0) 2021.12.13
블로그 이미지

dung beetle

취미는 데이터 수집 직업은 MYSQL과 함께 일하는 DBA의 소소한 일상 이야기

,
반응형

오라클 DB에 사용량관련 alert이 떠서 확인해보니 디스크 파티션이 90%이상 찼다. 
확인해서 Online 으로 지울 수 있는 것을 지워보자.

 

1. 로그파일 2개 삭제 (리스너 로그, 트레이스 로그)

 

1) 리스너로 로그파일 위치확인

[oracle@admin-test ~]$ lsnrctl status LISTENER

LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 21-JUL-2021 16:49:25

Copyright (c) 1991, 2009, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 11.2.0.1.0 - Production
Start Date                27-NOV-2018 06:30:07
Uptime                    470 days 7 hr. 51 min. 25 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /oracle/app/oracle/product/11.2.0/network/admin/listener.ora
Listener Log File         /oracle/app/oracle/diag/tnslsnr/admin-test/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
Services Summary...
Service "orcl" has 1 instance(s).
  Instance "orcl", status READY, has 1 handler(s) for this service...
Service "orclXDB" has 1 instance(s).
  Instance "orcl", status READY, has 1 handler(s) for this service...
The command completed successfully

2) 로그파일 위치
Listener Log File         /oracle/app/oracle/diag/tnslsnr/admin-test/listener/alert/log.xml

 

3) 로그비우기

혹시 모를 상황에 대비해서 파일을 바로 삭제하지 않고 별도 파티션으로 파일 이동후 삭제한다.

 

3.1) 백업폴더 생성

[root@admin-test ] cd /backup
[root@admin-test ] mkdir alert
[root@admin-test backup]# chown -Rf oracle:oinstall alert

 

3.2) 리스너 로그삭제

[root@admin-test alert]# su - oracle
[oracle@admin-test ~]$ cd /oracle/app/oracle/diag/tnslsnr/admin-test/listener/alert
[oracle@admin-test ~]$ find . -name "*.xml" -mtime +30 -exec mv {} /backup/alert/ \;

// 30일이 지난 파일을 /backup/alert 폴더로 이동시킨다.
// 이동하지 않고 그냥 삭제하고 싶다면 --> find . -name "*.xml" -mtime +30 -type f -exec rm -vf {} \

 

3.3) 트레이스 로그삭제

[oracle@admin-test ~]$ cd /oracle/app/oracle/diag/tnslsnr/admin-test/listener/trace
[oracle@admin-test ~]$ cp -rp listener.log listener.log.20210722
//백업하고 삭제한다

[oracle@admin-test ~]$ cp /dev/null listener.log
//trace 로그를 비운다

su
tar -cvzf listener.log_20210722.tar.gz listener.log.20210722
chown -Rf oracle:oinstall listener.log_20210722.tar.gz
rm listener.log.20210722
//백업한 파일은 압축후 삭제한다.

 

4) 테이블스페이스 데이터 정상여부 확인

SQL> select tablespace_name,status from dba_tablespaces;

TABLESPACE_NAME 	       STATUS
------------------------------ ---------
SYSTEM			       ONLINE
SYSAUX			       ONLINE
UNDOTBS1               ONLINE
TEMP			       ONLINE
USERS			       ONLINE
EXAMPLE 		       ONLINE
TS_xxx		       	   ONLINE
TS_xxxx		       	   ONLINE
TS_xxxxx		       ONLINE
TS_xxxxxx		       ONLINE
TS_xxxxxxx		       ONLINE

TABLESPACE_NAME 	       STATUS
------------------------------ ---------
TS_xxxxxxx		       ONLINE

12 rows selected.

 

5) 디스크 용량 확인

df -Th
Filesystem     Type   Size  Used Avail Use% Mounted on
...
/dev/sdb1      ext4   275G  233G   29G  80% /oracle
/dev/sdc1      ext4   550G  173G  350G  34% /backup

끝~

 

# trace 파일 삭제 후 장애발생시 대처

DB 접속은 되는데 테이블 조회가 안된다.

data tablespace 용량도 0, 을 넘어서 아에 조회가 되지 않는다;;;

#[예제]
SQL> select tablespace_name,status from dba_tablespaces;
 
TABLESPACE_NAME                STATUS
------------------------------ ---------
SYSTEM                         ONLINE
UNDOTBS1                       ONLINE
SYSAUX                         ONLINE
TEMP                           ONLINE
USERS                          ONLINE
TEMP3                          ONLINE
 
6 rows selected.

SQL> alter tablespace users offline;
 
Tablespace altered.
 
SQL> select tablespace_name,status from dba_tablespaces;
 
TABLESPACE_NAME                STATUS
------------------------------ ---------
SYSTEM                         ONLINE
UNDOTBS1                       ONLINE
SYSAUX                         ONLINE
TEMP                           ONLINE
USERS                          OFFLINE
TEMP3                          ONLINE
 
6 rows selected.
 
SQL> alter tablespace users online;
 
Tablespace altered.
 
SQL> select tablespace_name,status from dba_tablespaces;
 
TABLESPACE_NAME                STATUS
------------------------------ ---------
SYSTEM                         ONLINE
UNDOTBS1                       ONLINE
SYSAUX                         ONLINE
TEMP                           ONLINE
USERS                          ONLINE
TEMP3                          ONLINE
 
6 rows selected.
 
SQL>

중요한 것은 select tablespace_name,status from dba_tablespaces;
조회를 했을때 빨간 글씨처럼 OFFLINE이라고 써진 테이블 스페이스가 비활성화 되어있는 것이 있을 것이다.
이 tablespace가 data를 담당하는 tablespace라면 당연히 기존 데이터나 테이블을 참조하지 못하게 되는것이다.
따라서 이걸 ONLINE상태로 변경해주면 된다.
그럼 정상적으로 데이터나 테이블을 확인할 수 있다.

 

참조 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=cestlavie_01&logNo=40210123206

반응형

'RDB > oracle' 카테고리의 다른 글

오라클 DB 디스크 용량 비우기 2  (2) 2022.02.23
블로그 이미지

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의 소소한 일상 이야기

,
반응형

xtrabackup 후 restore하면서 로그를 보고있는데 *.TRG로 끝나는 파일이 있다.
생소한데;... 뭔가 한번 확인해 보았다.


TRG 파일은?

트리거 관련 파일을 말한다.
트리거 파일은 확장자가 trg가 되며 트리거 명.trg가 아니라, 트리거가 생성되어 있는 테이블명.trg가 생성된다.
해당 테이블에 트리거가 많을 경우 하나의 trg파일에 모두 저장되고, 트리거명.trn 파일이 생성된다.

 

1) restore 후 실제파일 확인

[root@test-db xxxDB]# ls -al *.TRG
-rw-r----- 1 root root 9509 2021-03-23 06:04 TB_xxx.TRG
-rw-r----- 1 root root 5450 2021-03-23 06:04 TB_xxx_TC.TRG
// trg파일은 트리거를 사용하는 테이블명.trg로 생성되어 있다.

[root@test-db xxxDB]# ls -al *.TRN
-rw-r----- 1 root root 42 2021-03-23 06:04 TB_xxx_AFTER_INSERT.TRN
-rw-r----- 1 root root 42 2021-03-23 06:04 TB_xxx_AFTER_UPDATE.TRN
-rw-r----- 1 root root 46 2021-03-23 06:04 TB_xxx__TC_AFTER_INSERT.TRN
-rw-r----- 1 root root 46 2021-03-23 06:04 TB_xxx__TC_AFTER_UPDATE.TRN
// 실제 트리거는 .trn으로 생성되어있다.

 

2) mysql 8에서 달라지는 점
data dictionary를 사용하면서 기존에 파일로 있었던 .frm / .par / .trn / .trg 등의 파일이 사라진다.
mysql 데이터베이스의 데이터들은 mysql.ibd 테이블 스페이스에 저장이 된다고 합니다.

 - mysql 8에서는 데이터사전이란 개념이 들어가면서 mysql.ibd로 통합되고 .trg는 더이상 사용하지 않는다고 한다.

 

mysql 데이터베이스의 테이블들을 show create table 명령으로 확인해 보면 아래와 같습니다.
/*!50100 TABLESPACE `mysql` */ ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0
더이상 MyISAM 엔진을 사용하지 않습니다.

 

InnoDB 엔진 이외의 엔진들에 대한 metadata 저장은 Serialized Dictionary Information (SDI) 파일에 JSON으로 저장합니다. 기본 설치후에 mysql 데이터베이스 디렉토리에 general_log와 slow_log 테이블의 .sdi 파일을 확인할 수 있습니다.

반응형
블로그 이미지

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의 소소한 일상 이야기

,
반응형

SQL 튜닝하려고 개발 DB를 multi instance로 구축해놓고 필요할 때

migration 해서 사용하는데 mirgration 에러가 나서 확인해보니 디스크용량이 부족하다고 한다..
근데 디스크 빵빵한 걸로 알고 있는데???

일단 파티션별로 디스크 용량을 확인해본다

 

# df -Th
Filesystem           Type   Size  Used Avail Use% Mounted on
/dev/sda2            ext4    20G  4.0G   15G  22% /
tmpfs                tmpfs   16G     0   16G   0% /dev/shm
/dev/sda1            ext4   477M  142M  310M  32% /boot
/dev/sda5            ext4    20G  9.7G  9.0G  52% /usr
/dev/sda7            ext4   3.9G  927M  2.8G  26% /var
/dev/sda6            ext4   3.9G  8.0M  3.7G   1% /tmp
/dev/sdb1            ext4   1.1T  938G  107G  90% /data
/dev/sda8            ext4   212G  136G   66G  68% /backup
xxx.xxx.xxx.xxx:/backup2 nfs    2.5T  1.9T  515G  79% /backup2


# du -h --max-depth=1
11M	./xxDB
1.1G	./xxDB
6.5G	./xxxTDB
22M	./mysql
31G	./zzDB
1.1M	./performance_schema
156K	./test
17G	./zzz
8.0K	./backup
617M	./vvv
676K	./sys
35G	./xxDB
829G	. 

//뭐야 이거; 현재경로에 829G 파일이 있다고??

 

어떤 파일인지 좀 더 확인해본다.

# ls -lh
합계 738G
drwxr-x--- 2 mysql mysql  12K 2020-10-13 13:43 xxDB
drwxr-x--- 2 mysql mysql  20K 2020-02-28 17:35 xxxDB
drwxr-x--- 2 mysql mysql  52K 2021-02-22 18:49 xxxx
drwxr-x--- 2 mysql mysql  20K 2021-02-16 14:08 xxx
drwxr-x--- 2 mysql mysql  12K 2021-02-16 15:05 zzDB
drwxr-x--- 2 mysql mysql 4.0K 2021-02-02 18:56 ttDB
drwxr-x--- 2 mysql mysql  40K 2021-02-23 10:07 xxxxDB
-rw-r----- 1 mysql mysql   56 2020-02-28 17:45 auto.cnf
drwxr-x--- 2 mysql mysql 4.0K 2020-02-28 17:34 backup
-rw-r----- 1 mysql mysql  36K 2021-02-10 15:22 ddl_log.log
-rw-r----- 1 mysql mysql 558K 2020-11-23 11:23 ib_buffer_pool
-rw-r----- 1 mysql mysql 256M 2021-02-23 10:10 ib_logfile0
-rw-r----- 1 mysql mysql 256M 2021-02-23 10:10 ib_logfile1
-rw-r----- 1 mysql mysql 256M 2021-02-23 10:07 ib_logfile2
-rw-r----- 1 mysql mysql 500M 2021-02-23 10:10 ibdata1
-rw-r----- 1 mysql mysql 500M 2021-02-23 10:10 ibdata2
-rw-r----- 1 mysql mysql 500M 2021-02-23 10:08 ibdata3
-rw-r----- 1 mysql mysql 5.9G 2021-02-23 10:10 ibdata4
-rw-r----- 1 mysql mysql 730G 2021-02-23 10:06 ibtmp1
-rw-r----- 1 mysql mysql 2.8K 2020-02-28 17:43 mvno-my.cnf
drwxr-x--- 2 mysql mysql 4.0K 2020-02-28 17:35 mysql
drwxr-x--- 2 mysql mysql 4.0K 2020-02-28 17:34 performance_schema
-rw-r----- 1 mysql mysql    6 2020-11-23 11:23 privacy-db.pid
drwxr-x--- 2 mysql mysql  12K 2020-02-28 17:43 sys
drwxr-x--- 2 mysql mysql 4.0K 2020-02-28 17:43 test
-rw-r----- 1 mysql mysql   22 2020-02-28 17:43 xtrabackup_binlog_pos_innodb
-rw-r----- 1 mysql mysql  578 2020-02-28 17:43 xtrabackup_info

-rw-r----- 1 mysql mysql 730G 2021-02-23 10:06 ibtmp1
//헐 이게 뭐냐?? ibtmp1에 대해 알아봐야겠다.

 

* ibtmp1 이란?

 

[MySQL Internals] Temporary Tablespace
압축되지 않고 사용자가 생성한 임시 테이블과 디스크에 생성되는 내부적인 임시 테이블들이 shared temporary tablespace 에 생성됩니다.
innodb_temp_data_file_path 옵션으로 상대 경로, 이름, 사이즈, 데이터파일의 속성을 설정할 수 있습니다.
아무것도 설정하지 않으면 기본적으로 innodb_data_home_dir 경로에 ibtmp1:12M:authextend 속성으로 생성됩니다.

 

[Note]
MySQL 5.6에서는 압축되지 않은 테이블에 대한 임시 테이블 스페이스는 개별 file-per-table 테이블 스페이스에 생성되었었습니다.
또는 innodb_file_per_table 설정이 안되어 있다면 시스템 테이블 스페이스에 생성됩니다.
5.7의 Temporary Tablespace 는 기존 개별 file-per-table 테이블 스페이스를 생성하고 삭제할 필요가 없기 때문에 성능 이점을 가집니다.
또한 전용 Temporary Tablespace가 있기 때문에 temp table 에 대한 metadata 를 시스템 테이블에 생성할 필요가 없어집니다.

 

[Mysql 5.7에서 임시테이블에 대한 성능개선]

Mysql ver 5.7.2에서 일반 임시 테이블과 압축 임시테이블 그리고 거기에 연관된 오브젝트들을 위한 새로운 타입의 Undo Log가 소개되었다. 임시 테이블의 내용은 Crash Recovery에서 사용되지 않기 때문에 redo log가 필요하지 않다. 즉, 임시테이블의 정보는 서버가 운영 중일때, 롤백해야 하는 상황에서만 필요하다. 리두로그를 만들지 않는 Undo Log는 해당 임시테이블과 거기에 관련된 오브젝트를 위한 redo logging으로 인해 발생하는 Disk I/O 를 피할수 있기 때문에 성능에 도움을 준다. 임시테이블에 대한 Undo log는 임시테이블 스페이스에 위치한다. 기본으로 생성되는 임시테이블 스페이스 파일은 ibtmp1이라는 이름을 가진다. 이것은 따로 지정하지 않으면 Data Directory에 위치하게 되고, 이것은 Mysql이 Startup 될 때 자동으로 재성생된다. 사용자의 요구에 따라 위치를 변경할 수 있는데 이때 사용하는 시스템 변수는 innodb_temp_data_file_path이다.

--> 아~ 임시파일을 저장하는 파일이군..

redo log를 쓰지않으니 Disk I/O 이슈는 없었던 것이고, DB를 재시작하게 되면 삭제하고 다시 생성하는 것으로 확인했다.

 

mysql> SELECT @@innodb_temp_data_file_path;
+------------------------------+
| @@innodb_temp_data_file_path |
+------------------------------+
| ibtmp1:12M:autoextend        |
+------------------------------+
1 row in set (0.00 sec)

#사용량 확인
mysql> SELECT * FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME='innodb_temporary'\G;
*************************** 1. row ***************************
             FILE_ID: 3293
           FILE_NAME: ./ibtmp1
           FILE_TYPE: TEMPORARY
     TABLESPACE_NAME: innodb_temporary
       TABLE_CATALOG: 
        TABLE_SCHEMA: NULL
          TABLE_NAME: NULL
  LOGFILE_GROUP_NAME: NULL
LOGFILE_GROUP_NUMBER: NULL
              ENGINE: InnoDB
       FULLTEXT_KEYS: NULL
        DELETED_ROWS: NULL
        UPDATE_COUNT: NULL
        FREE_EXTENTS: 736959
       TOTAL_EXTENTS: 747404
         EXTENT_SIZE: 1048576
        INITIAL_SIZE: 12582912
        MAXIMUM_SIZE: NULL
     AUTOEXTEND_SIZE: 67108864
       CREATION_TIME: NULL
    LAST_UPDATE_TIME: NULL
    LAST_ACCESS_TIME: NULL
        RECOVER_TIME: NULL
 TRANSACTION_COUNTER: NULL
             VERSION: NULL
          ROW_FORMAT: NULL
          TABLE_ROWS: NULL
      AVG_ROW_LENGTH: NULL
         DATA_LENGTH: NULL
     MAX_DATA_LENGTH: NULL
        INDEX_LENGTH: NULL
           DATA_FREE: 772806803456
         CREATE_TIME: NULL
         UPDATE_TIME: NULL
          CHECK_TIME: NULL
            CHECKSUM: NULL
              STATUS: NORMAL
               EXTRA: NULL
1 row in set (0.05 sec)

 

* 그렇다면 너무 커진 Temporary Tablespace 를 줄이기 위한 방법은 ?

--> DB를 재시작하여 기본설정으로 Tablespace 를 재생성하도록 하는 방법밖에 없다고 한다

하지만 다행이다; 이건 개발 DB다.

 

따라서 설정 시에 디스크 사이즈를 고려하여 너무 크게 설정하지 않도록 max 를 제한할 수 있는 방법도 있다

[mysqld]
innodb_temp_data_file_path=ibtmp1:12M:autoextend:max:500M

주의할 점은..

쿼리가 수행 도중에 MAX 에 도달하게 되면 table is full 에러를 내면서 쿼리는 실패됩니다. --> 잠깐만요..; 뭐라고요?
하지만 무제한으로 tablespace 를 제공할 수는 없기 때문에 적절한 사이즈를 정해야 합니다.

--> DB는 분기별로 정기 PM이 있어서 굳이 넣을 필요가 있을까 싶다.. 그냥 재시작한다.

 

* DB shutdown 후 파일확인

# ls -lh
합계 8.1G
drwxr-x--- 2 mysql mysql  12K 2020-10-13 13:43 xxDB
drwxr-x--- 2 mysql mysql  20K 2020-02-28 17:35 xxxDB
drwxr-x--- 2 mysql mysql  52K 2021-02-22 18:49 zzz
drwxr-x--- 2 mysql mysql  20K 2021-02-23 18:35 xxDB
drwxr-x--- 2 mysql mysql  12K 2021-02-16 15:05 xxDB
drwxr-x--- 2 mysql mysql 4.0K 2021-02-02 18:56 xxDB
drwxr-x--- 2 mysql mysql  52K 2021-02-23 12:53 xxxxDB
-rw-r----- 1 mysql mysql   56 2020-02-28 17:45 auto.cnf
drwxr-x--- 2 mysql mysql 4.0K 2020-02-28 17:34 backup
-rw-r----- 1 mysql mysql  36K 2021-02-10 15:22 ddl_log.log
-rw-r----- 1 mysql mysql 2.7M 2021-02-24 08:21 ib_buffer_pool
-rw-r----- 1 mysql mysql 256M 2021-02-24 08:21 ib_logfile0
-rw-r----- 1 mysql mysql 256M 2021-02-24 03:05 ib_logfile1
-rw-r----- 1 mysql mysql 256M 2021-02-24 08:21 ib_logfile2
-rw-r----- 1 mysql mysql 500M 2021-02-24 08:21 ibdata1
-rw-r----- 1 mysql mysql 500M 2021-02-24 08:21 ibdata2
-rw-r----- 1 mysql mysql 500M 2021-02-24 03:13 ibdata3
-rw-r----- 1 mysql mysql 5.9G 2021-02-24 08:21 ibdata4
-rw-r----- 1 mysql mysql 2.8K 2020-02-28 17:43 mvno-my.cnf
drwxr-x--- 2 mysql mysql 4.0K 2020-02-28 17:35 mysql
drwxr-x--- 2 mysql mysql 4.0K 2020-02-28 17:34 performance_schema
drwxr-x--- 2 mysql mysql  12K 2020-02-28 17:43 sys
drwxr-x--- 2 mysql mysql 4.0K 2020-02-28 17:43 test
-rw-r----- 1 mysql mysql   22 2020-02-28 17:43 xtrabackup_binlog_pos_innodb
-rw-r----- 1 mysql mysql  578 2020-02-28 17:43 xtrabackup_info

//DB shutdown 후 확인해보니 파일이 사라졌다. DB를 내릴때 같이 삭제하는 로직인 것을 알수 있다.

DB를 다시 startup 하고 ls -lh로 파일을 확인해보니 ibtmp1 파일이 12M 로 생성된 것을 확인할 수 있었다.

 

파티션별 디스크 용량한번 다시 확인

df -Th
Filesystem           Type   Size  Used Avail Use% Mounted on
/dev/sda2            ext4    20G  4.0G   15G  22% /
tmpfs                tmpfs   16G     0   16G   0% /dev/shm
/dev/sda1            ext4   477M  142M  310M  32% /boot
/dev/sda5            ext4    20G  9.7G  9.0G  52% /usr
/dev/sda7            ext4   3.9G  927M  2.8G  26% /var
/dev/sda6            ext4   3.9G  8.0M  3.7G   1% /tmp
/dev/sdb1            ext4   1.1T  224G  821G  22% /data
/dev/sda8            ext4   212G  136G   66G  68% /backup
xxx.xxx.xxx.xxx:/backup2 nfs    2.5T  1.9T  497G  80% /backup2

이슈 해결 끝~

 

참조:
https://m.blog.naver.com/PostView.nhn?blogId=sory1008&logNo=221381987533&proxyReferer=http:%2F%2Fwww.google.co.kr%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D%26ved%3D2ahUKEwjL3e3s6f7uAhUKPnAKHcIqCL8QFjAAegQIAhAD%26url%3Dhttp%253A%252F%252Fm.blog.naver.com%252Fsory1008%252F221381987533%26usg%3DAOvVaw3NPXn05xI9F2uUudbJ4-Vf
https://mysqldba.tistory.com/284

반응형
블로그 이미지

dung beetle

취미는 데이터 수집 직업은 MYSQL과 함께 일하는 DBA의 소소한 일상 이야기

,