c++ - una - view lenta mysql
Cómo acceder a MySQL desde múltiples hilos simultáneamente (4)
Como mantenedor de una aplicación de C bastante grande que realiza llamadas a MySQL desde varios subprocesos, puedo decir que no he tenido problemas simplemente con hacer una nueva conexión en cada subproceso. Algunas advertencias que he encontrado:
- Edición: parece que esta viñeta solo se aplica a las versiones <5.5; vea esta página para su versión apropiada : como dice que ya está haciendo, enlace contra
libmysqlclient_r
. - Llame a
mysql_library_init()
(una vez, desdemain()
). Lea la documentación sobre el uso en entornos multiproceso para ver por qué es necesario. - Crea una nueva estructura
MYSQL
usandomysql_init()
en cada hilo. Esto tiene el efecto secundario de llamar amysql_thread_init()
por ti.mysql_real_connect()
como es habitual dentro de cada hilo, con su estructura MYSQL específica del hilo. - Si está creando / destruyendo muchos subprocesos, querrá usar
mysql_thread_end()
al final de cada subproceso (ymysql_library_end()
al final demain()
). Es una buena práctica de todos modos.
Básicamente, no comparta las estructuras MYSQL
o cualquier cosa creada específicamente para esa estructura (es decir, MYSQL_STMT
s) y funcionará como espera.
Esto parece menos trabajo que hacer un grupo de conexiones para mí.
Estamos haciendo un pequeño punto de referencia de MySQL en el que queremos ver cómo funciona para nuestros datos.
Parte de esa prueba es ver cómo funciona cuando varios subprocesos concurrentes impiden que el servidor realice varias consultas.
La documentación de MySQL (5.0) no es realmente clara acerca de los clientes de múltiples subprocesos. Debo señalar que vinculo con la biblioteca segura de subprocesos ( libmysqlclient_r.so
)
Estoy usando declaraciones preparadas y hago tanto leer (SELECCIONAR) como escribir (ACTUALIZAR, INSERTAR, ELIMINAR).
- ¿Debo abrir una conexión por hilo? Y si es así: ¿cómo puedo hacer esto? Parece que
mysql_real_connect()
devuelve el identificador de DB original que obtuve cuando llamé amysql_init()
) - Si no es así, ¿cómo me aseguro de que los resultados y los métodos como
mysql_affected_rows
devuelvan el valor correcto en lugar de chocar con las llamadas de otros subprocesos (la exclusión / los bloqueos podrían funcionar, pero se siente mal)
Me parece claro a partir de mySQL Docs que cualquier estructura MYSQL específica se puede usar en un subproceso sin dificultad: usar la misma estructura MYSQL en diferentes subprocesos simultáneamente le dará resultados extremadamente impredecibles a medida que el estado se almacena dentro de la conexión MYSQL.
Por lo tanto, cree una conexión por subproceso o use un conjunto de conexiones como se sugiere anteriormente y proteja el acceso a ese conjunto (es decir, reserve o libere una conexión) utilizando algún tipo de Mutex.
Podrías crear un grupo de conexiones. Cada subproceso que necesita una conexión podría solicitar uno gratuito del grupo. Si no hay conexión disponible, puede bloquear o aumentar el grupo agregándole una nueva conexión.
Aquí hay un artículo que describe las ventajas y desventajas de un grupo de conexiones (aunque está basado en Java)
Edición: Aquí hay una pregunta / respuesta SO sobre grupos de conexiones en C
Edit2: Aquí hay un enlace a un grupo de conexiones de muestra para MySQL escrito en C ++. (Probablemente deberías ignorar las declaraciones goto cuando implementes las tuyas).
Indica que mysql_real_connect () no es seguro para subprocesos de forma predeterminada. La biblioteca del cliente debe compilarse para acceso por hilos.