El porcentaje útil de E/S del disco es extremadamente alto

1. Antecedentes Introducción
Como DBA, es inevitable que nos encontremos con problemas de rendimiento, entonces, ¿cómo debemos solucionar los problemas de rendimiento?

Por ejemplo, en nuestro negocio de alta concurrencia, si la respuesta del negocio es lenta y el tiempo de procesamiento es largo, ¿cómo debemos comenzar a investigar?

Este artículo analizará cómo analizar y localizar cuando el io es alto.

2.
Configuración del entorno de reproducción del entorno: esta prueba utiliza la configuración del servidor 128C_512G_4TSSD, la versión de MySQL es 8.0.27

Simulación de escenarios: use sysbench para crear 5 tablas con 200 millones de registros de datos en cada tabla, ejecute instrucciones SQL que generen consultas de productos cartesianos, genere io y simule la presión empresarial. Sysbench de primer uso para la medición de presión de datos

3. Solución de problemas de bajo nivel a nivel del sistema
Shell> sysbench --test=/usr/local/share/sysbench/oltp_insert.lua --mysql-host=XXX --mysql-port=3306 --mysql-user=pcms --mysql -password=abc123 --mysql-db=sysbench --percentile=99 --table-size=2000000000 --tables=5 --threads=1000 prepare
Use sysbench para simular alta concurrencia

shell> sysbench --test=/usr/local/share/sysbench/oltp_write_only.lua --mysql-host=xxx --mysql-port=3306 --mysql-user=pcms --mysql-password=abc123 --mysql -db=sysbench --percentile=99 --table-size=2000000000 --tables=5 --threads=1000 --max-time=60000 --report-interval=1 --threads=1000 --max-requests =0 --mysql-ignore-errors=todos se
ejecutan

mysql> seleccione SQL_NO_CACHE b.id,ak de sbtest_a a izquierda únase a sbtest_b b en a.id=b.id grupo por orden de ak por bc desc;
3.1 Verifique el estado actual del servidor
shell> top
top - 19:49:05 hasta 10 días , 8:16, 2 usuarios, promedio de carga: 72,56, 40,21, 17,08
Tareas: 1288 en total, 1 en ejecución, 586 en reposo, 0 detenido, 0 zombi
%Cpu(s): 19,7 us, 4,2 sy, 0,0 ni, 75,9 id, 1.0 wa, 0.0 hi, 0.2 si, 0.0 st
KiB Mem: 53542118+total, 23667507+free, 22735366+used, 71392448 buff/cache
KiB Swap: 0 total, 0 free, 0 used
. lo anterior: la carga actual de un minuto es 72.56, y está en aumento, y hay presión io

3.2 Ver el estado actual de io de cada dispositivo de disco
shell> iostat -m -x 1
Linux 4.14.0-115.el7a.0.1.aarch64 (mysql-4) 08/01/2022 _aarch64_ (128 CPU)
Dispositivo: rrqm/s wrqm /s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0,00 0,00 14213,00 27430,00 222,08 465,15 33,80 5,39 0,13 0,14 0.12 0.02 86.00
sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0,00 0,00 0,00
dm-0 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 dm-1 0,00 0,00 0,00 0,00 0,00 0,00 0 .00 0.0 0 0.00 0.00 0.00 0.00
0.00
dm-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Se
puede ver en lo anterior: actualmente hay varios discos físicos, y la presión io del disco sda es relativamente alta

3.3 Comprobar el estado actual de lectura y escritura de io de la
carcasa del disco sda > iostat -d /dev/sda -m -x 1
Linux 4.14.0-115.el7a.0.1.aarch64 (mysql-4) 08/01/ 2022 _aarch64_ (128 CPU)
Dispositivo: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0,00 0,17 7,86 81,23 0,29 3,96 97,8 8 0,23 2,53 0,22 2,76 0,04 0,33 Dispositivo: rrqm
/
s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0,00 0,00 21109,00 42839,00 329,81 710,90 33,33 19,47 0,30 0,16 0,37 0,02 96,00 Dispositivo: rrqm/s wrqm
/
s r/s w/ s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.00 19287.00 41404.00 301.36 692.29 33.53 15.73 0.26 0.18 0.30 0.02 93.00
Dispositivo: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz a vgqu-sz espera r_await w_await svctm %util sda 0.00 0.00 22135.00 43044.00
345.86 1165,18 47,48 100,87 1,55 0,20 2,24 0,01 97,00
Se puede ver en lo anterior: la presión actual en el disco sda es relativamente alta, y la brecha entre la escritura por segundo y la lectura por segundo es grande, lo que demuestra que actualmente hay un gran cantidad de escrituras IO

3.4 Comprobar qué aplicación en el disco sda ocupa el
shell io más alto > pidstat -d 1
Linux 4.14.0-115.el7a.0.1.aarch64 (mysql-4) 08/01/2022 _aarch64_ (128 CPU)
08:01 : 43 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Comando
08:01:44 PM 1000 73739 62018.35 171346.79 0.00 mysqld
08:01:44 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Comando
08:0 1:45 PM 1000 73739 145328.00 435216.00 0.00 mysqld
08:01:45 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Comando 08:01:46
PM 1000 73739 141488.00 433232.00 0.0 0 mysqld
Se puede ver en lo anterior: el programa de aplicación que ocupa alto IO es mysql, y el pid es 73739

3.5 Analizar qué subproceso en el programa de aplicación ocupa un io relativamente alto
d
11 : 11:56:17 PM 1000 - 74770 124603.77 73358.49 0.00 __mysqld Promedio: 1000 - 74770 1247 61.17 74003.88 0.00 |__mys qld Se puede ver en lo anterior: 74770 esto hilo ocupa un io relativamente alto




3.6 ¿Analizar qué está haciendo este hilo?
Shell> perf trace -t 74770 -o /tmp/tmp_aa.pstrace
Shell> cat /tmp/tmp_aa.pstrace
  2850.656 ( 1.915 ms): futex(uaddr: 0x653ae9c4, op: WAIT|PRIVATE_FLAG, val: 1) = 0
  2852.572 ( 0,001 ms): futex(uaddr: 0x653ae990, op: WAKE|PRIVATE_FLAG, val: 1) = 0 2852,601 (0,001
  ms): clock_gettime(cual_reloj: MONOTÓNICO, tp: 0xfff7bd470f68) = 0
  2852,690 (0,040 ms): write(f re: 159, buf: 0xd7a30020, recuento: 65536) = 65536
  2852,796 (0,001 ms): clock_gettime (cual_reloj: MONOTONIC, tp: 0xfff7bd470f68) = 0 2852,798 (0,001 ms):
  clock_get time (cual_reloj: MONOTO NIC, tp: 0xfff7bd470f58) = 0
  2852,939 ( 0,001 ms): clock_gettime(cual_reloj: MONOTÓNICO, tp: 0xfff7bd470f38) = 0
  2852,950 ( 0,001 ms): clock_gettime(cual_reloj: MONOTÓNICO, tp: 0xfff7bd470f68) = 0 2 852,977 ( 0. 001 ms) :
  clock_gettime(cual_reloj: MONOTÓNICO, tp : 0xfff7bd470f68) = 0
  2853.029 ( 0.035 ms): escritura (fd: 64, buf: 0xcd51e020, cuenta: 65536) = 65536
  2853.164 ( 0.001 ms): clock_gettime (cual_reloj: MONOTÓNICO, t p: 0xfff7bd4 70f68) = 0
  2853,167 (0,001 ms) : clock_gettime(cual_reloj: MONOTÓNICO, tp: 0xfff7bd470f58) = 0
  2853.302 ( 0.001 ms): clock_gettime(cual_reloj: MONOTÓNICO, tp: 0xfff7bd470f38) =
0 Los números de identificador son 64, 159

3.7 Compruebe cuál es el identificador de este archivo
shell> lsof -p 73739|grep 159u
mysqld 73739 mysql 159u REG 8,0 212143246 7046482357 /mysql/mysqldata/16320fff-5fd5-4c47-889a-a9e1a8591 d0d/tmp /#7046482357 (eliminado) [
raíz @mysql-4 ~]# lsof -p 73739|grep 64u
mysqld 73739 mysql 64u REG 8,0 211872724 6979323031 /mysql/mysqldata/16320fff-5fd5-4c47-889a-a9e1a8591d0d/ tmp/#697 9323031 (eliminado) Puede
ser visto desde arriba: este hilo está escribiendo mucho en archivos temporales

4. Análisis de aplicaciones MySQL
4.1 Ver la lista de sesión actual
mysql> select * from information_schema.processlist where command !='sleep';
| 9 | pcms | 172.16.76.12:57596 | sysbench | Query | 67 | executing | select SQL_NO_CACHE b . id,ak de sbtest_a a izquierda unirse a sbtest_b b en a.id=b.id agrupar por ak ordenar por bc desc | 66477 | 0 | 0 | Se puede
ver en lo anterior: el SQL actual se ha ejecutado durante 67 s, y este SQL usa group by y order by inevitablemente generará io

4.2 通过线程号查询会话
mysql> seleccionar * de hilos donde thread_os_id=74770\G;
*************************** 1. fila ******************** *******
          THREAD_ID: 95
               NOMBRE: thread/sql/one_connection
               TIPO: FOREGROUND
     PROCESSLIST_ID: 9
   PROCESSLIST_USER: pcms
   PROCESSLIST_HOST: 172.16.76.12
     PROCESSLIST_DB: sysbench
PROCESSLIST_COMMAND: consulta
   PROCESSLIST_TIME: 91
  PROCESSLIST_STATE: NULL
   PROCESSLIST_INFO: seleccionar SQL_NO_CACHE b.id ,ak de sbtest_a a unión izquierda sbtest_b b en a.id=b.id agrupar por ak ordenar por bc desc
   PARENT_THREAD_ID: 1
               ROL: NULO
       INSTRUMENTADO: SÍ
            HISTORIAL: SÍ
    TIPO DE CONEXIÓN: TCP/IP
       THREAD_OS_ID: 74770
     GRUPO DE RECURSO: USR_predeterminado
1 fila en conjunto (0,00 segundos)
Se puede ver en lo anterior que se puede verificar consultando la tabla de subprocesos. La razón por la que este subproceso crea con frecuencia tablas temporales viene de este sql

4.3 Ver el plan de ejecución de la instrucción sql para una mayor autenticación
mysql> explicar seleccionar SQL_NO_CACHE b.id,ak de sbtest_a a izquierda unirse a sbtest_b b en a.id=b.id agrupar por ak ordenar por bc desc\G;
*** ************************ 1. fila ************************ *** ****
           id: 1
  select_type: tabla SIMPLE
        : a
   particiones:
         tipo NULL: TODAS
las claves_posibles:
          clave NULL: NULL
      key_len: NULL
          ref: NULL
         filas: 1
     filtrado: 100.00
        Extra: usando temporal; usando filesort
*** * ********************* 2. fila ************************* ** *
           id: 1
  select_type: tabla SIMPLE
        : b
   particiones: NULL
         tipo: eq_ref
posibles_claves: PRIMARIA
          clave: PRIMARIA
      key_len: 4
          ref: sysbench.a.id
         filas: 1
     filtrado: 100.00
        Extra: NULL
2 filas en conjunto, 2 advertencias (0.00 seg) Se
puede ver en lo anterior: la ejecución del sql El plan utiliza tablas temporales y archivos temporales, que se ajustan a

4.4 Ver el estado global para confirmación adicional
mysql> mostrar el estado global como '%tmp%';
+-------------------------+-- - ---+
| Nombre_variable | Valor |
+-------------------------+-------+
| Tablas_disco_tmp_creadas | 3 |
| Created_tmp_files | 22 |
| Created_tmp_tables | 8 |
+-------------------------+-------+
Ejecutar varias veces, usted Se puede ver que los valores de tmp_files y tmp_disk_tables están aumentando, lo que demuestra que la creación de una gran cantidad de archivos temporales y tablas temporales de disco se ajusta al comportamiento de este hilo.

5. Solución de problemas
A través de la serie de investigaciones mencionada anteriormente, hemos analizado que: en la actualidad, la tasa de uso de io del disco sda ​​es la más alta, y el programa mysqld ocupa la mayor parte.

Al comprobar que hay un subproceso que con frecuencia crea tablas temporales o archivos temporales, y al iniciar sesión en mysql para verificar la sesión y la vista del subproceso, se puede encontrar que es causado por un cierto SQL lento.

Verificar el plan de ejecución de este SQL lento también creará tablas temporales y archivos temporales, lo cual está en línea con nuestras expectativas de investigación previa.

En este punto, necesitamos optimizar este SQL lento. El DBA maneja el paso de optimización, que se ignora aquí.

Una vez completada la optimización lenta de sql, puede continuar observando el io para ver si el io ha disminuido.

6. Análisis de código
Podemos usar pstack para rastrear el número de subprocesos y obtener la información actual de la pila de subprocesos. Recuerde que pstack llamará a gdb para la depuración de errores

shell> pstack 74770 >/tmp/74770.pstack
Hilo 1 (proceso 74770):
#0 ha_innobase::general_fetch (this=0xea654228, buf=0xea662028 "\212t\317\030\002", direction=1, match_mode=0 ) en /builds/naiwei.fang/percona-server/storage/innobase/handler/ha_innodb.cc:11159
#1 0x0000000000d9913c en handler::ha_rnd_next (this=0xea654228, buf=0xea662028 "\212t\317\030\002 " ) en /build
s/naiwei.fang/percona-server/sql/handler.cc:3173
#2 0x0000000000f77db0 en TableScanIterator::Read (this=0xd256d5e8) en /builds/naiwei.fang/percona-server/sql/row_iterator
. h:208
#3 0x000000000124c714 en WriteRowsToChunks (xxhash_seed=899339, write_to_build_chunk=true, write_rows_with_nu
LL_IN_JOIN_KEY = FALSE, Join_Key_Buffer = 0xd01fdb98, Tables_To_Get_rowid_For = 0, Chunks = 0xd01fdb58, Join_Condition
s = ..., Tablas = ..., iterator = 0xd256d5e8, thD = 0xdb88000) /SQL /hash_join_it
erator.cc:282
#4 HashJoinIterator::BuildHashTable (this=this@entry=0xd01fd028) en /builds/naiwei.fang/percona-server/sql/ha
sh_join_iterator.cc:495
#5 0x000000000124c8ac en Init (this= 0xd01fd028) en /builds/naiwei.fang/percona-server/sql/hash_join_iterator.
cc:203
#6 HashJoinIterator::Init (this=0xd01fd028) en /builds/naiwei.fang/percona-server/sql/hash_join_iterator.cc:1
45
#7 0x00000000010eca14 en Query_expression::ExecuteIteratorQuery (this=0xdec3a8b8, thd=thd @entrada=0xdb888000) una
t /builds/naiwei.fang/percona-server/sql/sql_union.cc:1224
#8 0x00000000010ecccc en Query_expression::execute (this=this@entry=0xdec3a8b8, thd=thd@entry=0xdb888000) en 
/builds/naiwei. fang/percona-server/sql/sql_union.cc:1284
#9 0x0000000001083db0 en Sql_cmd_dml::execute_inner (this=0xd256bcb0, thd=0xdb888000) en /builds/naiwei.fang/percona-server/sql/sql_select. CC
: 791
# 10 0x000000000108cac8 en Sql_cmd_dml::execute (this=0xd256bcb0, thd=0xdb888000) en /builds/naiwei.fang/percon
a-server/sql/sql_select.cc:575
#11 0x00000000010384e8 en mi sql_execute_command (thd=thd@entry=0xdb888000, primer_nivel=primer_nivel@entrada=verdadero)
 en /builds/naiwei.fang/percona-server/sql/sql_parse.cc:4677
#12 0x000000000103b314 en dispatch_sql_command (thd=thd@entry=0xdb888000, parser_state=parser_state@entry=0xff
f7bd4735b0, update_userstat=update_userstat@entry=false) en /builds/naiwei.fang/percona-server/sql/sq
l_parse.c c: 5273
#13 0x000000000103ccf0 en dispatch_command (thd=thd@entry=0xdb888000, com_data=0xffffb467c4d0, com_data@entry=
0xfff7bd474640, command=COM_QUERY) en /builds/naiwei.fang/percona-server/sq l/sql_parse.cc:1938
#14 0x000000000103da40 en do_command (thd=thd@entry=0xdb888000) en /builds/naiwei.fang/percona-server/sql/sql_
parse.cc:1386
#15 0x0000000001152ca8 en handle_connection (arg=arg@entry=0xda53 ab10) en /construcciones/ naiwei.fang/percona-server/s
ql/conn_handler/connection_handler_per_thread.cc:307
#16 0x00000000022bc3ec en pfs_spawn_thread (arg=<optimizado>) en /builds/naiwei.fang/percona-server/storage
/perfschema/pfs.cc:2899
#17 0x0000ffffb43c7c48 en start_thread () desde /lib64/libpthread.so.0
#18 0x0000ffffb3c0f600 en thread_start () de /lib64/libc.so.6
Disfrute de GreatSQL :)

Supongo que te gusta

Origin blog.csdn.net/eagle89/article/details/129687922
Recomendado
Clasificación