2019년 5월 27일 월요일

spring mongodb Sort시 에러.

spring mongodb Sort시에 아래와 같은 에러가 발생한다.

Query failed with error code 96 and error message 'Executor error during find command :: caused by :: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.' on server localhost:27017

조회하려는 테이블이 log성 테이블이라 백만건이 넘어간다.
Sort 하려는 필드는 lastUpdated 이다. 해당 필드를 index에 추가 해서 해결했다.
index 추가하는 건 compass로 접속 해서 collection 선택하면 나오는 index 탭에서 쉽게 할 수 있다.

근데, compass에서는 index 설정을 안해도 잘 된다. 어떻게 되는 건지 모르겠다.

2019년 4월 17일 수요일

mysql federated 트래픽 증가 문제.

어느 날 갑자기 트래픽이 약 2배이상 증가한 것을 확인 해 보니 nethogs 로 확인 해 보니
 mysql 프로세스가 문제 였다.

federated 를 사용하여 간단한 상태체크를 하는 테이블을 하나 만들어 사용중이였는 데, 이게 문제 였다.

원인은 federated 테이블을 select 해 올 때 index를 타지 않으면 모든 데이터를 가져온 후 처리 하는 방식이였다.

약 22,000건 정도의 데이터를 가져오는 데, 약 1.5M 정도의 데이터를 사용하고 있었다.


         SELECT
        *
       FROM CHARGER_STATUS
       WHERE send = 'N'
       AND createdAt > @intervalTime

createdAt(timestamp)에 index를 설정하고 실행 하니 2K정도로 줄어든 것을 확인 할 수 있었다.

2019년 4월 15일 월요일

mysql http post json 전송 트리거

mysql http post json 전송 트리거


테이블에 값이 insert 되면 trigger를 이용하여 http post를 전송하도록 한다.
mysql 자체적으로는 해당 기능을 지원하지 않는다.

검색해 보니 mysql의 UDF(user define function)를 이용하여 만들어진 mysql-udf-httpmysql-udf-http lib가 있다.


근데 최근 업데이트 2013년이다. 찜찜한 면이 있지만, 소스를 살펴보니 별 거 없다.
libcurl을 이용하여 http 전송해 주는 c로 짠 플러그인이다.



소스를 서버에 받은 후 압출을 풀고 컴파일 하면 된다.
문서상으로 되어 있는 설치가이드는 mysql을 소스 설치 했을 때 상황으로 보인다.
yum을 이용하여 설치 하였기 때문에 config 설정이 조금 다르다.
config 시 mysql_config 명령어를 사용하는 데, mariadb-devel를 설치해야 한다.


sudo yum install mariadb-devel -y

sudo wget https://github.com/y-ken/mysql-udf-http/archive/master.zip

unzip master.zip


or
(git 명령어가 있으면)
git clone https://github.com/y-ken/mysql-udf-http.git


여기서 소스를 조금 수정 해야 된다.
실제 테스트 해보면, http_post로 json 전송하면 받는 server에서 json 타입으로 인식을 하지 못한다.
json으로 post 전송하기 때문에 header에 "Content-Type: application/json"이 필요하지만 그런 설정 부분이 없다.
워낙 소스가 간단해서 http_post function을 복사해서 http_post_json을 하나 만들고
해더만 아래처럼 추가 했다.
...
  if (curl)
  {
    struct curl_slist *hs=NULL;
hs = curl_slist_append(hs, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);
...

소스 수정 파일


재컴파일 후 mysql 재시작 후 function 등록.
create function http_post_json returns string soname 'mysql-udf-http.so';

테스트 해보면 정상적으로 인식 된다.



cd mysql-udf-http-master/

sudo CPPFLAGS="-I/usr/include/mysql" sh ./configure --with-mysql=/etc/my.cnf   --enable-shared --libdir=/usr/lib64/mysql/plugin && sudo make && sudo make install



설치가 정상적으로 완료 되었으면 /usr/lib64/mysql/plugin 디렉토리에 mysql-udf-http.* 파일들이 생긴다.
동적으로 인식이 되기 때문에 mysql 재시작은 안해도 된다. (*** 같은 이름으로 다시 넣으면 인식 안된다. 그럴 때는 재시작하자)

mysql console 상에서 function을 등록해 준다.

create function http_get returns string soname 'mysql-udf-http.so';
create function http_post returns string soname 'mysql-udf-http.so';
create function http_put returns string soname 'mysql-udf-http.so';
create function http_delete returns string soname 'mysql-udf-http.so';


사용법
SELECT http_get('<url>');
SELECT http_post('<url>', '<data>');
SELECT http_put('<url>', '<data>');
SELECT http_delete('<url>');

테스트로 가져오면 잘 가져온다.
select http_get('http://example.com/');



lib_mysqludf_json을 설치해서 json 타입을 리턴 받을 수 있다.


소스를 다운받은 후 so 파일로 만들어 주면 된다.
이건 make를 지원하지 않아 다른 방식으로 만들어야 된다.
같이 다운받아지는 so 파일을 사용하려고 봤는데, 32bit이다.
[root@VM1554776686489 lib_mysqludf_json]# file lib_mysqludf_json.so
lib_mysqludf_json.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped

삭제 하자.

git clone https://github.com/mysqludf/lib_mysqludf_json.git

cd lib_mysqludf_json/

gcc -fPIC -shared -o lib_mysqludf_json.so -I/usr/include/mysql/  lib_mysqludf_json.c


만들어진 lib_mysqludf_json.so 파일을 plugin 폴더로 넣자.
mv lib_mysqludf_json.so /usr/lib64/mysql/plugin/

.sql 파일을 보면 function 만드는 법이 나온다. 복사해서 쓰자.


mariadb 기반으로 설치 하였다.


https://github.com/y-ken/mysql-udf-http
https://github.com/mysqludf/lib_mysqludf_json

워드프레스 서버 날라가다.

워드프레스를 사용하던 서버가 드디어 날라가 버렸다.
한 10개의 글도 같이 날라 갔다.

서버를 다시 맞추기가 어렵다.
구글 블로그로 갈아 타기로 했다.

최초로 설치형 블로그를 시작한 개기도 당시 근무하던 회사에서 외부 블로그 검색 자체를 막아 놨기 때문이였다.

이제 그런 것도 없으니 구글블로그를 써도 무방하다.
도메인 역시 필요없어지게 됐다. 연장 하지 않을 예정이다.

2018년 5월 24일 목요일

스택트레이스(stacktrace) 읽는 팁

자바는 에러 발생시 익셉션을 발생시켜서 에러가 발생한 위치를 정확히 알려준다.

스택트레이스는 꽤나 중요한 사항인데, 나 역시도 깊게 생각해 본 적이 없다.

그러다 okky 글을 읽고 내 나름의 스택트레이스 읽는 팁을 적어 본다.

 
1. lib 는 제외하고, 내 소스 부분만 본다.

2. 스택의 제일 윗 부분을 본다.

3. Caused by 가 있을 경우 제일 하단의 Caused by 부터 본다.

대부분의 경험있는 개발자라면 느낄 것이다. lib에서 에러가 발생하는 경우는 99%이상 없다고 본다.
에러의 대부분은 내가 짠 소스에서 발생한다.
개발할 때는 기본적으로 여러가지 라이브러리를 사용하기 때문에 스택이 복잡해 지는 데, 라이브러리를 제외하고 보면 꽤나 단순해 진다.

스택은 알다시피 First in Last Out (FILO)이다. 그렇기 때문에 제일 상단의 라인이 제일 마지막에 실행된 부분이고 이 부분이 에러인 경우가 가장 많다.

"Caused by: " 부분은 exception chaining 이 발생 할 때 나타나는 메시지이다.
제일 하단의 "Caused by: " 섹션에서 내 패키지가 없다면 패스, 있다면 해당 부분이 원인일 경우가 많다.

검색해 보니, 이런 부분을 이용하여 보기 스택트레이스를 보기 좋게 해주는 사이트도 있다.

참조
https://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors
https://bukkit.org/threads/how-to-read-stack-traces-and-troubleshoot-your-own-plugins-by-yourself.32457/

2018년 2월 10일 토요일

Parameter index out of range (3 > number of parameters, which is 2)

mybatis 사용시 아래와 같은 에러 발생.

Parameter index out of range (3 > number of parameters, which is 2)

원인은 mybatis 변수 사용시 '를 사용하였기 때문이였다.
#before
AND reg_date BETWEEN CONCAT('#{start_search_date}', ' 00:00:00') AND CONCAT('#{end_search_date}',' 23:59:59')

#after
AND reg_date BETWEEN CONCAT(#{start_search_date}, ' 00:00:00') AND CONCAT(#{end_search_date},' 23:59:59')

 

 

2017년 12월 26일 화요일

Mysql 암호화, 복호화

 
#암호화
INSERT INTO 테이블명 (컬럼1) VALUES (HEX(AES_ENCRYPT('문자열', SHA2('My secret passphrase',512))));

#복호화
SELECT CAST(AES_DECRYPT(UNHEX(컬럼1), SHA2('My secret passphrase',512)) as char) FROM 테이블명;
OR
#복호화
SELECT CONVERT(AES_DECRYPT(UNHEX(컬럼1), SHA2('My secret passphrase',512)) USING utf8) FROM 테이블명;

 

CAST나 CONVERT으로 형변환 하는 부분 때문에 한참 해맸다.
대부분의 블로그가 형변환을 안 써 놨다.(심지어 공식 사이트 에서도...)

암복호화 함수의 리턴값은 BINARY 이기 때문에 HEX를 사용하지 않으면 필드 타입을 BINARY 저장이 가능한 타입으로 지정해야 된다. 공식문서는 BLOB을 추천한다고...

문제는 BINARY타입으로 지정시 일반 문자열 저장이 안되는 문제가 있기 때문에 필드타입을 VARCAHR로 사용하고 HEX를 사용하여 저장이 가능 하도록 한다.

 

MySQL 5.6이상부터 변경 가능.
암호화 모드 확인
select @@block_encryption_mode

암호화 모드 변경
SET block_encryption_mode = 'aes-256-cbc';#기본값 aes-128-ecb

암호화 모도는 처음부터 확인. 중간에 바뀌면 골치 아파진다.