'MySQL'에 해당하는 글 9건

DBCP connection 유지

Daily/Prog 2021. 10. 6. 21:30
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 38,597,187 milliseconds ago.  The last packet sent successfully to the server was 38,597,188 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
Caused by: java.net.SocketException: Connection timed out (Write failed)

 

개발서버에서 작업 후 다음날 출근하여 동일한 웹페이지에서 쿼리를 보낼 때 발생하는 오류이다. 매일 아침 반복되고 있다.ㅋㅋ mysql connection 이 끊어진 것으로 보이는데... mysql 의 wait_timeout 옵션에 8시간으로 설정되어 있어, 이 시간이 지나고 쿼리를 보낼 때 발생하는 오류이다. autoReconnect=true 를 설정하라는 메시지가 보이지만 이미 설정된 상태이며, 같은 상황에서 이 옵션은 어쨌든 재접속에는 성공하겠지만 접속이 끊긴 상태에서의 첫번째 요청에는 에러를 발생시킬 것이다.

 

Caused by: java.sql.SQLException: Could not retrieve transation read-only status server
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 32,648,084 milliseconds ago.  The last packet sent successfully to the server was 20 milliseconds ago.
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

 

마찬가지 상황인데 이를 방지하기 위해서는 dbcp 설정을 추가/수정해야 한다.

 

 

- validationQuery : select 1
- testWhileIdle : true (커넥션 풀 안에 있는 유휴 상태의 커넥션을 대상으로 테스트 실행)
- timeBetweenEvictionRunsMillis : 7200000 (쓰레드가 동작하는 간격)
- testOnBorrow : true (커넥션  풀에서 커넥션을 가져올때 해당 커넥션의 유효성 검사 실행)

 

위는 2시간 마다 유휴 상태의 커넥션을 대상으로 'select 1' 쿼리를 실행하여 커넥션을 유지시키는 설정이며, naver d2 사이트에서 성능상 testOnBorrow 옵션과 testOnReturn 옵션은 false, testWhileIdle 옵션은 true 로 설정을 추천하고 있지만, 개발서버에는 testOnBorrow 를 true 로 설정하는 것이 좋을듯...?

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

RDS cpu 100%

Database/Mysql 2017. 8. 9. 23:39

결론부터 말하자면 RDS 의 cpu 가 예상과 다르게 100% 를 찍는다면 빨리 slow query 를 찾아보세요.

며칠 동안 불규칙 적으로 발생한 5분 정도 짜리의 cpu 과부하를 찾아내는 것은 쉽지 않았습니다.

RDS 에서 생성된 slow_query.log 파일에는 로그 flush 메시지 밖에 없었으니까요.


/rdsdbbin/mysql/bin/mysqld, Version: 5.6.27-log (MySQL Community Server (GPL)). started with:
Tcp port: 3306 Unix socket: /tmp/mysql.sock
Time Id Command Argument
cs


특별히 높지 않은 커넥션 수...

lock 이 걸렸는지, slow query 가 걸렸는지 5분 정도만에 cpu 점유율이 다시 안정을 되찾는...

밤이고 낮이고 심심할 때 가끔씩 찾아오는 과부하라...


그 시간대에 발생된 query 를 5 대가 넘는 서버에서 모두 뽑기엔, 아니 뽑는다 해도 이 중 무엇이 문제인지 알 수가 없다는...

람다에서 주기적으로 유입되는 데이터를 의심했지만, 시간대가 맞기도 하고 안맞기도 하고...

processlist query 를 1분마다 날리면서 lock 걸린 query 를 찾아야 하는 것인가...


일단 slow query 를 좀 봐야겠다는 생각에 20초 짜리 query 를 날렸지만, 이마저 slow_query.log 파일은 응답하지 않았습니다.


결국 고객센터에 징징거리기 시작했더니, 해결책을 알려줬습니다.

log_output 이 default 로 table 로 되어 있어서 slow query 가 테이블에 들어가 있다는...

EC~! 근데 왜 slow_query 파일이 생성되서 사람 민망하게 만드는 거냐고!!


화는 잠시 접어두고 결국 slow query 를 찾아 잘못된 인덱스를 수정하고 cpu 를 잠재웠습니다.

하필 중요한 검색 쪽이 ㅡㅡ;;

그럼 그렇지. 이 많은 query 들이 slow query 하나 없이 잘 돌아가고 있다고 생각한 나는 용자.


참고로 알아두면 좋을 Parameter Groups 를 적어 봅니다.


  • slow_query_log : 1 (slow query 사용)
  • long_query_time : 2 (slow query 제한, default 10 초)
  • log_queries_not_using_indexes : 1 (인덱스 타지 않는 query 기록)
  • log_output : table (로그 출력 table / file)





WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

Insert Emoji

Database/Mysql 2017. 2. 21. 22:52

웹서비스를 구축할 때 데이터베이스는 주로 utf-8 을 사용해 왔다.

요즘은 웹과 모바일 앱을 동시에 사용하다 보니, 입력란에 모바일 이모지들을 함부로(?) 입력하는 유저들 덕분에 앱이 종료되거나 오류가 발생하는 일이 생긴다.

이것은 모바일 내장 이모지들이 4byte 문자열이고, DB collation 이 3byte 집합인 UTF8 을 사용하기 때문이다.

그로 인해 아래와 흡사한 오류들을 마주할 수 있다.


### Error updating database.  

Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x83 \xF0...' for column 'comment' at row 1



해결 방법은 어렵지 않다. DB 옵션의 character_set / collation 과 테이블을 UTF8 에서 UTF8MB4 로 변경하면 된다.

Mysql 에서는 2010년 MYSQL 5.5.3 버전에 4byte 집합인 utf8mb4 charset 을 추가하였다.

기존 utf8 시스템을 utf8mb4 로 바꾸어도 값의 손실은 없으며, DB 용량이 조금 늘어날 것이다.


난 아래의 순서대로 기존 UTF8 코드를 UTF8MB4 로 변경했다.

(환경 : java / RDS mysql)



1. JDBC


connect.url=jdbc:mysql://db_domains.rds.amazonaws.com:3306/test?useUnicode=true&characterEncoding=utf8
cs


소스에서 DB 연결에 jdbc characterEncoding 을 지정하는데 이것을 utf8 에서 utf8mb4 로 바꾸면 되는줄 알았지만 MySQL Connector/J 문서에 보면 utf8mb4 는 지원하지 않는다.

그냥 characterEncoding 파라미터를 삭제해 버리면 DB 의 기본 인코딩대로 작동한다. 이거 수정하고 그냥 배포!

요고 안하면 조~기 맨 위에 오류가 발생한다.



2. Parameter Groups


RDS mysql 의 Parameter Groups 은 my.ini 파일과 같다. 각종 옵션들을 수정할 수 있다. 여기서 인코딩을 전부 바꿔준다.

(참고로 character_set_server 만 바꿔주고, 나머지는 default 로 내비둬도 utf8mb4 적용되었음.)



3. Table Column


이모지를 저장할 테이블의 컬럼들을 utf8mb4 로 수정한다.

table 전체를 바꿔도 무방하지만 난 이모지가 저장될 컬럼에만 utf8mb4 를 적용했다.


ALTER TABLE `oops4u`.`article` 
CHANGE COLUMN `title` `title` VARCHAR(255CHARACTER SET 'utf8mb4' NOT NULL COMMENT '제목 ' ,
CHANGE COLUMN `content` `content` VARCHAR(255CHARACTER SET 'utf8mb4' NOT NULL COMMENT '내용' ;
...
cs



4. DB reboot


Parameter groups 의 인코딩 관련한 옵션들은 바로 적용이 되지 않는다. 재부팅이 필요하다.

Parameter groups 가 적용되지 않으면 테이블 collation 변경 덕분에 오류 없이 데이터는 들어오지만 이모지 대신 ??? 문자로 도배될 것이다.

재부팅하고 자알~ 되는지 확인한다.



위 이미지는 ios 에서 입력한 이모지를 android 와 web 에서 확인한 것이다.

http://getemoji.com/ 의 이모지 리스트처럼 웹에서 ㅁ형태로 깨져보이는 이모지도 꽤 있지만 뭐...

그건 내 힘으로 해결할 수 있는건 아닌듯 하고...




유의사항


Mysql 에서 한 컬럼의 최대 key 사이즈는 767 byte 이다.

그래서 index 가 문자열일 경우 utf8 에서는 255 까지 지정이 가능했다 (767 / 3 byte = 255...)

만약 utf8mb4 로 변경한 컬럼이 문자열 index 로 사용되고 있다면, 그 컬럼의 자료형은 varchar(191) 로 수정되어야 한다. (767 / 4 byte = 191...)

그렇지 않으면 아마도 이런 오류를 만나게 될 것이다.


ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes


혹은 innodb_large_prefix=1 로 시스템 변수를 설정하면 key 길이가 3072 byte 까지 확장되므로 위 오류를 막을 수 있다.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

 

 

 

아주 오래전, 기억이 나지 않는 어떤 이유로 워크벤치는 사용하지 않았다. dbforge가 가볍고 좋았다;
주변에서 워크벤치에 대한 질문들이 간혹있어 깔아봤는데 시작부터 장애가 ㅋㅋ

 

특정 테이블의 데이터를 직접 수정하려니 불가능하다.
Read Only 라고 쓰여 있는 곳에 마우스를 올리니,

 

The table has no unique row identifier (primary key or a NOT NULL unique index)

 

Primary key 가 필요없는 테이블이니 Primary key 를 넣지 않았을 것이고,
unique index 도 넣을 수 없으니 넣지 않았을 것이고...

 

Not unique index 하나 넣으니 Read Only 가 사라졌음. ^^
primary key 나 index 가 없다는 이유로 Read Only 를 거는 이유가 뭐지?
오히려 primary key 나 index 걸린 데이터를 수정하는게 더 위험한거 아닌가???

 

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,