2009-09-21 14 views
19

Estamos haciendo un pequeño punto de referencia de MySQL donde queremos ver cómo funciona para nuestros datos.Cómo acceder a MySQL desde múltiples hilos simultáneamente

Parte de esa prueba consiste en ver cómo funciona cuando varios subprocesos simultáneos golpean el servidor con varias consultas.

El MySQL documentation (5.0) no es muy claro acerca de los clientes multihilo. Debo señalar que sí enlace con la biblioteca segura de subprocesos (libmysqlclient_r.so)

Estoy usando declaraciones preparadas y hago tanto lectura (SELECCIONAR) como escribir (ACTUALIZAR, INSERTAR, ELIMINAR).

  • ¿Debo abrir una conexión por tema? Y si es así: ¿cómo puedo hacer esto incluso .. parece mysql_real_connect() devuelve el identificador original de DB que me dieron cuando me llamaron mysql_init())
  • Si no: ¿cómo hago resultados y métodos seguros como mysql_affected_rows devuelve el valor correcto en vez de colisión con llamadas de otro hilo (el mutex/locks podría funcionar, pero se siente mal)

Respuesta

25

Como mantenedor de una aplicación C bastante grande que hace llamadas de MySQL desde múltiples hilos, puedo decir que no he tenido problemas con simplemente hacer una nueva conexión en cada hilo. Algunas advertencias que me he encontrado:

  • Editar: Parece que esta bala sólo se aplica a las versiones 5.5 <; vea this page for your appropriate version: Como usted dice que ya está haciendo, enlace contra libmysqlclient_r.
  • Llamada mysql_library_init() (una vez, desde main()). Lea los documentos sobre el uso en entornos multiproceso para ver por qué es necesario.
  • Haga una nueva estructura MYSQL usando mysql_init() en cada hilo. Esto tiene el efecto secundario de llamar al mysql_thread_init() por usted. mysql_real_connect() como siempre dentro de cada subproceso, con su estructura MYSQL específica de subproceso.
  • Si está creando/destruyendo muchos hilos, querrá usar mysql_thread_end() al final de cada hilo (y mysql_library_end() al final de main()). Es una buena práctica de todos modos.

Básicamente, no comparten MYSQL estructuras creadas o nada específico para esa estructura (es decir, MYSQL_STMT s) y que funcionará como se espera.

Esto parece menos trabajo que hacer un grupo de conexión conmigo.

+1

Este fue el tipo de respuesta que necesitaba. No me di cuenta de que tendría que llamar a mysql_init en cada hilo; lo hice una vez en main(). Gracias –

+1

@chazomaticus, ¿cuántos hilos usarías normalmente y cuántas conexiones tendrías abiertas? ¿Esto escala a un gran número de hilos/conexiones? Un grupo de conexiones es realmente útil si tiene muchos hilos (100's - 1000's) pero no desea la sobrecarga de abrir 1000 conexiones (de las cuales puede que no tenga permiso de todos modos ya que el valor predeterminado para max_connections generalmente se establece en 100). Si tienes pocos hilos, entonces tu enfoque funcionaría. +1 de mí para mostrar ejemplos de código. – Glen

+1

Dado que Isak está tratando de enfatizar la base de datos, tantos hilos como sea posible. He ejecutado ~ 1000 sin problema (si todos los subprocesos son consultas de problemas, la mayor parte de su tiempo se pasa inactivo en 'poll()', por lo que no es tan intensivo en la CPU como se podría pensar, aunque puede comerse un trozo de memoria). Tiene razón acerca de que max_connections le cubre en 100 por defecto, por lo que para un máximo estrés, suba eso según lo desee. – chazomaticus

6

Puede crear un grupo de conexiones. Cada hilo que necesita una conexión podría solicitar uno gratis del grupo. Si no hay conexión disponible, bloquee o haga crecer el grupo agregando una nueva conexión.

Hay un artículo here que describe los pros y los contras de un grupo de conexiones (a pesar de que está basado en Java)

Editar: Aquí hay una pregunta SO/respuesta sobre connection pools in C

Edit2: He aquí un enlace a una muestra Connection Pool for MySQL escrito en C++. (Probablemente debería ignorar las sentencias goto al implementar su propio.)

+0

buena respuesta .. gracias. Pero todavía tengo problemas con la apertura de más de una conexión y la muestra a la que se vinculó no tiene ese fragmento de código. Te di un +1 pero no quiero aceptarlo (todavía), ya que no resuelve mi problema. problema con la apertura de múltiples conexiones –

+0

pero realmente gracias por compartir los artículos ~ – yaobin

-1

MySQL Threaded Clients in C

Se afirma que mysql_real_connect() no es hilo de seguridad por defecto. La biblioteca del cliente necesita ser compilada para acceso enhebrado.

+0

Estoy usando la biblioteca libmysqlclient_r así que supongo que tiene compiladas todas las cosas relacionadas con la seguridad de los hilos. Solo para estar seguro, intentaré hacer todas las conexiones. antes de engendrar hilos y ver si eso ayuda –

1

me parece claro desde el MySQL Docs que cualquier estructura MYSQL específica se puede utilizar en un hilo sin dificultad - utilizando la misma estructura MYSQL en diferentes hilos simultáneamente está claro que va a dar resultados muy impredecibles como estado se almacena dentro de la conexión MYSQL.

Por lo tanto, cree una conexión por subproceso o use un grupo de conexiones como se sugiere arriba y proteja el acceso a ese grupo (es decir, reservar o liberar una conexión) utilizando algún tipo de Mutex.

+0

Esto es lo que sospechaba ... Solo necesito averiguar cómo hacer conexiones múltiples ... no puedo hacer que funcione ahora mismo –

+0

Nunca tuve un problema con esto, pero no suelo usa estas bibliotecas Me parece que debería ser capaz de asignar estructuras MYSQL separadas e iniciar y conectar cada una. – Elemental

Cuestiones relacionadas