bulk insert시 commit/update에서 지연이 발생합니다. 0 0 2,274

by 아직은초보 [MySQL] bulk insert. 지연 lock [2021.03.11 13:19:29]


안녕하세요.

mariadb를 이용해서 한창 데이터베이스를 배우고 있는 초짜입니다.

파이썬으로 웹페이지 크롤링을 연습하고 있는데요.

뜬금없이 데이터베이스 처리에서 막혀서 진도가 안나가고 있습니다.

이에 질문드려봅니다.

[현상]

전부 bulk insert로 데이터를 넣고 있습니다.

상대적으로 데이터량이 작은 키워드 테이블은 막힘없이 들어가고 있구요.

주소테이블까지도 쿼리길이 기준으로 300,000자정도의 크기인데 잘 들어가고 있습니다.

문제는 내용 테이블인데요. 4스레드로 파이썬에서 밀어넣으면 update/commit단계에서

짧게는 10초 길게는 1000초정도까지 지연이 생깁니다.

[테이블의 구조]

키워드 테이블의 구조

IDX : bigint 프라이머리 키

KEYWORD : varchar(255) 키워드가 들어갑니다. 유니크 키

PROC_URL : tinyint 해당 키워드에 대한 작업이 되었는지 판별 (0:작업전/1:주소수집완료)

주소 테이블의 구조

IDX : bigint 프라이머리 키

URL : varchar(255) 크롤링할 주소가 들어갑니다.

TITLE : varchar(255) 게시물의 제목이 들어갑니다. full-text 엔진

PROC : 해당 URL의 내용을 가져왔는지 판별 (0:작업전/1:내용수집완료)

내용 테이블의 구조

IDX : bigint 프라이머리 키

내용 : midtext 본문의 내용이 들어갑니다. full-text 엔진

혹시 관계성 검증때문에 lock이 생긴게 아닌가하여,

각 테이블간에 foreign키는 전부 생략해놓은 상태입니다.

[자세한 설명]

일 처리 단계는 다음과 같습니다.

1. 키워드 프로그램

파이썬에서 키워드 수집 -> php의 insert.php 호출 -> mariadb에서 처리

한번에 삽입되는 쿼리의 양은 쿼리문기준으로 100,000글자 미만입니다.

2. 주소수집프로그램

keylist.php(키워드테이블 PROC=0인것들 IDX기준 ASC)에서 10개씩 불러옴

-> 파이썬에서 작업완료 -> php의 keyinsert.php 호출 -> mariadb에서 처리

한번에 삽입되는 쿼리의 양은 쿼리문기준으로 100,000글자 미만입니다.

3. 내용수집프로그램

urllist.php(주소테이블 PROC=0인것들 IDX기준 ASC)에서 10개씩 불러옴

-> 파이썬에서 작업완료 -> php의 urlinsert.php 호출 -> mariadb에서 처리

한번에 삽입되는 쿼리의 양은 쿼리문기준으로 1,000,000글자 미만입니다.

이런 과정입니다.

1, 2, 3번의 파이썬 프로그램이 실시간으로 계속 돌고 있는 상태입니다. (프로그램당 4쓰레드)

[insert 쿼리문]

1. 키워드 프로그램

INSERT IGNORE INTO KEYWORD_0 (KEYWORD_KEYWORD, KEYWORD_DATE, KEYWORD_SITE, KEYWORD_HIGH) VALUES (),(),(), ... 10개

2. 주소 프로그램

INSERT INTO URL_0 (URL_TITLE, URL_LINK, URL_DATE, URL_REF_IDX, URL_HIGH) VALUES (),(),()...

UPDATE KEYWORD_0 SET KEYWORD_PROC_URL='1' WHERE KEYWORD_IDX IN (1,2,3,4,5,6,7,...) // 작업이 완료되었다는 표시

UPDATE KEYWORD_0 SET KEYWORD_DEL='1' WHERE KEYWORD_IDX IN (1,2,3,4,5,6,7,...) // 관련 주소가 없는 경우 표시

3. 본문 프로그램

INSERT INTO PAGE_0(PAGE_CONTENT, PAGE_IMG, PAGE_SUBKEYWORD, PAGE_DATE, PAGE_REF_IDX) VALUES (), (), (), ... 10개

UPDATE URL_0 SET URL_PROC=1 WHERE URL_IDX IN (1,2,3,4,5,6,7,8,9,10) // 작업이 완료되었다는 표시

UPDATE URL_0 SET URL_DEL=1 WHERE URL_IDX IN (1,2,3,...) // 해당 주소에 본문이 없다면 표시

[my.cnf]

[client-server]

# Import all .cnf files from configuration directory

!includedir /etc/mysql/conf.d/

!includedir /etc/mysql/mariadb.conf.d/

[mysqld]

datadir = /database/mysql

socket = /var/run/mysqld/mysqld.sock

pid-file = /var/run/mysqld/mydqld.pid

max_connection = 100

#innodb_thread_concurrency = 0

#innodb_read_io_threads = 64

#innodb_write_io_threads = 64

#innodb_adaptive_hash_index = ON

#connect_timeout = 900

#wait_timeout = 7200

max_allowed_packet = 16M

#thread_stack = 256K

#thread_cache_size = 128

sort_buffer_size = 256K

join_buffer_size = 256K

read_buffer_size = 256K

#read_md_buffer_size = 256K

#net_buffer_length = 16K

#bulk_insert_buffer_size = 4000M // innodb라서 필요가 없는듯 해요.

tmp_table_size = 1M

max_heap_table_size = 32M

#max_open_files = 40000

#wait_timeout = 30

query_cache_size = 0

query_cache_type = OFF

query_cache_limit = 2M

#open_files_limit = 65535

innodb_flush_log_at_trx_commit = 0

innodb_buffer_pool_size = 8000M

innodb_buffer_pool_instances = 4

innodb_autoinc_lock_mode = 1

innodb_log_file_size = 256M

innodb_log_buffer_size = 8M

innodb_flush_method = O_DIRECT

#table_definition_cache = 4000

#table_open_cache = 40000

#open_files_limit = 120000

#binlog_cache_size = 16M

#max_binlog_size = 128M

#innodb_lock_wait_timeout = 10

#innodb_additional_mem_pool_size = 2M

#innodb_log_file_size

#skip-grant-tables

#symbolic-links=0

#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

slow_query_log = 1

slow_query_log_file = /database/log/slow_query.log

long_query_time = 3

#autocommit = on

transaction_isolation = 'READ-COMMITTED'

#performance_schema = 1

innodb_locks_unsafe_for_binlog = on

[지연될때 트랜잭션 정보]

----------

SEMAPHORES

----------

OS WAIT ARRAY INFO: reservation count 19004

--Thread 140032845915904 has waited at fts0fts.cc line 4850 for 34.00 seconds the semaphore:

X-lock on RW-latch at 0x556d6cf6bdd8 created in file fts0fts.cc line 617

a writer (thread id 140032511084288) has reserved it in mode exclusive

number of readers 0, waiters flag 1, lock_word: 0

Last time write locked in file fts0fts.cc line 4850

--Thread 140032510777088 has waited at fts0fts.cc line 4850 for 34.00 seconds the semaphore:

X-lock on RW-latch at 0x556d6cf6bdd8 created in file fts0fts.cc line 617

a writer (thread id 140032511084288) has reserved it in mode exclusive

number of readers 0, waiters flag 1, lock_word: 0

Last time write locked in file fts0fts.cc line 4850

--Thread 140032845608704 has waited at fts0fts.cc line 4850 for 35.00 seconds the semaphore:

X-lock on RW-latch at 0x556d6cf6bdd8 created in file fts0fts.cc line 617

a writer (thread id 140032511084288) has reserved it in mode exclusive

number of readers 0, waiters flag 1, lock_word: 0

Last time write locked in file fts0fts.cc line 4850

OS WAIT ARRAY INFO: signal count 17555

RW-shared spins 13013, rounds 388535, OS waits 12823

RW-excl spins 693, rounds 20972, OS waits 690

RW-sx spins 1253, rounds 36857, OS waits 1173

Spin rounds per wait: 29.86 RW-shared, 30.26 RW-excl, 29.42 RW-sx

------------

TRANSACTIONS

------------

Trx id counter 9792189

Purge done for trx's n:o < 9792180 undo n:o < 0 state: running

History list length 27

LIST OF TRANSACTIONS FOR EACH SESSION:

---TRANSACTION 421507487839432, not started

0 lock struct(s), heap size 1128, 0 row lock(s)

---TRANSACTION 9792188, ACTIVE 34 sec inserting

mysql tables in use 1, locked 1

0 lock struct(s), heap size 1128, 0 row lock(s)

MySQL thread id 55, OS thread handle 140032510777088, query id 121 localhost root Update

INSERT INTO PAGE_0(... 중략)

---TRANSACTION 9792187, ACTIVE 34 sec inserting

mysql tables in use 1, locked 1

0 lock struct(s), heap size 1128, 0 row lock(s)

MySQL thread id 54, OS thread handle 140032845915904, query id 120 localhost root Update

INSERT INTO PAGE_0(... 중략)

---TRANSACTION 9792186, ACTIVE 35 sec inserting

mysql tables in use 1, locked 1

0 lock struct(s), heap size 1128, 0 row lock(s)

MySQL thread id 53, OS thread handle 140032845608704, query id 119 localhost root Update

INSERT INTO PAGE_0(...중략)

---TRANSACTION 9792185, ACTIVE 35 sec fetching indexed FTS document

0 lock struct(s), heap size 1128, 0 row lock(s)

Trx read view will not see trx with id >= 9792186, sees < 9792170

---TRANSACTION 9792182, ACTIVE 35 sec inserting

mysql tables in use 1, locked 1

0 lock struct(s), heap size 1128, 0 row lock(s)

MySQL thread id 52, OS thread handle 140032511084288, query id 118 localhost root Update

INSERT INTO PAGE_0((..중략)

---TRANSACTION 421507487822568, not started

0 lock struct(s), heap size 1128, 0 row lock(s)

---TRANSACTION 9792174, ACTIVE 1143 sec recovered trx

ROLLING BACK 1 lock struct(s), heap size 1128, 0 row lock(s), undo log entries 980262

---TRANSACTION 9792171, ACTIVE 1143 sec recovered trx

1 lock struct(s), heap size 1128, 0 row lock(s), undo log entries 10

---TRANSACTION 9792170, ACTIVE 1143 sec recovered trx

1 lock struct(s), heap size 1128, 0 row lock(s), undo log entries 10

장문의 글 읽어주셔서 감사드리구요.

부디 초보가 힘을 얻을수 있도록 도움 부탁드립니다.

감사합니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입