#include <stdio.h>
#include <sys/timeb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/wait.h>
#include <sys/poll.h>
#include <stdbool.h>
#include <fcntl.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include "mysql.h"

 

#define SZ_QUEUETEXT 4096

 

struct __MESSAGE_QUEUE
{
    long mtype;
    char mtext[SZ_QUEUETEXT];
};

 

MYSQL *mysql=NULL;
MYSQL *connection=NULL;
char mesg[1024];

 

static int s_insert(char *buff);
static int s_commit(void);
static int ____l_myInsert(MYSQL *mysql, char *query, char *errmsg);
static int extract_message_from_strchr(char *resultstr, char msg[8][100]);
static int insert_into_rb_order_test(char *rbuf, int rlen, char *queue_name, int kk);
static int ____getmsgqueue(key_t qkey);
static int ____rcvmsgqueue(int q_id, struct __MESSAGE_QUEUE *msg_buf, int msg_type);
static char *____get_semiconlon_date_time(void);

char rb_memory_buf[200000][999];
int rb_memory_cnt=0;

 

int main(int argc, char *argv[])
{
    int kk, rc, rlen;
    struct __MESSAGE_QUEUE msg_buf;
    int qkey, q_id = -1, mtype=1;
    char rbuf[4096];

    if(argc != 2) return(-100);

 

    sscanf(argv[1], "%x", &qkey);
    if((q_id = ____getmsgqueue(qkey)) < 0)
    {
        printf( "____getmsgqueue q_id[%d] error[%d]\n", q_id, errno);
        return(-1);
    }

    mysql = mysql_init(NULL);
    if(mysql == NULL) {
        return(-1);
    }

    connection = mysql_real_connect(mysql, "127.0.0.1", "heroG", "duddnd702!", "HEROG", 0, NULL, 0);
    if (connection == NULL)
    {
        return(-2);
    }

      /*READ LOOP------------------------------------------*/

    kk=0;
    while(1) 
    {
        rlen = 0;
        errno = 0;
        memset(&rbuf, 0x00, sizeof(rbuf));
        memset(&msg_buf, 0x00, sizeof(msg_buf));

        rlen = ____rcvmsgqueue(q_id, &msg_buf, mtype);
        if (errno > 0)
        {
            printf( "____rcvmsgqueue error[%d]\n", errno);
            break;
        }
        else  
        {
            if(rlen == 0)
            {
                usleep(10000);
                continue;
            }
        }
        memcpy(&rbuf[0], (char *)&msg_buf.mtext[0], rlen);

        rc = insert_into_rb_order_test(rbuf, rlen, argv[1], kk);
        if(rc)
        {
            return(-1);
        }

        kk++;
    }
    mysql_close(connection);
    return(0);
}

int insert_into_rb_order_test(char *rbuf, int rlen, char *queue_name, int kk)
{
    char command[4096];
    char msg[8][100];
    int rc;

 

    memset(command, 0x00, sizeof(command));
    memcpy(command, rbuf, rlen);

#if(1)
    rc = extract_message_from_strchr(rbuf, msg);
    if(rc)
    {
        //ERROR
    }
    sprintf(command, "REPLACE INTO"

                     " RB_OCUS_POS_TEST2(seqno,account_no,stock_symbol,start_volume,start_amount,"

                     "start_price,stock_type,trustee_id,regtime) VALUES("
                     "%s,"
                     "'%s',"
                     "'%s',"
                     "'%s',"
                     "'%s',"
                     "'%s',"
                     "'%s',"
                     "'%s',"
                     "'%s');",
                     msg[0],
                     msg[1],
                     msg[2],
                     msg[3],
                     msg[4],
                     msg[5],
                     msg[6],
                     msg[7],
                     ____get_semiconlon_date_time());
    rc = s_insert(command);
    if(rc)
    {
        printf("(error)(%s)\n", command);
        return(-1);
    }
    else
    {
        s_commit();
    }
#endif

    if(kk / 500 * 500 == kk) printf(">>QUEUE[%s],TIME(%s),SQ(%s)\n", queue_name, ____get_semiconlon_date_time(), command);

    return(0);
}

int extract_message_from_strchr(char *resultstr, char msg[8][100])
{
    char tmp[100][1024];
    char tmpstr[1024];
    char *d1, *d2;
    int kk, rc;

 

    memset(tmp,0x00,sizeof(tmp));

    for(kk=0; kk<8; kk++) memset(&msg[kk],0x00,sizeof(msg[kk]));

 

    kk=0;
    d1 = strchr(resultstr, '|');
    memcpy(tmp[kk++], resultstr, d1 - resultstr);

    if(d1 != NULL)
    {
        for(;;)
        {
            d2 = strchr(d1+1, '|');
            if(d2==NULL) break;
            memcpy(tmp[kk++], d1+1, d2-d1-1);

            d1 = strchr(d2+1, '|');
            if(d1==NULL) break;
            memcpy(tmp[kk++], d2+1, d1-d2-1);
        }
    }
    rc=kk;

 

    for(kk=0; kk<rc; kk++)
    {
        memset(tmpstr,0x00,sizeof(tmpstr));
        strcpy(tmpstr, tmp[kk]);

        memcpy(msg[kk],tmpstr,strlen(tmpstr));
    }
    return(0);
}

int s_insert(char *buff)
{
    if (____l_myInsert(mysql, buff, mesg) < 0) 
    {
        printf( "%s\n", mesg);
        return(-1);
    }

    return(0);
}

int s_commit(void)
{
    mysql_commit(mysql);

    return(0);
}

int ____l_myInsert(MYSQL *mysql, char *query, char *errmsg)
{
    int retn;

    retn = mysql_real_query(mysql, query, strlen(query));
    if (retn != 0)
    {
        sprintf(errmsg, "SQL insert Error[%d].",mysql_errno(mysql));
        return -1;
    }

    return (mysql_affected_rows(mysql));
}

/*- ------------------------------------------------------------------------- -*
 *- Message Queue Get
 *- ------------------------------------------------------------------------ -*/
int ____getmsgqueue(key_t qkey)
{
    int q_id;

    if((q_id = msgget(qkey,IPC_CREAT | 0666)) < 0)
    {
        return(-1);
    }
    return (q_id);
}

/*- ------------------------------------------------------------------------- -*
 *- Message Queue Rcveive
 *- ------------------------------------------------------------------------ -*/
int ____rcvmsgqueue(int q_id, struct __MESSAGE_QUEUE *msg_buf, int msg_type)
{
    int msg_size;

    if((msg_size = msgrcv(q_id, msg_buf, SZ_QUEUETEXT , msg_type, MSG_NOERROR)) < 0)
    {
        if(errno == ENOMSG)
        {
            return(0);
        }
        return(-1);
    }
    return (msg_size);
}

char *____get_semiconlon_date_time(void)
{
    struct timeb itb;
    struct tm *lt;
    static char dt[100];

    ftime(&itb);

    lt = localtime(&itb.time);

    memset(dt , 0x00 , sizeof(dt));

    sprintf(dt, "%04d%02d%02d %02d:%02d:%02d(%03d)"
             , lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday
             , lt->tm_hour, lt->tm_min, lt->tm_sec
             , itb.millitm);
    return dt;
}

 

 

 

 

mysql> select * from RB_OCUS_POS_TEST2 limit 10;
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+------------------------+
| seqno | account_no | stock_symbol         | start_volume | start_amount  | start_price   | stock_type | trustee_id | regtime                |
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+------------------------+
|     1 | 0016100    | BANPU                | 0000045000   | 0000645569.57 | 000014.345990 | 02         |            | 20190829 15:31:55(410) |
|     2 | 0016100    | BBL                  | 0000001500   | 0000266962.22 | 000177.974813 | 02         |            | 20190829 15:31:55(410) |
|     3 | 0016100    | BPP                  | 0000002000   | 0000042000.00 | 000021.000000 | 02         |            | 20190829 15:31:55(410) |
|     4 | 0016100    | CK                   | 0000015375   | 0000296816.51 | 000019.305139 | 02         |            | 20190829 15:31:55(410) |
|     5 | 0016100    | IEC                  | 0012286603   | 0000308909.54 | 000000.025142 | 02         |            | 20190829 15:31:55(410) |
|     6 | 0016100    | IVL                  | 0000011769   | 0000309729.03 | 000026.317362 | 02         |            | 20190829 15:31:55(410) |
|     7 | 0016100    | KTB                  | 0000005000   | 0000103785.51 | 000020.757102 | 02         |            | 20190829 15:31:55(410) |
|     8 | 0055920    | ASAP                 | 0000001000   | 0000003106.87 | 000003.106870 | 02         |            | 20190829 15:31:55(411) |
|     9 | 0055920    | BCP                  | 0000001000   | 0000033574.22 | 000033.574220 | 02         |            | 20190829 15:31:55(411) |
|    10 | 0055920    | CBG                  | 0000000800   | 0000042844.70 | 000053.555875 | 02         |            | 20190829 15:31:55(411) |
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+------------------------+
10 rows in set (0.00 sec)

mysql>

 

mysql> select * from DUMMY;
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+
| seqno | account_no | stock_symbol         | start_volume | start_amount  | start_price   | stock_type | trustee_id |
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+
|     1 | 0016100    | BANPU                | 0000045000   | 0000645569.57 | 000014.345990 | 02         |            |
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+
1 row in set (0.00 sec)

mysql>

 

mysql> select @r:=@r+1 As rowNum, T2.* from DUMMY T1, (select substr(regtime,1,17) as t_regtime, count(1) as t_cnt from RB_OCUS_POS_TEST2 group by substr(regtime,1,17)) T2, (Select @r:=0) r limit 100;
+--------+-------------------+-------+
| rowNum | t_regtime         | t_cnt |
+--------+-------------------+-------+
|      1 | 20190829 15:31:55 |  2640 |
|      2 | 20190829 15:31:56 |  4744 |
|      3 | 20190829 15:31:57 |  5036 |
|      4 | 20190829 15:31:58 |  5270 |
|      5 | 20190829 15:31:59 |  2587 |
|      6 | 20190829 15:32:00 |  2909 |
|      7 | 20190829 15:32:01 |  3261 |
|      8 | 20190829 15:32:02 |  5019 |
|      9 | 20190829 15:32:03 |  5488 |
|     10 | 20190829 15:32:04 |  5853 |
|     11 | 20190829 15:32:05 |  4381 |
|     12 | 20190829 15:32:06 |  4307 |
|     13 | 20190829 15:32:07 |  2871 |
|     14 | 20190829 15:32:08 |   345 |
|     15 | 20190829 15:32:09 |  3368 |
|     16 | 20190829 15:32:10 |  3087 |

 

mysql> select @r:=@r+1 As rowNum, T2.* from DUMMY T1, (select substr(regtime,1,17) as t_regtime, count(1) as t_cnt from RB_OCUS_POS_TEST2 group by substr(regtime,1,17)) T2, (Select @r:=0) r limit 100;
+--------+-------------------+-------+
| rowNum | t_regtime         | t_cnt |
+--------+-------------------+-------+
|      1 | 20190829 15:31:55 |  2640 |
|      2 | 20190829 15:31:56 |  4744 |
|      3 | 20190829 15:31:57 |  5036 |
|      4 | 20190829 15:31:58 |  5270 |
|      5 | 20190829 15:31:59 |  2587 |
|      6 | 20190829 15:32:00 |  2909 |
|      7 | 20190829 15:32:01 |  3261 |
|      8 | 20190829 15:32:02 |  5019 |
|      9 | 20190829 15:32:03 |  5488 |
|     10 | 20190829 15:32:04 |  5853 |
|     11 | 20190829 15:32:05 |  4381 |
|     12 | 20190829 15:32:06 |  4307 |

 

>>아래 쿼리의 내용은 큐를 이용해서 데이타를 입력했을때에 순서적으로 입력이 안되는 상태임을 보여주는 예입니다.

>>큐가 10개라면, SERIAL하게 데이타가 입력되는것에 대한 정합성을 보장하지 않습니다.

>>저장하는 용도의 입력이면 괜찮지만, 순서적으로 입력이 보장되어야 한다면, 다른 로직을 넣어서 이를 해결해야 합니다.

 

mysql> select T2.rowNum, T2.t_seqno, T2.rowNum - T2.t_seqno from DUMMY T1, (select @r:=@r+1 As rowNum, T1.seqno as t_seqno from RB_OCUS_POS_TEST2 T1, (Select @r:=0) r order by regtime asc) T2 order by T2.t_seqno asc limit 100;
+--------+---------+------------------------+
| rowNum | t_seqno | T2.rowNum - T2.t_seqno |
+--------+---------+------------------------+
|      1 |       1 |                      0 |
|      2 |       2 |                      0 |
|      3 |       3 |                      0 |
|      4 |       4 |                      0 |
|      5 |       5 |                      0 |
|      6 |       6 |                      0 |
|      7 |       7 |                      0 |
|      8 |       8 |                      0 |
|      9 |       9 |                      0 |
|     10 |      10 |                      0 |
|     12 |      11 |                      1 |
|     11 |      12 |                     -1 |
|     13 |      13 |                      0 |

 

mysql> select T2.rowNum, T2.t_seqno, T2.rowNum - T2.t_seqno from DUMMY T1, (select @r:=@r+1 As rowNum, T1.seqno as t_seqno from RB_OCUS_POS_TEST2 T1, (Select @r:=0) r order by regtime asc) T2 where T2.rowNum - T2.t_seqno <> 0 order by T2.t_seqno asc limit 100;
+--------+---------+------------------------+
| rowNum | t_seqno | T2.rowNum - T2.t_seqno |
+--------+---------+------------------------+
|     12 |      11 |                      1 |
|     11 |      12 |                     -1 |
|     32 |      31 |                      1 |
|     33 |      32 |                      1 |
|     40 |      33 |                      7 |
|     31 |      34 |                     -3 |
|     34 |      35 |                     -1 |
|     35 |      36 |                     -1 |
|     36 |      37 |                     -1 |
|     37 |      38 |                     -1 |
|     38 |      39 |                     -1 |
|     39 |      40 |                     -1 |
|     47 |      43 |                      4 |
|     43 |      44 |                     -1 |
|     44 |      45 |                     -1 |
|     45 |      46 |                     -1 |
|     46 |      47 |                     -1 |
|     60 |      53 |                      7 | 

//ORDR_DT = YYYYMMDD

//ORDR_DT = YYYYMMDD

//ORDR_DT = YYYYMMDD

//ORDR_DT = YYYYMMDD

//ORDR_DT = YYYYMMDD

//ORDR_DT = YYYYMMDD

 

DELETE FROM OPS_ORDER WHERE ORDR_DT <= date_format(date_add(now(), INTERVAL -1 MONTH), '%Y%m%d');

MySQL LOCK 확인 및 해제(kill) 방법

 

MySQL 사용 시 관리자의 의도 혹은 그렇지 않은 이유들로 인해 Lock 상태가 발생한다.

이럴 경우 어느 쿼리가 Lock을 걸렸는지 확인 후 해당 쿼리를 해제(kill) 해야 할 상황이 있다.

 

Lock의 종류

 

Table Lock, User Lock, Global Lock, Name Lock이 있다. 트랜잭션 기반의 멀티 쓰레드를 사용하려면 Lock의 개념을 충분히 알아두어야 한다. 하지만 그렇지 못한 몇몇 프로그래머로 인해 다른 사용자들이 쿼리 대기상태(Lock으로 인한 리소스 접근 대기상태)로 서비스에 지장을 초래할 수 있다.

흔히들 알고있는 Read Lock, Write Lock은 Table, Global Lock 등에 포함된 내용이므로 이를 혼동해서 사용하지 않도록 하자.

이 포스팅은 Lock에 대한 개념을 다루지 않으므로, 보다 자세한 사항은 다른 포스팅을 참조하여 공부하고, Lock이 걸려있는 프로세스의 확인 및 해제를 다뤄보자.

 

Lock 확인 및 해제

 

아래 쿼리를 통해 현재 프로세스를 확인할 수 있다.

 

1. SHOW PROCESSLIST;

cs

(위 쿼리는 100개까지 list를 노출하며, 모두 노출 하려면 SHOW FULL PROCESSLIST;로 하면 된다.)

 

State컬럼을 보면 Waiting for table metadata lock 으로 인해 해당 쿼리가 진행되지 않음을 확인 할 수 있다.

그러면 이 프로세스를 해제(kill)해보자.

 

2. KILL 255;

cs

위 쿼리를 통해 lock을 해제할 수 있다.

 

 

원인

 

해당 테이블이 DDL을 통해 open상태일 경우.

선행 트랜잭션이 종료가 되지 않았을 경우 종료를 위한 DDL 구문 실행 대기.

보통 metadata lock info라는 별도의 플로그인을 통해 확인 할 수 있으나 불가능한 경우도 있다.

(트랜잭션 중 autocommit이 false일 때, commit을 수행하지 않고 DDL을 실행할 경우)

 

 

마무리

개발 중 문제에 봉착했을 때, 해결법에 대한 포스팅만 보고 해결하지 말고

원인을 분석하고 공부하다보면 내것으로 만들 수 있다는 생각으로 시간을 가지고 투자하면서

배움의 자세를 가지도록 노력하자.

 


#innodb_flush_log_at_trx_commit 에 따른 입력건수 성능비교
#innodb_flush_log_at_trx_commit 에 따른 입력건수 성능비교
#innodb_flush_log_at_trx_commit 에 따른 입력건수 성능비교
#innodb_flush_log_at_trx_commit 에 따른 입력건수 성능비교
#innodb_flush_log_at_trx_commit 에 따른 입력건수 성능비교

 

 

#QUEUE사용안함
#QUEUE사용안함

 

#QUEUE사용안함

#SERIAL형식의 입력
#SERIAL형식의 입력
#SERIAL형식의 입력
#SERIAL형식의 입력

 

mysql> select sum(T2.t_cnt) from DUMMY T1, (select substr(regtime,1,17) as t_regtime, count(1) as t_cnt from RB_OCUS_POS_TEST2 group by substr(regtime,1,17)) T2;
+---------------+
| sum(T2.t_cnt) |
+---------------+
|        161297 |
+---------------+
1 row in set (0.26 sec)

mysql>

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.04 sec)

1SEC > 647.7791164658635 입력

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 0     |
+--------------------------------+-------+
1 row in set (0.04 sec)

>>begin[20190829 07:23:04(988)],end[20190829 07:23:23(968)]

1SEC > 8489.315789473684 입력

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set (0.04 sec)

>>begin[20190829 07:25:41(568)],end[20190829 07:26:05(191)]

1SEC > 6451.88 입력 

+ Recent posts