martes, 22 de noviembre de 2011

Excepción "packets larger than max_allowed_packet are not allowed" en SphinxQL

Continuo trabajando con Sphinx bajo .NET, y llevo un par de días lidiando con una excepción muy molesta. Resulta que al intentar hacer un insert utilizando SphinxQL para indexar nuevo contenido en Sphinx, me aparecía la siguiente excepción:

"packets larger than max_allowed_packet are not allowed"

Esta excepción se refiere al tamaño del paquete en la conexión MySQL, en definitiva está relacionado con el tamaño de la sentencia SphinxQL. Cuando intentaba enviar una sentencia de más de 1024 caracteres, saltaba la excepción.

La causa es que la última release de Sphinx, la versión 2.01-beta, no es totalmente compatible con el conector de MySQL para .NET y al establecer la conexión inicial, Sphinx no envía el valor "Max_Packet_Size" que sirve precisamente para establecer el tamaño máximo del paquete (en nuestro caso, la query), por lo tanto el conector coge el valor por defecto, es decir, los escasos 1024 caracteres.

Tras hacer bastante investigación, llegué a un seguimiento de un bug en la página de Sphinx que trataba precisamente de esto:

http://sphinxsearch.com/bugs/view.php?id=987

En el seguimiento de error se notifica una posible solución al mismo, añadiendo una linea de código (aunque para ello tuve que utilizar el traductor de google de ruso a inglés).

Dentro del código fuente, en el fichero: searchd.cpp, dentro de la función HandleMysqlShowVariables, hay que añadir la siguiente linea:

SendMysqlPair ( tOut, uPacketID, dRows, "max_allowed_packet", CSphString().SetSprintf("%d", g_iMaxPacketSize).cstr());

Se debe añadir aproximadamente en la linea 11721 del código, pero lógicamente esto variará en función de la versión del código fuente que se esté utilizando.

Y ahora viene la parte complicada, la compilación. Yo he utilzado el Visual Studio 2008, aunque también puede utilizarse la versión 2005. En las siguientes páginas encontré algunas pistas sobre como compilar el proyecto:

http://sphinxsearch.com/forum/view.html?id=4359
http://blog.aulin.no/compiling-sphinx-110beta-on-windows

En definitiva, para poder compilarlo hay que instalar un par de librerías externas. Pero como en mi caso no utilizaba estas, simplemente las deshabilité en el archivo sphinx.h:

#ifdef _WIN32
 #define USE_MYSQL  1 /// whether to compile MySQL support
 #define USE_PGSQL  0 /// whether to compile PgSQL support
 #define USE_ODBC  1 /// whether to compile ODBC support
 #define USE_LIBEXPAT 1 /// whether to compile libexpat support
 #define USE_LIBICONV 1 /// whether to compile iconv support
 #define USE_LIBXML  0 /// whether to compile libxml support
 #define USE_LIBSTEMMER 0 /// whether to compile libstemmber support
 #define USE_WINDOWS  1 /// whether to compile for Windows
 #define USE_SYSLOG  0 /// whether to use syslog for logging

 #define UNALIGNED_RAM_ACCESS 1
 #define USE_LITTLE_ENDIAN  1
#else
 #define USE_WINDOWS  0 /// whether to compile for Windows
#endif


Solo hay que poner a 0, las directivas USE_MYSQL, USE_LIBEXPAT y USE_LIBICONV. Por ejemplo la directiva USE_MYSQL se utiliza para SphinxSE, por lo tanto, si no vas a utilizar SphinxSE, no es necesario compilar la librería, al igual que pasa con las otras.

Una vez hechas estas modificaciones el proyecto se puede compilar, en mi caso solo he compilado el searchd, pues es el que necesitaba.

Y de forma un tanto increíble funcionó a la primera, y ahora puedo ejecutar instrucciones SQL de mayor longitud de 1024 caracteres.



No hay comentarios:

Publicar un comentario