레이블이 MYSQL인 게시물을 표시합니다. 모든 게시물 표시
레이블이 MYSQL인 게시물을 표시합니다. 모든 게시물 표시

2022년 2월 11일 금요일

mysqldump 중 에러 발생. ERROR 1102 (42000): Incorrect database name '#mysql50#.gnome2'

아래와 같이 mysql 전체 백업을 진행하려고 하였다.

mysqldump -uroot -p'daims102938!' --all-databases > mysqldump.sql

에러가 발생.
ERROR 1102 (42000): Incorrect database name '#mysql50#.gnome2'

mysql data path로 가서 ls -al 로 전체 디렉토리를 확인하면 .gnome2와 .mozilla 디렉토리가 숨어있다.

mysql은 data path에 있는 디렉토리를 database로 인식한다. 그래서 .gnome2와 .mozilla를 database로 인식하였기 때문에 발생한 문제다.

원인은 리눅스를 gui로 설치하고 mysql계정을 만든 후 해당 계정을 mysql의 data path로 등록했기 때문이다.

mysql 계정으로 gui환경으로 접속 할 일이 없기 때문에 해당 디렉토리를 삭제하여 정상 처리 하였다.

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

2016년 12월 15일 목요일

mysql(mariadb) 테이블별 mysqldump 백업

디비별 디렉토리를 만들고, 테이블별 .sql 파일을 만든다.
[root@localhost cron.daily]# vim sqlBackup.sh 
#!/bin/bash

_DB_PASS='password'
_BACKUP_DIR='/backup/sqlBackup/'

find $_BACKUP_DIR* -mtime +7 -exec rm -fr {} \; > /dev/null 2>&1

db_list=`echo "show databases;" | mysql -N -uroot -p${_DB_PASS}`
eval `date "+day=%d; month=%m; year=%Y"`

INSTD="$_BACKUP_DIR/sql-backup-$year-$month-$day"
mkdir -p $INSTD

for db in $db_list; do
if [ ! -d $INSTD/$db ]
then
mkdir $INSTD/$db
fi
table_list=`echo "show tables" | mysql -N -uroot -p${_DB_PASS} $db`
for table in $table_list; do
mysqldump -uroot -p${_DB_PASS} --lock-all-table --opt --quick --quote-names $db $table > $INSTD/$db/${table}.sql
done
done

2014년 9월 12일 금요일

마리아DB 소켓 변경시 systemd-private-xxxx 디렉토리 안에 생성되는 문제.

마리아DB 의 socket 위치를 /tmp/mysql.sock 로 변경 하였습니다.
그랬더니, /tmp/systemd-private-xxxx/tmp/mysql.sock 으로 생성이 된다.
뭐 이렇게 해도 상관이 없으나, 클라이언트 접속시 접속이 되지 않는다.

[client]
socket=/tmp/mysql.sock

위와 같이 처리 하면 될 것 같았으나, 위처럼 하면 그냥 /tmp/mysql.sock 으로 인식된다.

centos 7버젼으로 설치 했더니, 조금 바뀐게 많다.
tmp 디렉토리의 보안이 추가 된것으로 보인다.

 
vim /lib/systemd/system/mariadb.service 
PrivateTmp=true 에서 PrivateTmp=false 로 변경.
systemctl daemon-reload
service mariadb restart

2014년 9월 5일 금요일

Mysql 4.0 -> 마리아 5.5.37 마이그레이션


  1. mysql 4.0  dump

  2. mysql 4.1.22 업그레이드

  3. mysql 5.5 업그레이드

  4. 마리아 db 설치.


mysql 4.1 버젼에서 마리아db 로 변경하는 부분은 그냥 덮어 쓰면 됨.

문제는 mysql 4.0 에서 mysql 4.1 로 업그레이드 부분.

binary로 그냥 덮어써도 되지만,  field size 가 반으로 줄어 버리기 때문에 문제가 발생 할 수 있다고 함.

그래서 dump 파일을 생성 해서 써야 함.
mysqldump -u root -ppass --opt --quick --quote-names --all-databases > allBackup.sql

-opt 옵션은 문제가 없다면 쓰는 게 좋음. 백업, 복구 시간을 엄청 단축시킴.
-quote-name 옵션은 테이블 필드명 중, sql 쿼리명이 들어가 있어서 문제를 발생시켜 넣어줌.

restore 완료후에는 mysql_install_db 를 실행 시켜줌.

아래는 마이그레이션시 사용한 스크립트.
#!/usr/bin/bash

#mysql 4.1.22 설치
#killall mysqld
echo "kill mysql"
service mysqld stop
rm -rf /usr/local/mysql/

cd /usr/local/src/mysql-4.1.22/
make install #컴파일 되어 있음. 설치만 하면 됨.
/usr/local/mysql/bin/mysql_install_db
chown -R mysql.mysql /usr/local/mysql
cp -f /usr/local/mysql/share/mysql/mysql.server /etc/init.d/mysqld
service mysqld start

#패스워드 설정
/usr/local/mysql/bin/mysqladmin password 'test01'

/usr/local/mysql/bin/mysql -uroot -ptest01 -e 'select now();' #그냥 확인용 or 복구 시간 확인.
#echo $?
#1 이면 제대로 안된거.

#덤프 복구시 필요. 안하면 에러남.
/usr/local/mysql/bin/mysql -uroot -ptest01 -e "set global max_allowed_packet=1000000000;"
/usr/local/mysql/bin/mysql -uroot -ptest01 -e "set global net_buffer_length=1000000;"
#--------------------------------------------------------------------------------------

echo "Start Restoring..."
#43번 dump 복구.
# --debug : 에러 확인용.
# -f 에러 무시 : 43번 덤프파일 duplication 에러남.
/usr/local/mysql/bin/mysql --debug -f -uroot -ptest01 < /usr/local/src/43_DB_ALL_20140820.sql

#설치시 나오는 duplication 정상.
#그외에 오류는 안 나야 됨.
#복구 끝나면 root 패스는 pass 이 됨.
#비교를 위해 test01로 설정.
/usr/local/mysql/bin/mysql -uroot -ptest01 -e 'select now();' #복구 시간 확인.
#--------------------------------------------------------------------------------------

#mysql 5.5.39 설치
#killall mysqld
service mysqld stop
cd /usr/local/src/mysql-5.5.39/
make install
cp -f /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chown -R mysql.mysql /usr/local/mysql
service mysqld start
#/usr/local/mysql/bin/mysql_fix_privilege_tables --password=pass
/usr/local/mysql/bin/mysql_upgrade --password=pass
/usr/local/mysql/bin/mysql -uroot -ppass -e 'select now();' #그냥 확인용.
chkconfig mariadb on

#마리아DB 설치 yum
service mysqld stop
service mariadb stop
ln -fs /usr/local/mysql/data/ /var/lib/mysql
yum -y remove mariadb mariadb-devel mariadb-libs mariadb-server
yum -y install mariadb mariadb-devel mariadb-libs mariadb-server
service mariadb start
mysql_upgrade --password=pass

완벽하지 않음.

마리아db 설치 완료 my.cnf 에 euckr 추가.
[mysqld]
...
#charset config
character-set-server=euckr
init_connect=SET collation_connection=euckr_korean_ci
init_connect=SET NAMES euckr
character-set-server=euckr
collation-server=euckr_korean_ci
...

2014년 8월 22일 금요일

mysql 에러 라인 출력.

mysql dump를 복구 하는데, 에러가 남.

근데, 어디서 에러가 나는 지 라인이 안나옴.

--debug  옵션을 주자.
mysql  --debug  database < database.sql

근데 에러남.

ERROR: Option 'debug' used, but is disabled

재컴파일 해야 된다고 함.
./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --with-charset=euckr --with-debug

mysql 4.1.22 버젼 이었음.

2014년 8월 19일 화요일

mysql 4.0 to 5.1 업그레이드

frm 파일 자체를 옮겨서 시도.
실패.

mysqldump 로 시도.
mysqldump -u root-ppass -e --all-databases > DB_ALL.sql

아래와 같은 오류 발생.
ERROR 1064 (42000) at line 250: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IN smallint(6) unsigned NOT NULL default '0',
  OUT smallint(6) unsigned NOT NUL' at line 18

정상적인 쿼리이나, IN 필드명이 mysql에서 사용하는 명령어라서 에러가 발생하는 것으로 보임.

테스트로 해당 테이블 필드를 모두 '로 감싸고 실행 했더니, 정상적으로 실행됨.

필드명를 '(따옴표)로 감싸줄 필요가 있음.

--quote-names 추가.
mysqldump -u kim01 -pwjqthr01 --opt --quick --quote-names --all-databases > DB_ALL.sql

결론.
-  mysql 간의 이동이라면 --opt 옵션를 사용하자. 복구 시간이 엄청 단축된다.
- --quote-names 를 사용하자.

참조 : http://start.goodtime.co.kr/2013/03/mysqldump-sql-%ED%98%B8%ED%99%98%EC%84%B1-%EB%86%92%EC%9D%B4%EA%B8%B0/

2013년 1월 3일 목요일

mysql 4.0 이하에서 bin 로그 제거

bin 로그 제거

mysql 버젼 : mysql Ver 12.22 Distrib 4.0.26, for pc-linux-gnu (i686)

my.cnf 에 아래의 옵션을 주면 되지만, MySQL 5.0.3 이상부터 지원.
expire_logs_days = 7
크론에 아래와 같이 등록 하여 사용하라고 했는 데, syntex 에러 발생
00 00 * * 7 /usr/local/mysql/bin/mysql -uroot -pxxxxx -e "PURGE BINARY LOGS BEFORE date_sub(now(), interval 7 day)";
출처

BEFORE 변수는 MySQL 4.1 (으)로부터 이용 가능하게 되어 있다고 함.;;
출처

할 수 있는 건, 아래 꺼 밖에 없음
PURGE MASTER LOGS TO 'mysql-bin.010';
스크립트 작성.
bin 로그 10개만 남기고 나머지 다 삭제.

 
#!/bin/sh
bin_log_path="/usr/local/mysql/data/"
bin_log_name="mysql-bin"
bin=${bin_log_path}${bin_log_name}

max_bin_index=`ls ${bin}.* | awk -F. '{print $2}' | sort -n | tail -1`
del_index=`expr ${max_bin_index} - 10`
if [ -f ${bin}.${del_index} ]
then
echo "${bin_log_name}.${del_index} 파일 존재"
echo "${bin_log_name}.${del_index} 이전 파일 제거"
/usr/local/mysql/bin/mysql -uroot -p패스워드 -e "PURGE MASTER LOGS TO '${bin_log_name}.${del_index}'";
fi

2011년 10월 26일 수요일

리눅스 콘솔 입력창에서 mysql 쿼리 날리기.(실행결과를 파일로 저장하기)


몇몇 업체에서 테이블의 정보를 보내달라고 할 때가 있다.
이 때 테이블의 내용이 몇 줄 안되면 mysql 들어가서 select 해서 이렇게 해서 나온 화면을 복사해서
넘기곤 했다.

문제는 내용이 몇천줄 이상가면 화면이 넘어가서 복사도 할 수 없다.

알고 보면 엄청 간단한데 검색해도 잘 안나와서 적어본다.

콘솔창에서 쿼리문을 날리고 이걸 파일로 저장하면 참 좋을 텐데, 어떻게 방법없나 검색해 봤지만
검색나오는 게 없더라...

오늘 bash 스크립트 짠다고 여기저기 뒤지다.
드디어 발견했다.

http://www.joinc.co.kr/modules/moniwik ··· isc.html


10.5번을 보면 아래와 같은 소스가 나온다.



#!/bin/bash 
DBS=`mysql -uroot -e"show databases"` 
for b in $DBS ; 
do 

mysql -uroot -e"show tables from $b" 
done




mysql 옵션에 -e 를 주면 된다는 것을 알수 있다.

응용해서 해보면 아래와 같이 할 수 있을 것이다.
/usr/local/mysql/bin/mysql -uroot -p패스워드 -e "use database_1;show tables" > table.txt