>  기사  >  데이터 베이스  >  MySQL 데이터베이스는 분석을 실행하여 정보를 수집합니다.

MySQL 데이터베이스는 분석을 실행하여 정보를 수집합니다.

coldplay.xixi
coldplay.xixi앞으로
2020-11-19 17:08:083235검색

MySQL tutorial 컬럼은 분석을 실행하여 정보를 수집합니다.

MySQL 데이터베이스는 분석을 실행하여 정보를 수집합니다.

오류 소개

이전 개발자가 찾아와서 애플리케이션의 특정 기능에 대한 쿼리가 이전보다 훨씬 느려졌다고 개발자에게 느린 SQL문을 제공해달라고 요청하고 갔습니다. 실행 계획이 잘못된 것으로 확인되면 해당 MySQL 데이터베이스에서 첫 번째 반응은 테이블 중 하나의 통계 정보가 정확하지 않아 SQL 문의 실행 계획이 잘못되었다는 것입니다. 효율적인 쿼리 SQL에서 느린 SQL로. 문제를 찾은 후 다시 정보를 분석하고 수집하는 것이 당연했는데, 이때 분석 테이블의 모든 선택 사항이 갑자기 중단되고 어떤 결과도 반환되지 않는 것을 발견했습니다. 그러다가 다양한 경고 메시지와 함께 애플리케이션이 폭발했습니다.

Fault review

분석 작업은 슬레이브 라이브러리에서 수행되었으며 영향을 받은 것은 기본적으로 선택 쿼리이므로 여기서 시뮬레이션한 것은 쿼리 작업입니다.

시뮬레이션 테이블 만들기

mysql> select * from t_test_1;
+----+--------+-------+--------+
| id | name   | name2 | status |
+----+--------+-------+--------+
|  1 | name1  | 1001  |      0 |
|  2 | name1  | 1002  |      1 |
|  3 | name1  | 1003  |      1 |
|  4 | name1  | 1004  |      0 |
|  5 | name1  | 1005  |      1 |
|  6 | name1  | 1006  |      0 |
|  7 | name1  | 1007  |      2 |
|  8 | name1  | 1008  |      0 |
|  9 | name1  | 1009  |      1 |
| 10 | name10 | 1001  |      0 |
+----+--------+-------+--------+
10 rows in set (0.00 sec)复制代码

느린 쿼리를 시뮬레이션합니다. 여기에는 데이터 양이 충분하지 않아 대신 sleep을 사용합니다. session1: 느린 쿼리 시뮬레이션

mysql> select sleep(1000) from t_test_1;复制代码

session2: 테이블 통계 수집 시뮬레이션

mysql> analyze table t_test_1;复制代码

session3: 분석 명령 실행 시뮬레이션 및 t_test_1 테이블에 대한 선택 쿼리 실행

mysql> select * from t_test_1 where id=5;复制代码

session4: session4에서 얻은 모든 세션 정보 쿼리

mysql> select * from processlist order by time desc;
+----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+
| ID | USER | HOST      | DB                 | COMMAND | TIME | STATE                   | INFO                                         |
+----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+
| 21 | root | localhost | testdb             | Query   |  242 | User sleep              | select sleep(1000) from t_test_1             |
| 23 | root | localhost | testdb             | Query   |  180 | Waiting for table flush | analyze table t_test_1                       |
| 24 | root | localhost | testdb             | Query   |    3 | Waiting for table flush | select * from t_test_1 where id=5            |
| 22 | root | localhost | information_schema | Query   |    0 | executing               | select * from processlist order by time desc |
+----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+
4 rows in set (0.00 sec)复制代码

그중에서 세션 정보를 보면 2개 세션의 상태가 "Waiting for table Flush"임을 알 수 있습니다.

테이블 플러시 이유를 기다리는 중

MySQL 데이터베이스가 FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE 또는 OPTIMIZE TABLE과 같은 작업을 수행하면 메모리에서 테이블을 닫고 테이블을 다시 엽니다. 새 테이블 구조를 메모리에 로드합니다. 그러나 테이블을 닫으려면 테이블의 모든 작업(선택, 삽입, 업데이트, 테이블 잠금 등 포함)이 끝날 때까지 기다려야 하므로 특히 느린 선택이 실행되는 경우 테이블 분석 명령이 종료되지 않습니다.

Solution

이제 테이블 플러시 대기의 원인을 알았으므로 느린 SQL 문을 찾기 시작합니다. 여기서 우리가 실행 중인 것은 t_test_1 테이블을 수집하는 것이므로 t_test_1 테이블과 관련된 느린 쿼리를 쿼리해야 하며 실행 시간은 분석 테이블 t_test_1의 실행 시간보다 길다는 것을 알 수 있습니다.

mysql> select * from processlist where info like '%t_test_1%' and time >=(select time from processlist where id=23)  order by time desc;
+----+------+-----------+--------+---------+------+-------------------------+----------------------------------+
| ID | USER | HOST      | DB     | COMMAND | TIME | STATE                   | INFO                             |
+----+------+-----------+--------+---------+------+-------------------------+----------------------------------+
| 21 | root | localhost | testdb | Query   | 1187 | User sleep              | select sleep(1000) from t_test_1 |
| 23 | root | localhost | testdb | Query   | 1125 | Waiting for table flush | analyze table t_test_1           |
+----+------+-----------+--------+---------+------+-------------------------+----------------------------------+
2 rows in set (0.37 sec)复制代码

위의 SQL 문을 사용하면 id=21인 세션을 쉽게 찾을 수 있으며 이로 인해 분석 테이블 t_test_1이 중단되므로 세션 21을 종료해야 합니다.

mysql> kill 21;
Query OK, 0 rows affected (0.01 sec)

mysql> show full processlist;
+----+------+-----------+--------------------+---------+------+----------+-----------------------+
| Id | User | Host      | db                 | Command | Time | State    | Info                  |
+----+------+-----------+--------------------+---------+------+----------+-----------------------+
| 22 | root | localhost | information_schema | Query   |    0 | starting | show full processlist |
| 23 | root | localhost | testdb             | Sleep   | 1205 |          | NULL                  |
| 24 | root | localhost | testdb             | Sleep   | 1028 |          | NULL                  |
+----+------+-----------+--------------------+---------+------+----------+-----------------------+
3 rows in set (0.00 sec)复制代码

세션을 종료하면 오류가 해결됩니다. .

Suggestions

생산 실행 분석 테이블 제안 1. 실행 전 테이블의 데이터 양을 추정하고 경험에 따라 필요한 시간을 추정하는 동시에 정보 테이블을 수집하는 SQL이 느리고 긴 트랜잭션이 실행되고 있는지 확인합니다.

2. 업무량이 많은 기간에는 통계 정보 수집을 위해 분석 테이블을 실행하지 마세요.

더 많은 관련 무료 학습 권장사항: mysql 튜토리얼(동영상)

위 내용은 MySQL 데이터베이스는 분석을 실행하여 정보를 수집합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제