Stored Procedure ....SP라고도 무르는 것 같은데......

Anyway...장단점에 대해서 정리해 본다.


Stored Procedure 는 Oracle DBA로 재직하면서 끊임없이 나와 마주했던 친구다.

내가 처음부터 끝까지 다 작성한 것은 많지 않지만..문제 발생 시 개발자와 같이 확인하고..Invaild로 상태가 바뀌었는지 체크하고

바뀌었으면 왜 바꼈는지...누가 해당 부분을 수정했는지 확인했다.


그리고 때로는 튜닝 요청관련해서 몇백줄 몇천줄 나의 능력을 뛰어넘는 놈을 이겨볼 꺼라고 아둥바둥 거렸다.


각설하고 MySQL에서는 Stored Procedure 라고 명명 한다.


장점


- DB 보안 향상

  -> 자체적인 보안 설정 기능을 가지고 있으며, Stored program 단위로 실행 권한을 부여할 수 있다.

  -> 세밀한 권한 제어가 가능

  -> SQL 인젝션과 같은 기본적인 보안 사고는 피할 수 있다.

  -> SQL 의 문법적인 취약점을 이용한 해킹이 어렵다


- 기능의 추상화

  ex) 여러 테이블에 걸쳐 유일한 일련번호를 발급하되, 일련번호에 자체적인 헤더 값과 시간 정보를 덧붙여서 생성

  -> 이러한 요구사항을 해결하기 위해서는 단순 Table 시퀀스(auto increment)를 사용하지 못하는데 Stored procedure 이용하면 해결가능


- 네트워크 소요 시간 절감

  -> 하나하나의 쿼리가 아주 가볍고 빠르게 처리될 수 있다면 네트워크를 경유하는 데 걸리는 시간이 문제가 될 수 있음

   (0.01만에 완료되는 쿼리가 0.1초의 네트워크 시간과  동일한 쿼리가 다량의 건수로 진행되는 경우 문제 소지)


- 절차적 기능 구현

  -> SQL 문장에 IF / While 과 같은 제어문장 사용 가능

    ( 어플리케이션 소스코드를 줄여줄 수 있음)


- 개발 업무의 구분

  -> 스토어드 프로그램을 만들어 API 처럼 제공하여 업무 구분


단점


- 낮은 처리 성능

  -> 다른 DBMS에 비해 Stored Procedure 프로그램은 성능이나 최적화가 부족하여 수행 능력이 떨어짐(오라클 pl/sql보다 2배 떨어짐)

  -> 문자열이나 숫자 연산을 위해 사용하기에는 나쁜 선택

  -> 하지만 한 번에 많은 쿼리를 실행해야 할 때 효율적임


- Application 코드의 조각화

 ??????이해가 되지 않기에 패스..


출처 : 개발자와 DBA를 위한 MySQL 서적


- 나의 생각 : 나는 Stored procedure 를 많이 만들지 않았지만 분명 여러가지로 유용한 부분이다.

Oracle로 비유하자면 많은 쿼리들이 Library cache에 등록이 되고 공유가 된다. 이 때 대,소문자 구분 및 바인드변수 미사용 등으로 동일한 쿼리이지만 전혀 다른 쿼리로 인식하여 실행계획이 공유되지 않는 상황이 발생된다. 이말은 즉슨, 동일한 쿼리로 인식하지 않기에 매번 하드파싱이 일어나 조금이라도 부하를 주게 된다. MySQL로 돌아와서 비슷한 것이라고 생각된다. MySQL에서 Stored procedure를 이용하게 되면 많이 사용되는 쿼리일 수록 부하는 줄게 될 것이고 성능적으로 향상될 것이다.

물론, 개발자들이 쿼리 규칙을 잘 지킨다면 걱정없겠지만...그게 아니라면 SP를 사용하는 것이 좋다고 생각든다.


몇주전에 어느 담당자가 SP는 MySQL 에 부하가 되기 때문에 사용을 지양 한다고 했었다.

나는 그 말에 동의 하지 않는다....

SP를 잘 사용한다면 많은 이득을 볼 수 있을 것이라고....


어디까지나 나의 생각일 뿐이다. 허접한...ㅠ

반응형

MySQL 관련하여 추가로 Percona 에서 제공하는 템플릿을 추가 함으로써

다양한 모니터링이 가능하다.


진행가능한 방법은 아래 사이트에서 확인하고 진행하면 된다.

https://www.percona.com/doc/percona-monitoring-plugins/LATEST/zabbix/index.html


yum으로 Install 할 수 있는데...직접 진행해 본 결과 yum으로는 진행이 안되어서 rpm 으로 설치를 직접 진행 하였다.


아래 사이트는 직접 파일을 다운받아 진행할 수 있다.

https://www.percona.com/downloads/percona-monitoring-plugins/LATEST/


Installation Instructions

Configure Zabbix Agent

  1. Install the package from Percona Software Repositories:

    yum install percona-zabbix-templates
    

    or:

    apt-get install percona-zabbix-templates
    

    It will place files under /var/lib/zabbix/percona/. Alternatively, you can grab the tarball and copy folderszabbix/scripts/ and zabbix/templates/ into /var/lib/zabbix/percona/. See below for the URL.

  2. Copy Zabbix Agent config:

    mkdir -p /etc/zabbix_agentd.conf.d/
    cp /var/lib/zabbix/percona/templates/userparameter_percona_mysql.conf /etc/zabbix_agentd.conf.d/userparameter_percona_mysql.conf
    
  3. Ensure /etc/zabbix_agentd.conf contains the line: Include=/etc/zabbix_agentd.conf.d/

  4. Restart Agent:

    service zabbix-agent restart
    

Configure MySQL connectivity on Agent

On this step we need to configure and verify MySQL connectivity with localhost on the Agent node.

  1. Create .cnf file /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php.cnf as described at configuration file

    Example:

    <?php
    $mysql_user = 'root';
    $mysql_pass = 's3cret';
    
  2. Test the script:

    [root@centos6 main]# /var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh gg
    405647
    

    Should return any number. If the password is wrong in .cnf file, you will get something like:

    [root@centos6 ~]# /var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh gg
    ERROR: run the command manually to investigate the problem: /usr/bin/php -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php --host localhost --items gg
    [root@centos6 ~]# /usr/bin/php -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php --host localhost --items gg
    ERROR: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)[root@centos6 ~]#
    
  3. Configure ~zabbix/.my.cnf

    Example:

    [client]
    user = root
    password = s3cret
    
  4. Test the script:

    [root@centos6 ~]# sudo -u zabbix -H /var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh running-slave
    0
    

    Should return 0 or 1 but not the “Access denied” error.

Configure Zabbix Server

  1. Grab the latest tarball from the Percona Software Downloads directory to your desktop.
  2. Unpack it to get zabbix/templates/ folder.
  3. Import the XML template using Zabbix UI (Configuration -> Templates -> Import) by additionally choosing “Screens”.
  4. Create/edit hosts by assigning them “Percona Templates” group and linking the template “Percona MySQL Server Template” (Templates tab).

You are done.



위의 내용은 단순히 복사해서 왔다. 이 이상도 이 이하도 아니다.

다만, 3. Configure ~zabbix/.my.cnf 는 사실 zabbix mysql 를 설치했을 때 의미인 것 같다.

그래서 나는 /etc/my.cnf 에 user 와 password 를 작성 후 진행 하였다.


이 후 Test 스크립트를 진행하게 되면 예시와 동일하게 값이 나왔다.



Import 를 진행 후 보는바와 같이 Percona MySQL Server Template 가 뜬 것을 확인할 수 있다.



MySQL 모니터링을 보게 되면 많은 Item 이 추가 된 것도 확인할 수 있다.

다양한 부분에 대해서 모니터링을 진행할 수 있다.


이 이상으로 추가로 Zabbix 관련 모니터링이 있는지 검색해 봐야겠다.



반응형

테스트 중에 나의 주요 목적인 MySQL 모니터링이 제대로 되고 있는지 확인해 보았다.


역시나 Server down.....OTL....

너란 녀석은 정말 힘들구나...


먼저 로그를 보는게 가장 좋다.

zabbix_agentd.log (/var/log/zabbix) 확인을 해 보았다.


여러 에러가 있었지만 이 부분이 가장 화근이었다.



보는 바와 같이 아래 에러를 이해하면 될 듯 싶다.

이미 존재한다고 한다......으응??????????????하아.....존재한다고..먼말이야;;;;

설마 존재하더라도 또 실행해도 되는거 아닌가....ㅠㅠ

이 내용을 빨리 이해했다면 시간을 허비하지 않아도 되었을텐데;;;

 9347:20160718:174922.943 using configuration file: /etc/zabbix/zabbix_agentd.conf

  9347:20160718:174922.973 cannot add user parameter "mysql.status[*],echo "show global status where Variable_name='$1';" | HOME=/var/lib/zabbix mysql -uzabbix -pzabbix -N | awk '{print $$2}'": key "mysql.status" already exists



 zabbix_agentd.conf 확인

- 여기서 해결되었다.

- 아래보면 Include 에서 나는 2개 동시를 include 하였다.

그래서 아래와 같이 하나만 실행되도록 하고 나머지는 모두 막았다.



이후 다시 실행 해 봤더니 되었다...(사실 에러가 발생하면 zabbix agent가 실행이 안되는 것을 확인 가능하다)


아래와 같이 MySQL 관련 항목들이 모두 받아 오고 있는 것을 확인 가능하다.




 결론 : 


zabbix_agentd.conf 에서 include를 2번이나 실행하면 안된다.


참고사항: https://www.zabbix.com/forum/showthread.php?t=40870



userparameter_mysql.conf


여기에는 추가적으로 이것저것 설정할 수 있다.

아래는 내가 테스트로 추가하다가 다 주석하고 제대로 된 default는 아니지만 참고 하면 된다.


mysql 또는 mysqladmin 에 문법에 맞춰 user와 패스워드를 작성해 줬다.

그리고 문법은 검색하면 나오지만 아래 사이트 참고하면 좋을 듯 싶다.


참고사항 : http://zabbix.dothome.co.kr/doku.php/manual/appendix/recipes


UserParameter=변수명,문법


인데...문법만 실행하면 해당 결과 값이 리턴되어 나온다.

리턴된 값을 변수에 담게 되고  zabbix 에서 사용하는 것으로 예상된다.

그래서 자신의 문법이 틀렸는지 여부는 바로 서버에서 확인하면 될 듯 싶다.


이 부분에서 에러생기면 또 실행이 안되니 이 점 필히 체크 필요하다.


UserParameter=mysql.status[*],echo "show global status where Variable_name='$1';" | HOME=/var/lib/zabbix mysql -uzabbix -pzabbix -N | awk '{print $$2}'

# Flexible parameter to determine database or table size. On the frontend side, use keys like mysql.size[zabbix,history,data].

# Key syntax is mysql.size[<database>,<table>,<type>].

# Database may be a database name or "all". Default is "all".

# Table may be a table name or "all". Default is "all".

# Type may be "data", "index", "free" or "both". Both is a sum of data and index. Default is "both".

# Database is mandatory if a table is specified. Type may be specified always.

# Returns value in bytes.

# 'sum' on data_length or index_length alone needed when we are getting this information for whole database instead of a single table

UserParameter=mysql.size[*],bash -c 'echo "select sum($(case "$3" in both|"") echo "data_length+index_length";; data|index) echo "$3_length";; free) echo "data_free";; esac)) from information_schema.tables$([[ "$1" = "all" || ! "$1" ]] || echo " where table_schema=\"$1\"")$([[ "$2" = "all" || ! "$2" ]] || echo "and table_name=\"$2\"");" | HOME=/var/lib/zabbix mysql -uzabbix -pzabbix -N'

UserParameter=mysql.ping,HOME=/var/lib/zabbix mysqladmin -uzabbix --password=zabbix ping | grep -c alive

UserParameter=mysql.version,mysql -V

#UserParameter=mysql.ping,mysqladmin -uzabbix --password=zabbix ping | grep alive | wc -l | tr -d " "

#UserParameter=mysql.uptime,mysqladmin -uzabbix --password=zabbix status | cut -f2 -d ":" | cut -f1 -d "T" | tr -d " "

#UserParameter=mysql.threads,mysqladmin -uzabbix --password=zabbix status | cut -f3 -d ":" | cut -f1 -d "Q" | tr -d " "

#UserParameter=mysql.questions,mysqladmin -uzabbix --password=zabbix status | cut -f4 -d ":"|cut -f1 -d "S" | tr -d " "

#UserParameter=mysql.slowqueries,mysqladmin -uzabbix --password=zabbix status | cut -f5 -d ":" | cut -f1 -d "O" | tr -d " "

#UserParameter=mysql.qps,mysqladmin -uzabbix --password=zabbix status | cut -f9 -d ":" | tr -d " "

#UserParameter=mysql.version,mysql -V





반응형

+ Recent posts