<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TecnoRetales &#187; MySQL</title>
	<atom:link href="http://www.tecnoretales.com/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tecnoretales.com</link>
	<description>La experiencia no se olvida</description>
	<lastBuildDate>Mon, 13 Sep 2010 21:37:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; float: right; padding-right: 0; margin: 3px;"><!-- Ad number: 1 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Qué es una Caché y como aplicarla a la programación Web</title>
		<link>http://www.tecnoretales.com/programacion/que-es-una-cache-y-como-aplicarla-a-la-programacion-web/</link>
		<comments>http://www.tecnoretales.com/programacion/que-es-una-cache-y-como-aplicarla-a-la-programacion-web/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 08:15:27 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Caché]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Optimización]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=642</guid>
		<description><![CDATA[Vamos a ver que es una caché con un ejemplo muy ilustrativo que leí hace algún tiempo. Supongamos que estamos trabajando en una centralita que facilita números de teléfono de un pueblo relativamente pequeño; para ello, tenemos un listín telefónico común con todos los teléfonos del pais.
Cada vez que recibimos una llamada, cogemos el listín, [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Vamos a ver <strong>que es una caché</strong> con un ejemplo muy ilustrativo que leí hace algún tiempo. Supongamos que estamos trabajando en una centralita que facilita números de teléfono de un pueblo relativamente pequeño; para ello, tenemos un listín telefónico común con todos los teléfonos del pais.</p>
<p>Cada vez que recibimos una llamada, cogemos el listín, realizamos la búsqueda y facilitamos el número encontrado al usuario. Al poco tiempo, nos damos cuenta que la gente suele pedir los teléfonos de los mismos restaurantes y comercios una y otra vez, así que cogemos una libreta pequeña y vamos anotando los números de teléfono que nos solicitan ordenados alfabéticamente para poder <strong>acceder a ellos de manera más rápida</strong> la próxima vez&#8230; felicidades, acabas de crear una caché!<span id="more-642"></span></p>
<p>Sin embargo, el uso de una <strong>caché tiene un pequeño handicap</strong>; imaginemos que nos llama un usuario y nos solicita el teléfono de un comercio. Cogeremos nuestra libreta, lo buscaremos y si no lo encontramos recurriremos al listín, realizaremos la búsqueda en él y facilitaremos el número al usuario. En este momento estamos aumentando ligeramente el tiempo de búsqueda de un número, por ese motivo, la información debe almacenarse en la caché de manera eficiente, y a partir de aquí hay mil teorías sobre como y cuando almacenar la información en una caché.</p>
<p>En resumen y dicho de una manera más técnica un sistema de caché es una zona de memoria en la que se almacenan copias de un objeto original pero al que es mucho más rápido acceder.</p>
<h3><span style="text-decoration: underline;">La Caché en la programación</span>:</h3>
<p>A la hora de construir una aplicación medianamente grande, se hace imprescindible el cachear cierta información para conseguir un rendimiento óptimo. Un sistema de caché correctamente implementado puede <strong>reducir el número de servidores y evitar la sobrecarga</strong> de las máquinas.</p>
<p>Se pueden utilizar diferentes tipos de caché en función del tipo de datos que queramos guardar. Centrándome en la programación web, podemos encontrar:</p>
<ul>
<li><span style="text-decoration: underline;">Caché SQL</span>: Para almacenar en memoria el resultado de ciertas consultas recurrentes y poder así descargar la base de datos. MySQL 5.0 Server tiene soporte nativo para este tipo de caché pero se debe activar expresamente.</li>
<li><span style="text-decoration: underline;">Cachéo de Objetos</span>: En este tipo de caché podemos almacenar objetos, arrays, textos, resultados de funciones, resultados de base de datos&#8230; Podremos almacenar cualquier tipo de información soportada por el sistema de cacheo e indicarle el tiempo de expiración. Ejemplos de este sistema de caché para PHP son APC (Alternative PHP Cache) o Memcached.</li>
<li><span style="text-decoration: underline;">Cacheo de templates</span>: Puede ser de gran utilidad el cachear los resultados HTML al invocar diferentes URL, por ejemplo, el sistema de templates Smarty integra un sistema de caché que permite devolver el HTML de manera eficiente.</li>
</ul>
<h3><span style="text-decoration: underline;">Por qué no debo usar SQLCaché y APC o Memcached?</span></h3>
<p>La caché implementada por MySQL tiene una política en la gestión de su caché muy estricta. Cada vez que hay una escritura en una tabla, elimina toda la caché asociada a dicha tabla y a partir de ese momento, se debe volver a regenerar, por tanto, la entrada de un registro en la tabla implica insertar el registro, regenerar los indices, cachear los datos y por último devolverlos (aumentamos el tiempo de la consulta). Dada esta premisa, podemos extraer la conclusión de que es interesante <strong>activar SQLCaché en una base de datos con muchas lecturas y pocas escrituras</strong>.</p>
<p>A su vez, implementando un sistema de cacheo como APC o Memcached para almacenar la información devuelta por la base de datos dada una consulta, reduce considerablemente el número de lecturas a base de datos.</p>
<p>Por ese motivo, el tener activados estos dos tipos de caché simultaneamente, no solo no mejora el rendimiento de nuestra aplicación sino que lo empeora.</p>
<h3><span style="text-decoration: underline;">Es contraproducente usar APC y Memcached de manera simultanea?</span></h3>
<p>APC proporciona dos tipos de cacheo. Por un lado, evita el continuo compilado de un script PHP, pues a pesar de ser un lenguaje interpretado, PHP pasa todo script a un lenguaje entendible por la máquina antes de ejecutarlo ¿por qué recompilar cada vez el script si no ha cambiado desde la última ejecución? A partir de la versión 6 de PHP parece ser que APC estará activado de forma nativa. Por otra parte, podemos almacenar objetos con el uso de las funciones <a title="APC_add" href="http://es.php.net/manual/en/function.apc-add.php" target="_blank">apc_add</a> y <a title="APC_store" href="http://es.php.net/manual/en/function.apc-store.php" target="_blank">apc_store</a>.</p>
<p>Memcached proporciona un servicio web desacoplado y altamente escalable. <strong>El 95% del top ten y el 80% del top 50 de Alexa utiliza Memcached</strong> precisamente por la facilidad de implementación y de añadir nuevas máquinas para cachear información. APC tiene un rendimiento ligeramente superior, pero si tenemos un sistema con servidores balanceados no podemos compartir la caché entre todas las máquinas porque está vinculada al host, por ese motivo la balanza se ha ido decantando hacia el uso de Memcached.</p>
<p>Si bien, puede ser interesante <strong>utilizar una combinación de ambas</strong>, APC para el <strong>precompilado</strong> de nuestro código y <strong>Memcached para almacenar</strong> la información de base de datos y descargar así nuestro motor de bd.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/que-es-una-cache-y-como-aplicarla-a-la-programacion-web/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Consideraciones de velocidad con LIMIT</title>
		<link>http://www.tecnoretales.com/bases-de-datos/consideraciones-de-velocidad-con-limit/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/consideraciones-de-velocidad-con-limit/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 06:11:36 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=631</guid>
		<description><![CDATA[Un compañero de trabajo que es un crack en temas de optimización de bases de datos me ha pasado la siguiente información. Cuando hacemos una consulta con un LIMIT x, y sobre una tabla con millones de registros, a medida que x aumenta, la consulta se va haciendo cada vez más lenta. Veamos un ejemplo:
SELECT [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Un compañero de trabajo que es un crack en temas de optimización de bases de datos me ha pasado la siguiente información. Cuando hacemos una consulta con un <em>LIMIT x, y</em> sobre una tabla con millones de registros, a medida que <em>x</em> aumenta, la consulta se va haciendo cada vez más lenta. Veamos un ejemplo:</p>
<p>SELECT version FROM car LIMIT 300,100; (100 results, <strong>0.01 sec</strong>)</p>
<p>SELECT version FROM car LIMIT 3000000,100; (100 results, <strong>2.5 sec</strong>)</p>
<p>Si además agregamos un par de JOINS a esta consulta, la complicamos un poco y le añadimos un ORDER BY, los problemas de rendimiento pueden llegar a causar un colapso en la base de datos.<span id="more-631"></span></p>
<p><strong>¿Por qué pasa esto?</strong></p>
<p>Para determinar el primer valor que tiene que seleccionar, MySQL debe recorrer desde el primer registro e ir contando hasta llegar al 300, a partir de ahí, cogerá 100. Obviamente, a medida que el valor de X va aumentando, la búsqueda del primer elemento es más lenta y como podemos ver en el ejemplo de arriba, llega a tardar 2,5 segundos en recorrer 3.000.000 de registros.</p>
<p><strong>¿Cómo lo podemos solucionar?</strong></p>
<p>Mi compañero propone hacer la búsqueda acotando a partir de primary key de la tabla, de este modo, al ser un campo indexado la búsqueda es realmente eficiente y nos evitamos cargar la máquina:</p>
<p><span style="font-family: Arial; font-size: x-small;"><span style="font-size: 10pt; font-family: Arial;" lang="EN-GB">SELECT version FROM car WHERE id_car BETWEEN 3000000 AND 3000100; (~100 results, <strong>0.01 sec</strong>)</span></span></p>
<p><span style="font-family: Arial; font-size: x-small;"><span style="font-size: 10pt; font-family: Arial;" lang="EN-GB">Esta solución no nos sería válida a la hora de construir un paginador, porque en el caso de tener vehículos desactivados u eliminados, unas páginas contendrían 100 vehículos, otras quizá 74&#8230; sin embargo, si por ejemplo construimos un script que se recorra toda la tabla <em>car</em> esta es una buena manera de realizar la búsqueda.</span></span></p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/consideraciones-de-velocidad-con-limit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configurar Doctrine en Symfony</title>
		<link>http://www.tecnoretales.com/bases-de-datos/configurar-doctrine-en-symfony/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/configurar-doctrine-en-symfony/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 14:23:27 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=496</guid>
		<description><![CDATA[ Symfony integra Propel ORM por defecto, sin embargo, Doctrine está ganando puntos sobre su rival.
La principal ventaja de cada uno de ellos es:
Propel: Está completamente integrado con Symfony y decenas de plugins sólo funcionan para Propel.
Doctrine: Tiene muy buen rendimiento en ejecución y una forma muy concisa al escribir consultas complejas.
Si te has decidido [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignleft size-full wp-image-497" src="http://www.tecnoretales.com/wp-content/uploads/2009/07/doctrine.gif" alt="Doctrine Logo" width="191" height="53" /> Symfony integra Propel ORM por defecto, sin embargo, Doctrine está ganando puntos sobre su rival.</p>
<p>La principal ventaja de cada uno de ellos es:</p>
<p><strong>Propel:</strong> Está completamente integrado con Symfony y decenas de plugins sólo funcionan para Propel.</p>
<p><strong>Doctrine:</strong> Tiene muy buen rendimiento en ejecución y una forma muy concisa al escribir consultas complejas.</p>
<p>Si te has decidido a utilizar Doctrine en lugar de Propel y no sabes como integrarlo con Symfony, aquí te dejo los pasos para activarlo.<span id="more-496"></span></p>
<ol>
<li>Lo primero que deberemos hacer es habilitar <em>sfDoctrinePlugin</em> y deshabilitar <em>sfPropelPlugin</em>, esto lo haremos editando el archivo <em>config/ProjectConfiguration.class.php </em>:
<pre class="brush: php;">
public function setup()
{
  $this-&gt;enablePlugins(array('sfDoctrinePlugin'));
  $this-&gt;disablePlugins(array('sfPropelPlugin'));
}
</pre>
<p>o si lo prefieres, puedes habilitar todos los plugins por defecto excepto los que no te interesen:</p>
<pre class="brush: php;">
public function setup()
{
  $this-&gt;enableAllPluginsExcept(array('sfPropelPlugin'));
}
</pre>
</li>
<li>Activado Doctrine, borraremos la caché para asegurarnos que se cargan nuestros cambios:<br />
<code>symfony cc</code></li>
<li>Crearemos una carpeta <em>doctrine</em> dentro de <em>config</em> que contendrá nuestro archivo <em>schema.yml</em> y listo, ya tenemos a Symfony funcionando con Doctrine</li>
<li>Ahora sólo queda abrir el archivo <em>config/databases.yml</em> y cambiar &#8220;<em>propel</em>&#8221; por &#8220;<em>doctrine</em>&#8221; (respetando mayúsculas y minúsculas) y eliminar la linea &#8220;<em>classname:  PropelPDO</em>&#8220;.</li>
</ol>
<p>Recordemos que a partir de ahora, deberemos utilizar la sintaxis Doctrine, tanto en nuestra definición del schema como en el modelo de nuestra aplicación. Si son tus primeros pasos con Doctrine, puedes ver su documentación original <a title="Doctrine Tutorial" href="http://www.doctrine-project.org/documentation/manual/1_1/en/introduction" target="_blank">aquí</a>.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/configurar-doctrine-en-symfony/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; float: left; padding-left: 0px; margin: 3px;"><!-- Ad number: 2 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Qué es Doctrine ORM?</title>
		<link>http://www.tecnoretales.com/programacion/que-es-doctrine-orm/</link>
		<comments>http://www.tecnoretales.com/programacion/que-es-doctrine-orm/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 09:48:54 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=487</guid>
		<description><![CDATA[Qué es un ORM?
Un ORM o (Object Relation Mapper) es una técnica de programación que nos permite convertir datos entre el sistema de tipos utilizado en un lenguaje de programación orientado a objetos y el utilizado en una base de datos relacional, es decir, las tablas de nuestra base de datos pasan a ser clases [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><strong>Qué es un ORM?</strong></p>
<p>Un ORM o (Object Relation Mapper) es una técnica de programación que nos permite convertir datos entre el sistema de tipos utilizado en un lenguaje de programación orientado a objetos y el utilizado en una base de datos relacional, es decir, las tablas de nuestra base de datos pasan a ser clases y los registros objetos que podemos manejar con facilidad.</p>
<p><img class="aligncenter size-full wp-image-489" title="fig02" src="http://www.tecnoretales.com/wp-content/uploads/2009/07/fig02.jpg" alt="fig02" width="362" height="438" /></p>
<p><span id="more-487"></span>Utilizar un ORM tiene una serie de ventajas que nos facilitan enormemente tareas comúnes y de mantenimiento:</p>
<ol>
<li><strong>Reutilización:</strong> La principal ventaja que aporta un ORM es la reutilización permitiendo llamar a los métodos de un objeto de datos desde distintas partes de la aplicación e incluso desde diferentes aplicaciones.</li>
<li><strong>Encapsulación:</strong> La capa ORM encapsula la lógica de los datos pudiendo hacer cambios que afectan a toda la aplicación únicamente modificando una función.</li>
<li><strong>Portabilidad:</strong> Utilizar una capa de abstracción nos permite cambiar en mitad de un proyecto de una base de datos MySQL a una Oracle sin ningún tipo de complicación. Esto es debido a que no utilizamos una sintaxis MySQL, Oracle o SQLite para acceder a nuestro modelo, sino una sintaxis propia del ORM utilizado que es capaz de traducir a diferentes tipos de bases de datos.</li>
<li><strong>Seguridad:</strong> Los ORM suelen implementar mecanísmos de seguridad que protegen nuestra aplicación de los ataques más comúnes como SQL Injections.</li>
<li><strong>Mantenimiento del código:</strong> Gracias a la correcta ordenación de la capa de datos, modificar y mantener nuestro código es una tarea sencilla.</li>
</ol>
<p><strong>Qué es Doctrine?</strong></p>
<p><img class="alignleft size-full wp-image-488" title="doctrine-logo" src="http://www.tecnoretales.com/wp-content/uploads/2009/07/doctrine-logo.png" alt="doctrine-logo" width="119" height="96" />Según la <a title="Doctrine ORM" href="http://www.doctrine-project.org/" target="_blank">documentación oficial</a>, Doctrine es un <strong>ORM para PHP</strong> 5.2.3 y posterior. Además de todas las ventajas que conlleva un ORM, uno de sus puntos fuertes es su lenguaje <strong>DQL</strong> (Doctrine Query Language) <strong>inspirado en el HQL de Hibernate</strong>.</p>
<p>Cuando trabajamos con Doctrine, necesitamos informar a su motor interno de cual es el modelo de nuestra aplicación, para ello podemos hacer <strong>ingeniería inversa</strong> de nuestra base de datos existente, o si empezamos la aplicación desde 0, crear el modelo en la sintaxis específica que nos propone Doctrine y luego generar toda la base de datos.</p>
<p>Para crear el modelo, doctrine nos da dos alternativas, hacer una clase por tabla e indicarle mediante PHP el tipo de datos que almacenaremos en él, un ejemplo:</p>
<pre class="brush: php;">// models/generated/BaseUser.php

class User extends BaseUser
{
    public function setTableDefinition()
    {
        $this-&gt;hasColumn('username', 'string', 255, array('default' =&gt; 'default username'));
        $this-&gt;hasColumn('name', 'string', 255, array('default' =&gt; 'default name'));
        $this-&gt;hasColumn('age', 'integer', 4, array('unsigned' =&gt; true));
        // ...
    }

    // ...
}</pre>
<p>O crear un esquema en <a title="Yaml" href="http://es.wikipedia.org/wiki/YAML" target="_blank">formato YAML</a> (<em>schema.yml</em>) similar a XML, pero bastante más legible. El equivalente al ejemplo anterior en YAML sería:</p>
<pre class="brush: plain;"># schema.yml

# ...
User:
# ...
  columns:
    username:
      type: string(255)
      default: default username
    name:
      type: string(255)
      default: default name
    age:
      type: integer(4)
      unsigned: true
    # ...</pre>
<p>Además de definir los campos de cada tabla, también le indicamos las relaciones que tienen con las otras tablas y su tipo (many-to-many, one-to-many, one-to-one&#8230;), lo que deja perfectamente estructurada nuestro modelo de datos y su manera de acceder a los valores.</p>
<p>Más adelante seguiré escribiendo sobre las ventajas de Doctrine y añadiendo ejemplos que considere interesantes y/o útiles.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/que-es-doctrine-orm/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Instalar DBDesigner4 en Ubuntu</title>
		<link>http://www.tecnoretales.com/linux/instalar-dbdesigner4-en-ubuntu/</link>
		<comments>http://www.tecnoretales.com/linux/instalar-dbdesigner4-en-ubuntu/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 06:05:36 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[DBDesigner4]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=451</guid>
		<description><![CDATA[DBDesigner4 es una aplicación gratuita que integra diseño de bases de datos, modelado, creación y mantenimiento en un entorno único.
Instalar DBDesigner4 en Ubuntu y hacer que funcione es relativamente fácil, el problema viene cuando quieres hacer conexiones con la base de datos para hacer, por ejemplo, ingeniería inversa y obtener el modelo gráfico de las [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignleft size-full wp-image-452" title="DBDesigner4 logo" src="http://www.tecnoretales.com/wp-content/uploads/2009/06/dbdesigner.jpg" alt="DBDesigner4 logo" width="150" height="134" /><strong>DBDesigner4 </strong>es una aplicación gratuita que integra diseño de bases de datos, modelado, creación y mantenimiento en un entorno único.</p>
<p><strong>Instalar DBDesigner4 en Ubuntu</strong> y hacer que funcione es relativamente fácil, el problema viene cuando quieres hacer conexiones con la base de datos para hacer, por ejemplo, ingeniería inversa y obtener el modelo gráfico de las tablas.</p>
<p>Para que esto no nos suceda, aquí os dejo los pasos a seguir para que os funcione en vuestra Ubuntu a la primera.<span id="more-451"></span></p>
<ol>
<li>Descargarnos las librerias que vamos a necesitar y el programa:
<pre>cd /opt</pre>
<pre>wget http://www.silcom.com.pe/soft/xlibs_6.8.2-77_all.deb</pre>
<pre>wget http://www.silcom.com.pe/soft/kylixlibs3-borqt_3.0-1_i386.deb</pre>
<pre>wget http://downloads.mysql.com/DBDesigner4/DBDesigner4.0.5.4.tar.gz</pre>
<pre>wget http://crlab.com/dbx/dbxmda.tar.gz</pre>
</li>
<li>
<pre>Instalamos...</pre>
<pre>sudo apt-get install xkeyboard-config</pre>
<pre>sudo dpkg -i xlibs_6.8.2-77_all.deb</pre>
<pre>sudo dpkg -i kylixlibs3-borqt_3.0-1_i386.deb</pre>
<pre>sudo tar xvfz DBDesigner4.0.5.4.tar.gz</pre>
<pre>sudo tar xvfz dbxmda.tar.gz</pre>
<pre>sudo mv DbxMda/libsqlmda.so.3.20 /usr/lib/</pre>
<pre>sudo ldconfig</pre>
</li>
<li>
<pre>Hacemos unos cuantos enlaces simbólicos:</pre>
<pre>sudo ln -s /usr/lib/kylix3/libborqt-6.9-qt2.3.so /usr/lib/libborqt-6.9-qt2.3.so</pre>
<pre>sudo ldconfig</pre>
<pre>sudo ln -s /usr/lib/kylix3/libborqt-6.9.0-qt2.3.so /lib/libborqt-6.9-qt2.3.so</pre>
</li>
<li>Por último, sólo nos queda iniciar el programa
<pre>/opt/DBDesigner4/DBDesigner4 &amp;</pre>
</li>
</ol>
<p>Si todo ha ido bien, el programa iniciará normalmente mostrándonos el entorno de modelado de base de datos. El siguiente paso será <strong>configurar la conexión a base de datos</strong>:</p>
<ol>
<li>Click en el menú superior en &#8220;D<span style="text-decoration: underline;">a</span>tabase &gt; <span style="text-decoration: underline;">C</span>onnect to Database&#8221; y nos aparecerá una ventana como la que siguie:<img class="aligncenter size-full wp-image-453" title="DBDesigner4 - New Database" src="http://www.tecnoretales.com/wp-content/uploads/2009/06/pantallazo-select-database-connection.png" alt="DBDesigner4 - New Database" width="500" height="201" /></li>
<li>Click en el botón &#8220;New Database Connect&#8221; y rellenamos la información:
<ul>
<li><span style="text-decoration: underline;">Connection Name</span>: Nombre para la conexión</li>
<li><span style="text-decoration: underline;">Driver</span>: En nuestro caso, será MySQL pero se pueden elegir varios (Oracle, SQLLite&#8230;)</li>
<li><span style="text-decoration: underline;">Hostname</span>: Donde está localizada la base de datos (generalmente localhost)</li>
<li><span style="text-decoration: underline;">Database Name</span>: Nombre de la base de datos a la que queremos conectar</li>
<li><span style="text-decoration: underline;">Username</span>: Nombre de usuario para conectar a dicha base de datos</li>
<li><span style="text-decoration: underline;">Password</span>: Password de acceso</li>
</ul>
</li>
<li>Click en la pestaña &#8220;Advanced&#8221; y rellenamos los valores como muestra la imágen excepto los campos User Name y Database que deberán contener los de tu conexión:<img class="aligncenter size-full wp-image-454" title="DBDesigner4 Database Connection Editor" src="http://www.tecnoretales.com/wp-content/uploads/2009/06/pantallazo-database-connection-editor-2.png" alt="DBDesigner4 Database Connection Editor" width="300" height="279" /></li>
</ol>
<p>Ahora ya estás en disposición de conectar el programa con tu base de datos y hacer ingeniería inversa de tus tablas existentes.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/linux/instalar-dbdesigner4-en-ubuntu/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Explain MySQL para optimizar tus consultas</title>
		<link>http://www.tecnoretales.com/bases-de-datos/explain-mysql-para-optimizar-tus-consultas/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/explain-mysql-para-optimizar-tus-consultas/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 17:25:01 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=563</guid>
		<description><![CDATA[Explain es una potente herramienta que MySQL pone a nuestra disposición para orientarnos sobre como está ejecutando una consulta el motor de la base de datos.
Esto nos es de mucha utilidad cuando creamos una consulta nueva, pues nos indica que índices va a utilizar, de que tipo son, como de efectiva será la respuesta al [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><strong><img class="alignleft size-full wp-image-565" src="http://www.tecnoretales.com/wp-content/uploads/2009/07/mysql_5_4_300x290.png" alt="MySQL Dolphin" width="150" height="145" />Explain</strong> es una potente herramienta que MySQL pone a nuestra disposición para orientarnos sobre como está ejecutando una consulta el motor de la base de datos.</p>
<p>Esto nos es de mucha utilidad cuando creamos una consulta nueva, pues nos indica que índices va a utilizar, de que tipo son, como de efectiva será la respuesta al usar esos índices&#8230; por lo tanto, podemos detectar rápidamente, por ejemplo, de que nuestra consulta no está bien formada o que nos falta un índice en algún campo concreto.</p>
<p>Si ejecutamos la siguiente consulta:</p>
<p><code>EXPLAIN SELECT *<br />
FROM user u<br />
INNER JOIN user_profile up ON u.id = up.user_id</code></p>
<p>Obtendremos una respuesta como esta:</p>
<table id="table_results" border="1">
<thead>
<tr>
<th>id</th>
<th>select_type</th>
<th>table</th>
<th>type</th>
<th>possible_keys</th>
<th>key</th>
<th>key_len</th>
<th>ref</th>
<th>rows</th>
<th>Extra</th>
</tr>
</thead>
<tbody>
<tr>
<td align="right">1</td>
<td>SIMPLE</td>
<td>up</td>
<td>ALL</td>
<td>user_id_idx</td>
<td><em>NULL</em></td>
<td><em>NULL</em></td>
<td><em>NULL</em></td>
<td align="right">13</td>
<td></td>
</tr>
<tr>
<td align="right">1</td>
<td>SIMPLE</td>
<td>u</td>
<td>eq_ref</td>
<td>PRIMARY</td>
<td>PRIMARY</td>
<td>4</td>
<td>futbol.up.user_id</td>
<td align="right">1</td>
<td></td>
</tr>
</tbody>
</table>
<p>Pero, ¿qué quieren decir estas columnas? ¿qué información nos dan?<span id="more-563"></span></p>
<ol>
<li><strong>Table: </strong>Nos informa de la tabla a la que nos estamos refiriendo.</li>
<li><strong>Type:</strong> El tipo de unión que se está usando. Desde la mejor hasta la peor, los tipos de uniones son system, const, eq_ref, ref, range, index, y ALL.
<ul>
<li><strong>System:</strong> Tabla con una única fila, por tanto, la respuesta es inmediata.</li>
<li><strong>Const:</strong> En la tabla coincide una única fila con los criterios indicados. Al sólo haber una fila, el optimizador toma este valor como constante, por este motivo este tipo de tablas son muy rápidas.</li>
<li><strong>Eq_ref:</strong> Una fila de la tabla 1 será leída por cada combinación de filas de la tabla 2. Este tipo es usado cuando todas las partes de un índice se usan en la consulta y el índice es UNIQUE o PRIMARY KEY.</li>
<li><strong>Ref:</strong> Todas las filas con valores en el índice que coincidan serán leídos desde esta tabla por cada combinación de filas de las tablas previas. Similar a <strong>eq_ref</strong>, pero usado cuando usa sólo un prefijo más a la izquierda de la clave o si la clave no es UNIQUE o PRIMARY KEY. Si la clave que es usada coincide sólo con pocas filas, esta union es buena.</li>
<li><strong>Range:</strong> Sólo serán recuperadas las filas que estén en un rango dado, usando un índice para seleccionar las filas. La columna <strong>key</strong> indica cual índice es usado, y el valor <strong>key_len</strong> contiene la parte más grande de la clave que fue usada. La columna ref será NULL para este tipo.</li>
<li><strong>Index:</strong> Escaneo completo de la tabla para cada combinación de filas de las tablas previas, revisando únicamente el índice.</li>
<li><strong>ALL:</strong> Escaneo completo de la tabla para cada combinación de filas. Es el peor caso ya que revisará todas las filas para cada combinación.</li>
</ul>
</li>
<li><strong>Possible_keys:</strong> Posibles indices que utilizará la consulta.</li>
<li><strong>Key:</strong> Índice utilizado para ejecutar la consulta. Si indica el valor NULL, no se ha escogido ningún índice.</li>
<li><strong>Key_len: </strong>Cuanto más pequeño sea este valor, más rápida será la consulta, pues nos indica la longitud del índice usado.</li>
<li><strong>Ref: </strong>Las columnas del índice que se está usando, o una constante si esta es posible.</li>
<li><strong>Rows: </strong>Número de filas que MySQL debe analizar para devolver los datos solicitados.</li>
<li><strong>Extra: </strong>Información complementaria sobre como MySQL ejecutará la consulta. Los posibles valores en este campo pueden ser:
<ul>
<li> <strong>Distinct</strong>: MySQL ha encontrado una fila coincidente con los filtros indicados y no necesita seguir analizando.</li>
<li><strong>Not exists:</strong> MySQL fue capaz de hacer una optimización LEFT JOIN sobre la consulta y no examinará más filas en la tabla para la combinación de filas previa después de que encuentre una fila que coincida con el criterio LEFT JOIN.</li>
<li><strong>Range checked for each record:</strong> No se encontró un índice válido. Para cada combinación de filas se hará un chequeo para determinar que indice utilizar y en caso de encontrar alguno válido, lo utilizará.</li>
<li><strong>Using filesort:</strong> Este valor indica que MySQL necesita hacer un paso extra para encontrar la forma de ordenar las filas. Este tipo de consultas <strong>debe ser optimizada</strong>.</li>
<li><strong>Using index:</strong> Recupera la información solicitada utilizando únicamente la información del índice. Esto sucede cuando todas las columnas requeridas forman parte del índice.</li>
<li><strong>Using temporary:</strong> Para resolver esta consulta, MySQL creará una tabla temporal. Uno de los casos típicos en los que devuelve este valor es cuando usamos un ORDER BY sobre un conjunto de columnas diferentes a las indicadas en la clausula GROUP BY. Este tipo de consultas <strong>debe ser optimizada</strong>.</li>
<li><strong>Where used:</strong> Se usará una clausula WHERE para determinar que filas serán comparadas con otra tabla. Si no deseamos regresar todas las filas desde la tabla, y el join es del tipo ALL o index, es muy probable que hayamos escrito algo mal en la consulta.</li>
</ul>
<p>Una respuesta en este campo del tipo &#8220;Using filesort&#8221; o &#8220;Using temporary&#8221; es susceptible de ser una consulta a optimizar.</li>
</ol>
<p>Si analizamos la consulta ejecutada anteriormente,vemos que para la tabla con alias &#8216;up&#8217; está utilizando el tipo de unión `ALL` debido a que no existe ningun filtro en la clausula WHERE (en este caso, es normal ya que queremos devolver todos los valores). Se podría utilizar el índice existente `user_id_idx` pero al no haber ningún filtro, no es necesario usarlo. Para devolver esta consulta MySQL analizará 13 filas.</p>
<p>La segunda fila hace referencia a la tabla con alias &#8216;u&#8217;. Utiliza un tipo de unión `eq_ref` ya que devolverá una fila para cada fila de la tabla `up` pudiendo usar y usando el índice primario de la tabla que tiene una longitud de 4 (muy pequeño). Se está utilizando la columna `user_id` del índice de la tabla `up` y de la base de datos `futbol` analizando una única fila para cada fila de la tabla contigua.</p>
<p>Todos los valores son correctos y podemos asegurar que esta consulta está optimizada!!</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/explain-mysql-para-optimizar-tus-consultas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Replicación asíncrona unidireccional Maestro &#8211; Esclavo en MySQL 5.0</title>
		<link>http://www.tecnoretales.com/bases-de-datos/replicacion-asincrona-unidireccional-maestro-esclavo-en-mysql-50/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/replicacion-asincrona-unidireccional-maestro-esclavo-en-mysql-50/#comments</comments>
		<pubDate>Tue, 26 May 2009 18:26:05 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=94</guid>
		<description><![CDATA[Supongamos un escenario real de producción en el que tenemos dos servidores. Una de las máquinas contiene un servidor http y una base de datos MySQL que usamos para abserver el tráfico web; la otra la utilizamos para otras tareas necesarias. Sería magnífico poder utilizar la segunda máquina como backup de nuestro MySQL por si [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignright size-full wp-image-373" title="mysql logo" src="http://www.tecnoretales.com/wp-content/uploads/2009/05/mysql.jpg" alt="mysql logo" width="150" height="110" />Supongamos un escenario real de producción en el que tenemos dos servidores. Una de las máquinas contiene un servidor http y una base de datos MySQL que usamos para abserver el tráfico web; la otra la utilizamos para otras tareas necesarias. Sería magnífico poder utilizar la <strong>segunda máquina como backup de nuestro MySQL</strong> por si hay algún problema grave en la primera ¿no? En este artículo os explico como hacerlo.</p>
<p>La replicación en MySQL funciona de la siguiente manera, el servidor maestro escribe todas las actualizaciones en un fichero de log binario, y mantiene un índice de los ficheros para rastrear las rotaciones de logs. A su vez, el servidor esclavo, que mantiene una conexión abierta contínua con el  maestro, es informado cuando sucede algún cambio en el log binario del maestro, y ejecutan estos cambios en sus tablas.<span id="more-94"></span></p>
<p><strong>Configuración de la replica asíncrona unidireccional</strong></p>
<p>1) Localizaremos el fichero de configuración de MySQL de la máquina que hará de maestro. Generalmente lo podemos encontrar en la ruta <em>/etc/mysql/my.cnf</em> y descomentamos las líneas:</p>
<p><code>log_bin=/var/log/mysql/mysql-bin.log<br />
server-id = 1</code></p>
<p>Buscamos la misma línea en el servidor que hará las veces de esclavo y descomentamos la línea log_bin y server-id modificando el valor a uno diferente del de master:</p>
<p><code> log_bin=/var/log/mysql/mysql-bin.log<br />
server-id = 2</code></p>
<p>Ahora podemos arrancar los dos servidores MySQL para empezar a enseñarles a replicar.</p>
<p>2) Una vez arrancados ambos servidores, nos ponemos en el que hará de master y creamos la base de datos y el volcado de los datos en las tablas. En mi caso haré una importación de un fichero sql:</p>
<p><code>mysql -u [DBUSER-MASTER] -p -e "CREATE DATABASE `myBaseDeDatos`"<br />
mysql -u [DBUSER-MASTER] -p myBaseDeDatos &lt; myBaseDeDatos.sql</code></p>
<p>3) Ahora crearemos una cuenta de usuario con permisos de replicación, para autorizar, en el servidor maestro, al nuevo usuario a realizar replicas:</p>
<p><code> mysql&gt; GRANT REPLICATION SLAVE ON *.* TO '[DBUSER-REPLICATOR]'@'[IP-SERVER-SLAVE]' IDENTIFIED BY '[DBPASS-REPLICATOR]';<br />
mysql&gt; flush privileges;<br />
mysql&gt; exit<br />
</code></p>
<p>4) Finalmente, consultamos el nombre del archivo de log binario y la posición de compensación, datos necesarios para configurar el esclavo:</p>
<p><code>mysql&gt; SHOW MASTER STATUS;<br />
+------------------+----------+--------------+------------------+<br />
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |<br />
+------------------+----------+--------------+------------------+<br />
| mysql-bin.000    | 103      |              |                  |<br />
+------------------+----------+--------------+------------------+<br />
1 row in set (0.00 sec)</code></p>
<p>5) Una vez hecho esto, volcaremos la base de datos en el servidor esclavo tal y como hicimos con el maestro. Ejecutaré el mismo archivo sql:</p>
<p><code>mysql -u [DBUSER-SLAVE] -p -e "CREATE DATABASE `myBaseDeDatos`"<br />
mysql -u [DBUSER-SLAVE] -p myBaseDeDatos &lt; myBaseDeDatos.sql</code></p>
<p>6) Y una vez que el esclavo tenga generada la base de datos, lo configuramos para que esté posicionado con respecto al maestro:</p>
<p><code>mysql&gt; CHANGE MASTER TO MASTER_HOST = '[IP-SERVER-MASTER]';<br />
mysql&gt; CHANGE MASTER TO MASTER_USER = '[DBUSER-REPLICATOR]';<br />
mysql&gt; CHANGE MASTER TO MASTER_PASSWORD = '[DBPASS-REPLICATOR]';<br />
mysql&gt; CHANGE MASTER TO MASTER_LOG_FILE = 'mysql-bin.0001';<br />
mysql&gt; CHANGE MASTER TO MASTER_LOG_POS = 103;<br />
mysql&gt; start slave;</code></p>
<p>Y con esto ya queda configurado el servidor esclavo y alineado con el master. Desde este momento comenzará la replicación con el maestro.</p>
<p>Para comprobar que realmente está replicando, podemos ejecutar el siguiente comando en el servidor esclavo:</p>
<p><code>mysql&gt; show slave status</code></p>
<p>Eso muestra:</p>
<p><code>*************************** 1. row ***************************<br />
Slave_IO_State: Waiting for master to send event<br />
Master_Host: [IP-SERVER-MASTER]<br />
Master_User: [DBUSER-REPLICATOR]<br />
Master_Port: 3306<br />
Connect_Retry: 60<br />
Master_Log_File: mysql-bin.0001<br />
Read_Master_Log_Pos: 103<br />
Relay_Log_File: esclavo-relay-bin.000001<br />
Relay_Log_Pos: 103<br />
Relay_Master_Log_File: mysql-bin.0001<br />
Slave_IO_Running: Yes<br />
Slave_SQL_Running: Yes<br />
Replicate_Do_DB: myBaseDeDatos<br />
Replicate_Ignore_DB:<br />
Replicate_Do_Table:<br />
Replicate_Ignore_Table:<br />
Replicate_Wild_Do_Table:<br />
Replicate_Wild_Ignore_Table:<br />
Last_Errno: 0<br />
Last_Error:<br />
Skip_Counter: 0<br />
Exec_Master_Log_Pos: 103<br />
Relay_Log_Space: 103<br />
Until_Condition: None<br />
Until_Log_File:<br />
Until_Log_Pos: 0<br />
Master_SSL_Allowed: No<br />
Master_SSL_CA_File:<br />
Master_SSL_CA_Path:<br />
Master_SSL_Cert:<br />
Master_SSL_Cipher:<br />
Master_SSL_Key:<br />
Seconds_Behind_Master: 0<br />
1 row in set (0.00 sec)</code></p>
<p>En <strong>Read_Master_Log_Pos</strong> y <strong>Relay_Log_Pos</strong> podemos ver que ambos valores están correctamente alineados. La variable <strong>Seconds_Behind_Master</strong> nos indica el desfase de actualización entre maestro y esclavo, si todo está bien, mostrará un valor 0.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/replicacion-asincrona-unidireccional-maestro-esclavo-en-mysql-50/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; display: block; margin-left: auto; margin-right: auto; text-align: center;"><!-- Ad number: 3 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Instalar Monit para monitorizar un servidor Apache, MySQL y OpenSSH</title>
		<link>http://www.tecnoretales.com/linux/instalar-monit-para-monitorizar-un-servidor-apache-y-mysql/</link>
		<comments>http://www.tecnoretales.com/linux/instalar-monit-para-monitorizar-un-servidor-apache-y-mysql/#comments</comments>
		<pubDate>Sun, 10 May 2009 15:58:03 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Monit]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=79</guid>
		<description><![CDATA[Para los que no esteis al caso, según su propia web, Monit es una utilidad gratuita de código abierto para la gestión y vigilancia de procesos, archivos, directorios y sistemas de ficheros en un sistema UNIX.
Configurado correctamente, Monit es capaz de realizar el mantenimiento y la reparación de los servicios, procesos&#8230;  incluso ejecutar acciones [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><a href="http://mmonit.com/monit/"><img class="size-full wp-image-80 alignright" title="Monit Logo" src="http://www.tecnoretales.com/wp-content/uploads/2009/04/monit_banner.png" alt="Monit Logo" width="257" height="151" /></a>Para los que no esteis al caso, según su propia web, <a title="Web oficial Monit" href="http://mmonit.com/monit/" target="_blank">Monit</a> es una utilidad gratuita de código abierto para la gestión y vigilancia de procesos, archivos, directorios y sistemas de ficheros en un sistema UNIX.</p>
<p>Configurado correctamente, Monit es capaz de realizar el mantenimiento y la reparación de los servicios, procesos&#8230;  incluso ejecutar acciones programadas para situaciones de error.</p>
<p>Por poner un ejemplo, un uso común que se le suele dar es que vaya controlando si apache está funcionando correctamente, en caso de estar caido o saturado, Monit lo levantará automáticamente y nos enviará un mail informando del problema solventado.</p>
<p><span id="more-79"></span><strong>Instalación de Monit</strong></p>
<p>1) Descargamos la última versión estable de Monit (en mi caso la 5.0.1) de la <a href="http://mmonit.com/monit/download/dist.html" target="blank">página oficial</a>, como lo instalaré en una debian, voy a la distribución en concreto, y me descargo el paquete deb para la arquitectura de mi máquina i386:</p>
<pre>wget http://ftp.uk.debian.org/debian/pool/main/m/monit/monit_4.10.1-4_i386.deb</pre>
<p>2) Y lo instalamos con el comando dpkg:</p>
<pre>sudo dpkg -i monit_4.10.1-4_i386.deb</pre>
<p>Si todo ha ido bien, obtendremos un resultado como este:</p>
<pre>Selecting previously deselected package monit.
(Reading database ... 195390 files and directories currently installed.)
Unpacking monit (from monit_4.10.1-4_i386.deb) ...
Setting up monit (1:4.10.1-4) ...
Starting daemon monitor: monit won't be started/stopped
	unless it it's configured
	please configure monit and then edit /etc/default/monit
	and set the "startup" variable to 1 in order to allow
	monit to start</pre>
<p>Llegados a este punto, ya tenemos instalado <strong>Monit en nuestro servidor Debian</strong>, ¿sencillo no?</p>
<p>Un último paso en la instalación antes de pasar a la configuración (sólo aplica si tienes apache instalado y deseas monitorizarlo con monit):</p>
<p>Localiza el directorio root document del servidor Apache que queramos monitorizar y dentro de él crear una carpeta llamada monit que contenga un archivo llamado token (el contenido de este archivo es irrelevante)</p>
<pre>mkdir -p /PATH_TO_ROOT_FOLDER/monit/
touch /PATH_TO_ROOT_FOLDER/monit/token</pre>
<p>Comprobaremos que todo ha ido bien visitando <em>http://[IP_SERVER]/monit/token</em>. Si no hay un error, es que apache ha podido leer correctamente el archivo /monit/token, en caso de error asegúrate de que has creado el archivo en la ubicación correcta y que apache puede leerlo.</p>
<p><strong>Configuración de Alertas Monit</strong></p>
<p>El fichero de configuración de Monit se encuentra en la ruta <em>/etc/monit/monitrc</em>, por defecto trae una serie de configuraciones definidas y comentadas que podremos utilizar para tener lista una <strong>configuración básica</strong>, con un poco de tiempo y paciencia, podeis ir añadiendo diferentes chequeos.</p>
<pre>sudo vi /etc/monit/monitrc</pre>
<p>Primero modificaremos la <strong>información de las alertas vía mail</strong> (recordad que debeis tener configurado en vuestro servidor un servidor de correo).</p>
<p>Añadimos la siguiente información en la sección <em>Global Sectio</em> modificando miMail@hotmail.com por el mail en el que queremos recibir las visitas y monit@myServer.com por el mail del que queremos que provenga, por ejemplo, monit@mi-dominio.com:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">set</span> alert miMail@hotmail.com</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">set</span> mail-format <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;from: monit@myServer.com</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp;subject: <span class="re1">$SERVICE</span> <span class="re1">$EVENT</span> at <span class="re1">$DATE</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;message: </div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Monit <span class="re1">$ACTION</span> <span class="re1">$SERVICE</span> at <span class="re1">$DATE</span> on <span class="re1">$HOST</span>: <span class="re1">$DESCRIPTION</span>.</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Yours sincerely,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; monit</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p><strong>Configuración de control de Apache</strong></p>
<p>Añadimos la siguiente información al final de la sección <em>Services</em></p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">check process apache with pidfile /var/run/apache2.pid</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;group www</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;start program = <span class="st0">&quot;/etc/init.d/apache2 start&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;stop program &nbsp;= <span class="st0">&quot;/etc/init.d/apache2 stop&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp;<span class="kw1">if</span> failed host <span class="br0">&#91;</span>IP_SERVER<span class="br0">&#93;</span> port <span class="nu0">80</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; protocol http request /monit/token <span class="kw1">then</span> restart</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> cpu is greater than <span class="nu0">60</span>% <span class="kw1">for</span> <span class="nu0">3</span> cycles <span class="kw1">then</span> alert</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> cpu &gt; <span class="nu0">80</span>% <span class="kw1">for</span> <span class="nu0">5</span> cycles <span class="kw1">then</span> restart</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> totalmem &gt; <span class="nu0">400</span> MB <span class="kw1">for</span> <span class="nu0">5</span> cycles <span class="kw1">then</span> restart</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp;<span class="kw1">if</span> children &gt; <span class="nu0">250</span> <span class="kw1">then</span> restart</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> loadavg<span class="br0">&#40;</span>5min<span class="br0">&#41;</span> greater than <span class="nu0">10</span> <span class="kw1">for</span> <span class="nu0">8</span> cycles <span class="kw1">then</span> stop</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> <span class="nu0">3</span> restarts within <span class="nu0">5</span> cycles <span class="kw1">then</span> timeout</div>
</li>
</ol>
</div>
<p><strong>NOTA!!</strong> Debemos modificar la ruta del fichero pid de apache a donde lo tengamos alojado. En Debian suele ser <em>/var/run/apache2.pid</em> y los valores que he colocado entre [] por los de nuestro servidor.</p>
<p>Explicado de un modo rápido, le estamos indicando que reinicie el servidor Apache si el servidor presenta uno de los siguientes sintomas:</p>
<ul>
<li>No responde al visitar la url <em>http://[IP_SERVER]/monit/token</em></li>
<li>Apache ocupa más del 80% de la CPU durante 5 ciclos de Monit</li>
<li>La memoria utilizada por Apache es superior a 400MB durante 5 ciclos de Monit</li>
<li>El proceso tiene más de 250 hijos</li>
</ul>
<p>Que nos envíe un mail (siempre que tengamos configurado un servidor de correo) en caso de que:</p>
<ul>
<li>Haya detectado uno de los problemas mencionados anteriormente</li>
<li>Apache ocupa más del 60% de la CPU durante 3 ciclos de Monit</li>
</ul>
<p>Y parará el servidor en caso de error crítico avisandonos vía email.</p>
<p><strong>Configuración de control de MySQL</strong></p>
<p>Para configurar un chequeo del servidor MySQL, añadimos la siguiente información después del bloque configurado anteriormente:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">check process mysql with pidfile /var/run/mysqld/mysqld.pid</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;group database</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;start program = <span class="st0">&quot;/etc/init.d/mysql start&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;stop program = <span class="st0">&quot;/etc/init.d/mysql stop&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp;<span class="kw1">if</span> failed host <span class="nu0">127.0</span><span class="nu0">.0</span><span class="nu0">.1</span> port <span class="nu0">3306</span> <span class="kw1">then</span> restart</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> <span class="nu0">5</span> restarts within <span class="nu0">5</span> cycles <span class="kw1">then</span> timeout</div>
</li>
</ol>
</div>
<p><strong>NOTA!!</strong> Debemos modificar la ruta del fichero pid de mysql a donde lo tengamos alojado. En Debian suele ser <em>/var/run/mysqld/mysqld.pid</em>.</p>
<p><strong>Configuración de control de OpenSsh</strong></p>
<p>Para acabar este tutorial, configuraremos un control del servidor SSH, punto importante, pues si no podemos acceder físicamente a nuestro servidor y no podemos acceder mediante SSH porque este servicio ha caido, tenemos un pequeño problema <img src='http://www.tecnoretales.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p>Añadiremos el siguiente trozo de código acordandonos de cambiar la ruta al fichero sshd.pid a la correspondiente en nuestro servidor:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">check process sshd with pidfile /var/run/sshd.pid</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;start program &nbsp;<span class="st0">&quot;/etc/init.d/ssh start&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;stop program &nbsp;<span class="st0">&quot;/etc/init.d/ssh stop&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> failed port <span class="nu0">22</span> protocol <span class="kw2">ssh</span> <span class="kw1">then</span> restart</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp;<span class="kw1">if</span> <span class="nu0">5</span> restarts within <span class="nu0">5</span> cycles <span class="kw1">then</span> timeout</div>
</li>
</ol>
</div>
<p>Cabe <strong>remarcar la importancia de tener monitorizaciones cruzadas</strong> desde diferentes servidores, pues si, por poner un ejemplo, se corta la conexión en nuestro servidor de producción monitorizado desde la mísma máquina, a pesar de que monit lo detectará, intentará enviar emails que no llegarán (pues no tiene conexión). Para evitar esto y tenemos la suerte de disponer de varios servidores, podemos indicar al server1 que monitorice los servicios de server2 y en caso de fallar, que nos alerte vía mail para poder actuar en consecuencia.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/linux/instalar-monit-para-monitorizar-un-servidor-apache-y-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importar archivos DBF a MySQL</title>
		<link>http://www.tecnoretales.com/linux/importar-archivos-dbf-a-mysql/</link>
		<comments>http://www.tecnoretales.com/linux/importar-archivos-dbf-a-mysql/#comments</comments>
		<pubDate>Wed, 06 May 2009 20:54:39 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=56</guid>
		<description><![CDATA[Pues bien, otro post provocado por una necesidad del curro&#8230; esa necesidad me ha obligado a googlear un ratito y por último, he aquí el resultado.
La cosa está en que me han pasado unos archivos en formato dbf y para poder hacer el tratamiento necesario necesitaba poderlos importar a MySQL. La solucion está en dbf2mysql, [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Pues bien, otro post provocado por una necesidad del curro&#8230; esa necesidad me ha obligado a googlear un ratito y por último, he aquí el resultado.</p>
<p>La cosa está en que me han pasado unos archivos en <strong>formato dbf</strong> y para poder hacer el tratamiento necesario necesitaba poderlos <strong>importar a MySQL</strong>. La solucion está en <em>dbf2mysql</em>, programa que de una manera bastante sencilla se encarga de hacer la importación a la base de datos MySQL.<span id="more-56"></span></p>
<p>Los flags más importantes que nos ofrece dbf2mysql són los siguientes:</p>
<ul>
<li>-h indica server donde conectarse</li>
<li>-U usuario MySql</li>
<li>-P password MySql</li>
<li>-d base de datos donde se insertaran los datos</li>
<li>-t tabla donde se insertarán los datos</li>
<li>-c crea la tabla si no existe</li>
<li>-cc crea la tabla, pero no inserta registros</li>
<li>-f traduce los nombres de campo a minúsculas</li>
<li>-n no se agrega &#8216;NOT NULL&#8217; en las sentencias de creación de tabla</li>
<li>-o exporta solo los campos listados (Ej. -o field1,field2&#8230;)</li>
<li>-s substituye permite cambiar nombres de campos (Ej. -s oldName1=newName1,oldName1=newName1)</li>
<li>-i lista de campos a indexar. Genera UN indice por campo (Ej. -i field1,field2&#8230;)</li>
<li>-r quita espacios antes y después de datos alfanuméricos</li>
<li>-v muestra detalles de la conversión</li>
<li>-vv muestra más detalles</li>
<li>-vvv incluye informe de progreso</li>
</ul>
<p>Los pasos que he siguido para hacer la importacion són:</p>
<p>1) Instalo dbf2mysql, en mi caso desde <a title="Ubuntu" href="http://www.tecnoretales.com/tag/ubuntu/">Ubuntu</a>:</p>
<pre>sudo apt-get install dbf2mysql</pre>
<p>En cualquier caso, nos podemos bajar el programa para sistemas Unix de <a href="http://sourceforge.net/projects/dbf2mysql/" target="blank">Source Forge</a></p>
<p>2) Creo una base de datos MySQL vacia:</p>
<pre>mysql -u [DBUSER] -p -e "CREATE DATABASE `[DBNAME]`"</pre>
<p>3) Por último lanzamos el siguiente comando para indicarle que importe el archivo dbf a la base de datos local, en la tabla [DBTABLE] de la base de datos [DBNAME], entrando con el usuario [DBUSER] y el password [DBPASS]. Mediante el flag -c forzamos a que cree la tabla si no existe y con -f le indicamos que traduzca los nombres de los campos a minusculas:</p>
<pre>dbf2mysql -h localhost -U [DBUSER] -P [DBPASS] -d [DBNAME] -t [DBTABLE] -c -f /path/to/file/miTabla.dbf</pre>
<p>Es importante tener en cuenta que <strong>esta importación no tendra en cuenta algunos atributos importantes</strong> de la tabla como, por ejemplo, los campos autoincrementales. Si tenemos algun problema de este estilo, es recomendable crear la estructura de la tabla antes de realizar la importación.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/linux/importar-archivos-dbf-a-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Convertir base de datos a UTF8</title>
		<link>http://www.tecnoretales.com/bases-de-datos/convertir-base-de-datos-a-utf8/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/convertir-base-de-datos-a-utf8/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 08:10:55 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Encoding]]></category>
		<category><![CDATA[ISO-8859-15]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[UTF8]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=3</guid>
		<description><![CDATA[Hace algún tiempo que tenía ganas de migrar una base de datos de ISO-8859-1 a UTF-8, pero cuando tienes un proyecto funcionando, hacer un cambio de este estilo es algo delicado y por lo tanto, uno intenta postergarlo. En cualquier caso, finalmente decidí liarme la manta a la cabeza y tirarlo adelante.
Por desgracia, no existe [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Hace algún tiempo que tenía ganas de <strong>migrar una base de datos de ISO-8859-1 a UTF-8</strong>, pero cuando tienes un proyecto funcionando, hacer un cambio de este estilo es algo delicado y por lo tanto, uno intenta postergarlo. En cualquier caso, finalmente decidí liarme la manta a la cabeza y tirarlo adelante.</p>
<p>Por desgracia, no existe una sentencia SQL que haga algo similar de manera sencilla, sin embargo, podemos conseguirlo utilizando el comando de Linux recode (evolución bastante más inteligente del antiguo iconv), os dejo detallados los pasos que seguí para hacer el cambio:<span id="more-3"></span></p>
<p>1) <strong>Exportamos</strong> la base de datos mediante el comando mysqldump:</p>
<pre>mysqldump -u  -p -f --single-transaction --opt -hlocalhost --all-databases | gzip -9 -c &gt; [FICHERO_EXPORTACION_BD]</pre>
<p>2) <strong>Recodificamos</strong> el archivo dump mediante el comando recode:</p>
<pre>recode iso-8859-15..utf8 &lt; [FICHERO_EXPORTACION_BD] &gt; [FICHERO_EXPORTACION_BD].utf8</pre>
<p>3) <strong>Editamos</strong> el archivo y reemplazamos &#8220;latin1&#8243; por &#8220;utf8&#8243;</p>
<p>4) <strong>Creamos la nueva base de datos con el encoding utf8</strong>:</p>
<pre>mysql -u [USER] -p [DBNAME] -e "CREATE DATABASE `[DBNAME]` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;"</pre>
<p>5) Por último, <strong>importamos</strong> la base de datos de la siguiente manera:</p>
<pre>mysql -u [USER] -p [DBNAME] &lt; [FICHERO_EXPORTACION_BD].utf8</pre>
<p><strong>NOTA!!</strong> En mi caso concreto, la aplicación PHP seguía mostrando errores al visualizar la información que provenía de base de datos a pesar de haber cambiado convenientemente los metas del html resultante. En mi caso era debido a que la conexión a la base de datos estaba forzada a leer en ISO. Esto lo solventé añadiendo justo después de la conexión:</p>
<pre>@mysql_query("SET character_set_results='utf8'");</pre>
<p>o si nuestra version de PHP es superior o igual a la 5.2.3, tambien podemos hacer:</p>
<pre>@mysql_set_charset("utf8", $link_identifier);</pre>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/convertir-base-de-datos-a-utf8/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

