[질문] MYSQL INSERT, SELECT 시 LOCK 문제..

leolo의 이미지

아래 코드는 제가 mysql에서 insert, delete를 하는 코드입니다.
보시면, 아시겠지만, lock을 걸고, 나중에 락을 풀고 이렇게 하고 있습니다.

전에는 lock을 걸지 않았습니다. 그냥. 해도 잘 되었는데, 어느 순간
멈춰버리더군요. 그 멈춘 부분을 찾아보니, DB 질의하고 나니까 결과가 리턴이 되질 않더군요.
아마도, 멀티쓰레드 환경에서 문제가 발생한 것 같습니다.
그래서, 아래와 같이 lock을 걸게되었습니다.

1.첫번쨰질문 : 제가 mutex락을 제대로 걸고 있는건지, 그냥, 전역으로 lock을 걸고 하는데요. 이렇게 하면 문제가 없겠는지요?
2.두번째질문 : select하는 것도 락을 걸어야 하는지요?
추측하건데, select만 하는 프로세스는 이상없이 잘돌거든요. 만약, 이상이 없다면, select하는 코드는 lock을 걸지 않고, insert, delete하는 코드만 lock을 걸어도 될런지..

3.세번째질문 : lock을 걸고 걸지 않고의 시간적은 차이가 있는지요.
4.네번째질문 : 어떠한 경우에 의해서 lock이 풀리지 않는 상태에서 리턴이 되면 어떻게 되는지요. 또한 lock이 걸리는 시점에 프로세스가 죽었다 살면 어떻게 되는지요.

이상입니다.
여러 어르신들의 답변 부탁드립니다.


extern pthread_mutex_t db_mutex;
int deleteMysql(const char *query)
{
    int ret;
    pthread_mutex_lock(&db_mutex);
    // query 실행. 성공시 0을 리턴함
    if((ret = mysql_real_query(&mysql, query, (unsigned)strlen(query)) != 0))
    {
        DebugLog((DEB_ERROR, "[%s.%d][mysql_real_query] error(%s)(%d) \n", __FILE__, __LINE__,
            mysql_error(&mysql), mysql_errno(&mysql)));
        reconnectMysql();
        pthread_mutex_unlock(&db_mutex);
        return K_FAIL;
    }
    else
    {
        DebugLog((DEB_DEBUG, "QUERY[%s] \n", query));
    }
    pthread_mutex_unlock(&db_mutex);
    return K_SUCCESS;
}

int insertMysql(const char *query)
{
    int ret;
    pthread_mutex_lock(&db_mutex);
    // query 실행. 성공시 0을 리턴함
    if((ret = mysql_real_query(&mysql, query, (unsigned)strlen(query)) != 0))
    {
        DebugLog((DEB_ERROR, "[%s.%d][mysql_real_query] error(%s)(%d) \n", __FILE__, __LINE__,
            mysql_error(&mysql), mysql_errno(&mysql)));
        reconnectMysql();
        pthread_mutex_unlock(&db_mutex);
        return K_FAIL;
    }
    else
    {
        DebugLog((DEB_DEBUG, "QUERY[%s] \n", query));
    }
    pthread_mutex_unlock(&db_mutex);
    return K_SUCCESS;
}
익명 사용자의 이미지

스레드마다 별도의 mysql 객체를 만들어서 사용하세요.

익명 사용자의 이미지

innodb 에 트랜잭션으로 하는게 효율이 더 좋을것 같네요.

lock 걸려도 select 가 되지요.
select 랑은 상관 없는게 맞을겁니다.

progcom의 이미지

SQL LOCK이 아니라 프로그램 상에서의 쓰레드 뮤텍스 락이군요.

mysql 접속을 하나만 사용한다면, 모든 쿼리에 대해서 락 해야 하는게 맞습니다.
접속 리소스는 한번에 하나만 처리할 수 있으므로, 당연히 SELECT 쿼리에 대해서도 락을 걸어야합니다.

물론, 락을 거는것으로 인한 차이는 존재합니다. 걸지 않으면... 데이터가 어떻게 될지 모르지요.

락이 풀리지 않고 리턴 되면... 쓰레드의 다음 처리가 막히겠지요. 프로그램이 죽었다 살아나는건 문제가 없습니다.

멀티 쓰레드 프로그램이라면, DB 풀을 만들어서 활용하던지, SELECT용 접속과 INSERT/UPDATE/DELETE용 접속을 구분해서 처리하는 것이 구현하기 편합니다.

중요한건 mysql 접속 구조체 (쿼리에 &mysql로 넘기는 걸 말합니다)가 동시에 사용되지 않도록 하는 일입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.