<?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>Idea Factory &#187; MySQL</title>
	<atom:link href="http://ideafactory.it/category/mysql/feed" rel="self" type="application/rss+xml" />
	<link>http://ideafactory.it</link>
	<description>c&#039;e&#039; solo un modo di fare le cose: farle bene</description>
	<lastBuildDate>Sun, 05 Feb 2012 12:25:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>mysqltuner: migliorare le performance di MySQL</title>
		<link>http://ideafactory.it/mysql/mysqltuner-migliorare-le-performance-di-mysql.html</link>
		<comments>http://ideafactory.it/mysql/mysqltuner-migliorare-le-performance-di-mysql.html#comments</comments>
		<pubDate>Tue, 22 Jun 2010 07:51:47 +0000</pubDate>
		<dc:creator>Gianluca</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://ideafactory.it/?p=289</guid>
		<description><![CDATA[MySQLTuner è uno script Perl che in analizza il server MySQL e suggerisce le impostazioni migliori basandosi sulle statistiche di utilizzo del server. Premesso che MySQLTuner non fa miracoli ma semplici ottimizzazioni, vediamo come installarlo: apt-get install mysqltuner Adesso con un semplice mysqltuner lanciamo il nuovo tool: &#62;&#62; MySQLTuner 0.9.0 - Major Hayden &#62;&#62; Bug [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.mysqltuner.com/" onclick="pageTracker._trackPageview('/outgoing/blog.mysqltuner.com/?referer=');">MySQLTuner</a> è uno script Perl che in analizza il server MySQL e suggerisce le impostazioni migliori basandosi sulle statistiche di utilizzo del server.</p>
<p>Premesso che <a href="http://blog.mysqltuner.com/" onclick="pageTracker._trackPageview('/outgoing/blog.mysqltuner.com/?referer=');">MySQLTuner</a> non fa miracoli ma semplici ottimizzazioni, vediamo come installarlo:</p>
<p><code>apt-get install mysqltuner</code></p>
<p>Adesso con un semplice <em>mysqltuner</em> lanciamo il nuovo tool:<br />
<code><br />
&gt;&gt;  MySQLTuner 0.9.0 - Major Hayden<br />
&gt;&gt;  Bug reports, feature requests, and downloads at http://mysqltuner.com/<br />
&gt;&gt;  Run with '--help' for additional options and output filtering<br />
Please enter your MySQL administrative login: root<br />
Please enter your MySQL administrative password:<br />
-------- General Statistics --------------------------------------------------<br />
[!!] There is a new version of MySQLTuner available<br />
[OK] Currently running supported MySQL version 5.0.51a-24+lenny4-log<br />
[OK] Operating on 64-bit architecture<br />
-------- Storage Engine Statistics -------------------------------------------<br />
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster<br />
[--] Data in MyISAM tables: 4M (Tables: 1311)<br />
[--] Data in InnoDB tables: 300M (Tables: 2275)<br />
-------- Performance Metrics -------------------------------------------------<br />
[--] Up for: 17h 28m 59s (6M q [97.770 qps], 18K conn, TX: 11B, RX: 1B)<br />
[--] Reads / Writes: 84% / 16%<br />
[--] Total buffers: 2.6M per thread and 106.0M global<br />
[OK] Maximum possible memory usage: 368.5M (9% of installed RAM)<br />
[OK] Slow queries: 0% (2/6M)<br />
[OK] Highest usage of available connections: 11% (11/100)<br />
[OK] Key buffer size / total MyISAM indexes: 16.0M/4.7M<br />
[OK] Key buffer hit rate: 99.2%<br />
[OK] Query cache efficiency: 93.5%<br />
[!!] Query cache prunes per day: 362758<br />
[OK] Sorts requiring temporary tables: 0%<br />
[!!] Joins performed without indexes: 5599<br />
[!!] Temporary tables created on disk: 78%<br />
[OK] Thread cache hit rate: 99%<br />
[!!] Table cache hit rate: 0%<br />
[OK] Open file limit used: 0%<br />
[OK] Table locks acquired immediately: 100%<br />
[!!] InnoDB data size / buffer pool: 300.1M/8.0M<br />
-------- Recommendations -----------------------------------------------------<br />
General recommendations:<br />
MySQL started within last 24 hours - recommendations may be inaccurate<br />
Enable the slow query log to troubleshoot bad queries<br />
Adjust your join queries to always utilize indexes<br />
When making adjustments, make tmp_table_size/max_heap_table_size equal<br />
Reduce your SELECT DISTINCT queries without LIMIT clauses<br />
Increase table_cache gradually to avoid file descriptor limits<br />
Variables to adjust:<br />
query_cache_size (&gt; 64M)<br />
join_buffer_size (&gt; 128.0K, or always use indexes with joins)<br />
tmp_table_size (&gt; 32M)<br />
max_heap_table_size (&gt; 16M)<br />
table_cache (&gt; 128)<br />
innodb_buffer_pool_size (&gt;= 300M)<br />
</code></p>
<p>Il risultato è più che eplicito.<br />
MySQLTuner mi dice che vanno aggiunte o modificati i valori, delle seguenti variabili:</p>
<p><code><br />
query_cache_size (&gt; 64M)<br />
join_buffer_size (&gt; 128.0K, or always use indexes with joins)<br />
tmp_table_size (&gt; 32M)<br />
max_heap_table_size (&gt; 16M)<br />
table_cache (&gt; 128)<br />
innodb_buffer_pool_size (&gt;= 300M)<br />
</code></p>
<p>Edito il file di configurazione di MySQL (in Debian <em>/etc/mysql/my.cnf</em>) e lo modifico come suggerito.<br />
Fatta la modifica va ovviamente riavviato il servizio MySQL.</p>
<p>Vedete miglioramenti? <img src='http://ideafactory.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://ideafactory.it/mysql/mysqltuner-migliorare-le-performance-di-mysql.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZRM for MySQL: la soluzione definitiva per il backup di MySQL</title>
		<link>http://ideafactory.it/mysql/zrm-for-mysql-la-soluzione-definitiva-per-il-backup-di-mysql.html</link>
		<comments>http://ideafactory.it/mysql/zrm-for-mysql-la-soluzione-definitiva-per-il-backup-di-mysql.html#comments</comments>
		<pubDate>Thu, 25 Mar 2010 21:15:21 +0000</pubDate>
		<dc:creator>Gianluca</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[backup]]></category>

		<guid isPermaLink="false">http://ideafactory.it/?p=283</guid>
		<description><![CDATA[La maggior parte delle applicazioni (specie quelle web) utilizzano come backend un database. Il database più diffuso in ambito opensource è MySQL forse perché fa parte del mitico quartetto LAMP o semplicemente perché all&#8217;epoca era il dbms più veloce della storia&#8230; Chissà quale sarà il futuro di MySQL, ma in questo post è meglio parlare del presente. Di solito chi [...]]]></description>
			<content:encoded><![CDATA[<p>La maggior parte delle applicazioni (specie quelle web) utilizzano come backend un database.</p>
<p>Il database più diffuso in ambito opensource è MySQL forse perché fa parte del mitico quartetto LAMP o semplicemente perché all&#8217;epoca era il dbms più veloce della storia&#8230; Chissà quale sarà il futuro di MySQL, ma in questo post è meglio parlare del presente.</p>
<p>Di solito chi ha a che fare con MySQL e vuole salvare i preziosi dati contenuti al suo interno, effettua un backup del database (o dei databases) e salva il dump da qualche parte.<br />
Nulla da eccipere a questo modus operandi.<br />
Ma se il db è grande quanto spazio occupa un backup? Quanto tempo ci si impiega a fare un dump?<br />
Mi è capitato che durante un backup di MySQL l&#8217;utilizzo delle risorse schizzasse alle stelle e quindi mi sono messo alla ricerca di un sistema di backup degno di chiamarsi tale e la soluzione è stata <a href="http://www.zmanda.com/backup-mysql.htm" onclick="pageTracker._trackPageview('/outgoing/www.zmanda.com/backup-mysql.htm?referer=');">ZRM fro MySQL</a>.<br />
<a href="http://www.zmanda.com/backup-mysql.htm" onclick="pageTracker._trackPageview('/outgoing/www.zmanda.com/backup-mysql.htm?referer=');"> Zmanda Recovery Manager (ZRM) for MySQL</a> è un tool che permette di:</p>
<ul>
<li>effettuare backup incrementali o full</li>
<li>avere una gestione centralizzata dei backup</li>
<li>ricevere notifiche via e-mail, RSS ed HTML sull&#8217;esito dei backup</li>
<li>effettuare backup compressi e criptati</li>
<li>ripristino dei backup in modo facile</li>
<li>&#8230;e molto altro ancora!</li>
</ul>
<p>Per altri features ed informazioni consiglio di leggere il <a href="http://wiki.zmanda.com/index.php/MySQL_Backup_and_Recovery  " onclick="pageTracker._trackPageview('/outgoing/wiki.zmanda.com/index.php/MySQL_Backup_and_Recovery?referer=');">WiKi</a>.</p>
<p>In questo primo post vedremo come configurare un backup di un server MySQL che si trova sulla stessa macchina dove risiede MySQL. Ovviamente il backup potrà essere salvato su una partizione NFS o su una chiavetta USB ma in sostanza ZRM e MySQL sono sulla stessa macchina.<span id="more-283"></span>Nel prossimo articolo vedremo come fare un backup di un server MySQL remoto.</p>
<p>Procediamo con l&#8217;installazione, ovviamente su Debian.<br />
Nei repository Debian non c&#8217;è il pacchetto (eresiaaaa!) ma dal sito possiamo scaricare il comodissimo .deb:</p>
<p><em>http://www.zmanda.com/download-zrm.php</em></p>
<p>Basta selezionare l&#8217;ultima release (ad oggi la 2.2) e nella pagina successiva possiamo fare il download del pacchetto  <em>mysql-zrm-client_2.2.0_all.deb</em>.</p>
<p>Prima di installarlo abbiamo bisogno di alcuni software a corredo: <em>perl-DBI </em>e <em>perl-XML-parser</em>.</p>
<p>Installiamo:</p>
<p><code>apt-get install libxml-parser-perl libdbd-mysql-perl</code></p>
<p>Se tutto è andato a buon fine installiamo ZRM con:</p>
<p><code>dpkg -i mysql-zrm_2.2.0_all.deb</code></p>
<p>Adesso abbiamo ciò che ci serve, ma per fare i backup incrementali abbiamo bisogno che MySQL scriva il suo utilissimo logbin.<br />
Per abilitare questa opzione, basta editare <em>/etc//mysql/my.cnf</em> e decommentare:</p>
<p><code>log_bin                 = /var/log/mysql/mysql-bin.log<br />
expire_logs_days        = 10<br />
max_binlog_size         = 100M</code></p>
<p>Adesso il file va salvato e si deve riavviare il server MySQL.</p>
<p>I file di configurazione si trovano nella directory <em>/etc/mysql-zrm</em>, andiamo a vedere cosa c&#8217;è dentro:</p>
<ul>
<li><em>mysql-zrm.conf</em></li>
<li><em>mysql-zrm-release</em></li>
<li><em>mysql-zrm-reporter.conf</em></li>
<li><em>RSS.header</em></li>
</ul>
<p>Di vitale importanza sono i <em>.conf</em>, perché <em>mysql-zrm-release</em> ci dice che versione abbiamo e <em>RSS.header </em>è autoeplicativo, serve per l&#8217;RSS generato dal sistema di backup.</p>
<p>Dentro la directory <em>/etc/mysql-zrm</em> possiamo creare una nuova directory e dentro copiare i <em>.conf </em>appena illustrati.<br />
Ciò ci permette di avere vari set di backup che hanno delle configurazioni proprie ed in più ereditano quelle presenti sotto <em>/etc/mysql-zrm</em>.<br />
Esempio pratico: se tutti i database hanno la password di root identica possiamo specificare username e password nel file <em>/etc/mysql-zrm/mysql-zrm.conf</em> e non nel file <em>mysql-zrm.conf</em> presente nella directory del set.</p>
<p>Passiamo dalla teoria alla pratica.<br />
Voglio fare in modo che venga fatto un backup di svariati server che hanno in comune:</p>
<ul>
<li>la password di root di MySQL</li>
<li>la directory di destinazione dove salvare i file</li>
<li>il tipo di backup</li>
<li>uso di routines e quindi il backup delle stesse</li>
<li>la directory dove sono salvati i logbin di MySQL</li>
<li>la directory temporanea</li>
<li>l&#8217;indirizzo e-mail sul quale riceve le notifiche</li>
<li>il tipo di report</li>
<li>il path dove salvare i report html</li>
<li>la URL dal quale consultare i report html</li>
<li>il path da dove prendere l&#8217;header per l&#8217;RSS</li>
</ul>
<p>Detto questo avremo che il file <em>/etc/mysql-zrm/mysql-zrm.conf </em>conterrà (nel mio caso, mi raccomando personalizzate i parametri) questo:</p>
<p><code>backup-mode=logical<br />
destination=/mnt/nfs/mysql-zrm<br />
routines=1<br />
mysql-binlog-path="/var/log/mysql"<br />
tmpdir=/tmp<br />
mailto="info@ideafactory.it"<br />
html-reports=backup-status-info,backup-performance-info<br />
html-report-directory=/var/www/mysql-zrm/reports/<br />
webserver-url=http://backup.ideafactory.it/reports/html/<br />
rss-header-location=/etc/mysql-zrm/</code></p>
<p>Adesso mi creo il file di configurazione per il set che chiamerò &#8221;silver&#8221;  e quindi creerò la directory <em>/etc/mysql-zrm/silver</em> ed il file <em>mysql-zrm.conf</em> al suo interno conterrà (ripeto: nel mio caso!) :</p>
<p><code>comment=Silver<br />
backup-level=0<br />
all-databases=1<br />
user="root"<br />
password="superpasswordsegreta"<br />
retention-policy=7D<br />
host="localhost"<br />
port=3306<br />
socket=/var/run/mysqld/mysqld.sock</code></p>
<p>Ci siamo. Proviamo ad eseguire un backup di prova con:</p>
<p><code>mysql-zrm-scheduler --now --backup-set silver</code></p>
<p>Ovviamente a me il set si chiama silver&#8230;</p>
<p>Prima di spiegare i vari comandi penso sia il caso di illustrare i parametri di configurazione.<br />
Maggiori dettagli si trovano nel <a href="http://wiki.zmanda.com/index.php/Backup_Set_Parameters  " onclick="pageTracker._trackPageview('/outgoing/wiki.zmanda.com/index.php/Backup_Set_Parameters?referer=');">capitolo dedicato ai parametri </a>dell&#8217;ottimo <a href="http://wiki.zmanda.com/index.php/Zmanda_Recovery_Manager_for_MySQL_Users_Manual" onclick="pageTracker._trackPageview('/outgoing/wiki.zmanda.com/index.php/Zmanda_Recovery_Manager_for_MySQL_Users_Manual?referer=');">manuale di ZRM</a>.</p>
<p>Il set &#8220;silver&#8221; fa un backup completo (<em>backup-level=0</em>) di tutti i database (<em>all-databases=1</em>)  presenti sul server locale infatti ho chiamato il set silver proprio come il server così rende l&#8217;idea che il backup è di tutti i database presenti.</p>
<p>Adesso proviamo a dare un backup incrementale.</p>
<p>Non serve editare il file di configurazione del set, perché se passiamo il parametro da linea di comando <em>backup-level=1</em> viene ignorato quello presente nel file di configurazione. Proviamo:</p>
<p><code>mysql-zrm-scheduler --now --backup-set silver --backup-level=1</code></p>
<p>Non vengono fuori errori? Avete ricevuto la comoda e-mail? <img src='http://ideafactory.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Adesso è il caso di fare qualche strage al database e provare a fare un ripristino ma prima vediamo un report dei backup effettuati con il comodo comando:</p>
<p><code>mysql-zrm-reporter --show backup-status-info</code></p>
<p>Sotto forma tabellare comparirà un comodissimo riassunto che qui non riporto per motivi di formattazione ma è ben visibile nella documentazione.</p>
<p>Bene, facciamo fuori un database! <img src='http://ideafactory.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  L&#8217;ho appena fatto con un DROP DATABASE&#8230;!</p>
<p>Adesso vediamo come ripristinarlo.</p>
<p>La prima domanda è &#8220;che backup ho del set a cui apparteneva il defunto database?&#8221; La risposta viene da qui:</p>
<p><code>mysql-zrm-reporter -show restore-info --where backup-set=silver</code></p>
<p>Dalla lista scelgo il backup corretto è con un semplice:</p>
<p><code>mysql-zrm --action restore --backup-set silver --source-directory /mnt/ibm/mysql-zrm/silver/20100325214251</code></p>
<p>Abbiamo riportato in vita il db defunto partendo dallo snapshot posizionato nella directory illustrata dal report!</p>
<p>Se abbiamo cancellato 2 database e ne vogliamo ripristinare solo uno? Beh le opzioni offerte sono molteplici e la <a href="http://wiki.zmanda.com/index.php/Selective_Recovery" onclick="pageTracker._trackPageview('/outgoing/wiki.zmanda.com/index.php/Selective_Recovery?referer=');">guida sul recovery presente nella documentazione</a> ci mostra comandi per risolvere anche i casi disperatissimi!</p>
<p>Fin ora abbiamo visto come fare un backup e come ripristinarlo, una volta scelta la policy più appropriata alle nostre esigenze è il caso di <a href="http://wiki.zmanda.com/index.php/Daily/_Weekly/_Monthly_Schedules" onclick="pageTracker._trackPageview('/outgoing/wiki.zmanda.com/index.php/Daily/_Weekly/_Monthly_Schedules?referer=');">schedulare i backup</a>:</p>
<p><code>mysql-zrm-scheduler --add -interval daily --start 08:00 --backup-set silver --backup-level 0<br />
mysql-zrm-scheduler --add -interval daily --start 14:00 --backup-set silver --backup-level 1<br />
mysql-zrm-scheduler --add -interval daily --start 19:00 --backup-set silver --backup-level 1</code></p>
<p>Con questi 3 semplici ed esplicativi comandi ho detto al mio nuovo amizo ZRM di fare 3 backup:</p>
<ol>
<li>il primo alle 8.00 di mattina ed è un full backup</li>
<li>il secondo alle 14.00 ed è di tipo incrementale</li>
<li>il terzo alle 19.00 ed è sempre incrementale</li>
</ol>
<p>Le opzioni sono svariate ed accontenteranno tutti. Una domanda sorge spontanea: <em>ma i backup vecchi quando vengono cancellati</em>? Questo viene deciso dal parametro <em>retention-policy</em>, presente nel file di configurazione.</p>
<p>Per questo primo episodio dedicato a ZRM è tutto, spero di aver stimolato la vostra voglia di backup e la curiosità nello spulciare le mille opzioni di questo indispensabile software.</p>
]]></content:encoded>
			<wfw:commentRss>http://ideafactory.it/mysql/zrm-for-mysql-la-soluzione-definitiva-per-il-backup-di-mysql.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sincronizzare due database MySQL via SSH</title>
		<link>http://ideafactory.it/linux/sincronizzare-due-database-mysql-via-ssh.html</link>
		<comments>http://ideafactory.it/linux/sincronizzare-due-database-mysql-via-ssh.html#comments</comments>
		<pubDate>Mon, 02 Mar 2009 12:07:22 +0000</pubDate>
		<dc:creator>Gianluca</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SSH]]></category>

		<guid isPermaLink="false">http://www.ideafactory.it/?p=136</guid>
		<description><![CDATA[MySQL supporta nativamente la configurazione master/slave tra due database ma in questo modo si può scrivere solo sul master. Se si ha la necessità di  avere due database identici ed eseguire su entrambi operazioni di scrittura è necessario sincronizzarli in qualche modo. Si può optare per rsync e quindi aggiornare i file che compongono il [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL supporta nativamente <a href="http://www.ideafactory.it/debian/mysql-replicazione-database.html" onclick="pageTracker._trackPageview('/outgoing/www.ideafactory.it/debian/mysql-replicazione-database.html?referer=');">la configurazione master/slave tra due database</a> ma in questo modo si può scrivere solo sul master.</p>
<p>Se si ha la necessità di  avere due database identici ed eseguire su entrambi operazioni di scrittura è necessario sincronizzarli in qualche modo. Si può optare per <em>rsync</em> e quindi aggiornare i file che compongono il database o, come nel caso che vedremo tra poco, usare i comandi di MySQL e muovere i dati via SSH.</p>
<p>Supponiamo di voler trasferire il dump di un database locale in un db remoto, il comando è questo:<br />
<code><br />
ssh user@www.my_domain.com "mysqldump<br />
-u my_remote_db_username --password=my_remote_db_password my_remote_db_name"<br />
| mysql -u my_local_db_username --password=my_local_db_password --host=localhost -C my_local_db_name<br />
</code><br />
Viceversa, dal database remoto a quello locale:<br />
<code>mysqldump -u my_local_db_username --password=my_local_db_password --host=localhost -C my_local_db_name | ssh user@www.my_domain.com "mysql -u my_remote_db_username --password=my_remote_db_password my_remote_db_name" </code></p>
<p>Facile no?</p>
<p>Usando SSH con autenticazione a chiave pubblica è possibile automatizzare la sincronizzazione con crond e quindi schedulare il processo di aggiornameno.</p>
]]></content:encoded>
			<wfw:commentRss>http://ideafactory.it/linux/sincronizzare-due-database-mysql-via-ssh.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>MySQL 5 su Mac OS X Leopard</title>
		<link>http://ideafactory.it/apple/mysql-5-su-mac-os-x-leopard.html</link>
		<comments>http://ideafactory.it/apple/mysql-5-su-mac-os-x-leopard.html#comments</comments>
		<pubDate>Mon, 07 Apr 2008 08:58:45 +0000</pubDate>
		<dc:creator>Gianluca</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Leopard]]></category>
		<category><![CDATA[Mac OS X]]></category>

		<guid isPermaLink="false">http://www.ideafactory.it/2008/04/07/mysql-5-su-mac-os-x-leopard/</guid>
		<description><![CDATA[Nel precedente post ho descritto come installare PHP 5, adesso è il turno di MySQL 5. Per scaricare la versione open-source del celebre database server bisogna recarsi qui: http://dev.mysql.com/downloads/mysql/5.0.html#macosx-dmg Scegliere il pacchetto più adatto all&#8217;hardware ed alla versione di Mac OS X che si possiede. Il file .dmg scaricato contiene il server vero e proprio [...]]]></description>
			<content:encoded><![CDATA[<p>Nel precedente post ho descritto <a href="http://www.ideafactory.it/2008/04/07/php-5-su-mac-os-x-leopard/" onclick="pageTracker._trackPageview('/outgoing/www.ideafactory.it/2008/04/07/php-5-su-mac-os-x-leopard/?referer=');">come installare PHP 5</a>, adesso è il turno di <a href="http://www.mysql.com/" onclick="pageTracker._trackPageview('/outgoing/www.mysql.com/?referer=');">MySQL</a> 5.</p>
<p>Per scaricare la versione open-source del celebre database server bisogna recarsi qui:</p>
<p><a href="http://dev.mysql.com/downloads/mysql/5.0.html#macosx-dmg" onclick="pageTracker._trackPageview('/outgoing/dev.mysql.com/downloads/mysql/5.0.html_macosx-dmg?referer=');">http://dev.mysql.com/downloads/mysql/5.0.html#macosx-dmg</a></p>
<p>Scegliere il pacchetto più adatto all&#8217;hardware ed alla versione di Mac OS X che si possiede.</p>
<p>Il file .dmg scaricato contiene il server vero e proprio ed il comodissimo tool, <em>MySQL.prefPane</em>, che aggiunge alle &#8220;Preferenze di sistema&#8221; la possibilità di avviare MySQL.<span id="more-66"></span></p>
<p>Installiamo prima il server e poi  <em>MySQL.prefPane</em><em>.</em></p>
<p>Un bel messaggio di conferma vi segnalerà che l&#8217;installazione del server è andata a buon fine.</p>
<p>Cliccando su <em>MySQL.prefPane</em> vi verrà chiesta conferma per l&#8217;aggiunta di &#8220;<em>MySQL</em>&#8221; al pannello delle preferenze quindi selezionate &#8220;<em>Installa</em>&#8221; ed immettete la password.</p>
<p>Adesso, in perfetto stile Apple, vi basterà cliccare su &#8220;<em>Start MySQL Server</em>&#8221; ed il potente DBMS sarà al vostro servizio.</p>
<p>Sicuramente si avrà la necessità di usare PHP con MySQL e per non incappare in questo errore:</p>
<p>Non parte? Bene, o meglio non bene&#8230;</p>
<p>La versione che ho provato ad installare io è la 5.0.51 ed ha un piccolo BUG: il file di avvio di MySQL, chiamato MySQLCOM viene creato in <em>/usr/local</em> e non in <em>/Library/StartupItems/</em> quindi con un semplice:</p>
<p><code><br />
sudo mv /usr/local/MySQLCOM /Library/StartupItems/<br />
</code></p>
<p>E&#8217; necessario anche verificare i permessi della direcory <em>/usr/local/mysql/data</em>, se con:<br />
<code><br />
ls -al /usr/local/mysql/data/<br />
</code><br />
Avete in risposta un bruttissimo &#8220;<em>ls: : Permission denied</em>&#8220;, è necessario cambiare i permessi alla directory di MySQL:<br />
<code><br />
sudo chown -R <nomeutente> /usr/local/mysql/data<br />
</nomeutente></code><br />
Adesso tutto dovrebbe funzionare e di certo questi piccoli problemini saranno risolti nelle prossime versioni di MySQL per Mac OS X.</p>
<p>Sicuramente si avrà la necessità di usare PHP 5 con MySQL per non incappare in questo errore:<br />
<code><br />
Can't connect to local MySQL server through socket '/var/mysql/mysql.sock'<br />
</code><br />
bisogna configurare PHP a cercare il file di <em>sock</em> nella posizione dove MySQL lo crea.</p>
<p>Nella directory <em>/private/etc/</em>, è presente il file <em>php.ini.default</em>, va rinominato:<br />
<code><br />
sudo mv /private/etc/php.ini.default /private/etc/php.ini<br />
</code></p>
<p>Adesso è necessario editarlo e cambiare queste due direttive:<br />
<code><br />
mysql.default_socket =<br />
mysqli.default_socket =<br />
</code><br />
in:<br />
<code><br />
mysql.default_socket = /private/tmp/mysql.sock<br />
mysqli.default_socket = /private/tmp/mysql.sock<br />
</code></p>
<p>Sarà necessario salvare il file <em>php.ini</em> ed riavviare Apache.</p>
]]></content:encoded>
			<wfw:commentRss>http://ideafactory.it/apple/mysql-5-su-mac-os-x-leopard.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL: Replicazione database</title>
		<link>http://ideafactory.it/debian/mysql-replicazione-database.html</link>
		<comments>http://ideafactory.it/debian/mysql-replicazione-database.html#comments</comments>
		<pubDate>Fri, 10 Aug 2007 14:40:47 +0000</pubDate>
		<dc:creator>Gianluca</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.ideafactory.it/2007/08/10/mysql-replicazione-database/</guid>
		<description><![CDATA[Teoria: two is meglio che one! Pratica: La replicazione fornita da MySQL si definisce &#8220;one-way&#8220;, perché tale operazione è gestita dal server in modo monodirezionale, ovvero consente di replicare le operazioni di scrittura effettuate su un database master su più database slave. Come è lecito aspettarsi i server slave saranno utilizzati solo per le letture [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Teoria</strong>: two is meglio che one!</p>
<div align="center">
<img src="http://www.trovagratis.net/sfondi/Sfondi-1/animali/arc_animali/delfini.jpg" title="Due delfini" alt="Due delfini" align="middle" height="192" width="256" />
</div>
<p><strong>Pratica</strong>:</p>
<p>La replicazione fornita da MySQL si definisce &#8220;<em>one-way</em>&#8220;,  perché tale operazione è gestita dal server in modo monodirezionale, ovvero consente di replicare le operazioni di scrittura effettuate su un database <em>master</em> su più database <em>slave</em>.</p>
<p>Come è lecito aspettarsi i server <em>slave</em> saranno utilizzati solo per le letture mentre, sul <em>master,</em> graveranno gli inserimenti e gli update (nessuno vieta di utilizzarlo anche per le operazioni di <em>select</em>).</p>
<p>Il procedimento di replicazione di MySQL si riassume in questi step:</p>
<ol>
<li>Il <em>master</em> registra le query di scrittura (inserimento, update etc) in un file</li>
<li>I server <em>slave</em> leggono il file di log del master ed eseguono le operazioni lì riportate aggiornando il database locale</li>
</ol>
<p>Il rapporto tra <em>master</em> e <em>slave</em> è così definito:</p>
<ul>
<li>un <em>master</em> può avere più <em>slave</em></li>
<li>uno <em>slave</em> può avere un solo <em>master</em></li>
</ul>
<p>Bene si parte.</p>
<p><span id="more-24"></span></p>
<p><strong>Configuriamo il master</strong></p>
<p>Prima di tutto:</p>
<p><code> /etc/init.d/mysql stop</code></p>
<p>Così non si fanno disastri con il server up.</p>
<p>Utilizzando Debian è necessario editare il file <em>/etc/mysql/my.cnf</em>  per abilitare il networking e la scrittura del file di log:<br />
<code><br />
#skip-networking<br />
bind-address            = [indirizzo_ip_raggiungibile_dal_server_slave]<br />
server-id               = 1<br />
log_bin                 = /var/log/mysql/mysql-bin.log<br />
expire_logs_days        = 10<br />
max_binlog_size         = 100M<br />
binlog_do_db            = [nome_db_da_replicare]<br />
</code><br />
Adesso per sicurezza, cancelliamo (se presenti) i file di log dentro <em>/var/log/mysql/</em> che iniziano con <em>mysql-bin.*</em>.</p>
<p>Questo serve per far ricreare al server un file di log pulito ed a prova di errore.<br />
A questo punto facciamo ripartire il server con il classico</p>
<p><code><br />
/etc/init.d/mysql start </code></p>
<p>Ripartito il server, accediamo via consolle a MySQL:<br />
<code><br />
mysql -u root -p<br />
</code><br />
E diciamo a MySQL di consentire la replica al nostro <em>slave</em>:<br />
<code><br />
GRANT REPLICATION SLAVE ON *.* TO '[nome_utente]'@'[indirizzo_ip_dello_slave]' IDENTIFIED BY '[password]';<br />
FLUSH PRIVILEGES;<br />
</code><br />
Ora bisogna selezionare il database da replicare e sbloccare eventuali <em>lock</em> di lettura per spostare i dati (se presenti) dal <em>master</em> allo <em>slave</em>:<br />
<code><br />
USE [nome_database];<br />
FLUSH TABLES WITH READ LOCK;<br />
</code><br />
Controlliamo lo stato del <em>master</em>:<br />
<code><br />
SHOW MASTER STATUS;<br />
</code><br />
Dovrebbe venir fuori qualcosa del genere:<br />
<code><br />
mysql&gt; SHOW MASTER STATUS;<br />
+------------------+----------+--------------+------------------+<br />
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |<br />
+------------------+----------+--------------+------------------+<br />
| mysql-bin.000001 |       98 | [nome_db]     |                  |<br />
+------------------+----------+--------------+------------------+<br />
1 row in set (0.00 sec)<br />
</code></p>
<p>Bene, adesso usciamo dalla shell di MySQL (con il classico <em>quit;</em>) ed esportiamo il database in un file sql da traferire sul server <em>slave</em>:<br />
<code><br />
mysqldump -u root -p --opt [nome_db] &gt; [nome_db].sql<br />
</code></p>
<p><strong>Configuriamo lo slave</strong></p>
<p>E&#8217; necessario creare il database da replicare quindi entriamo nella consolle del server MySQL:</p>
<p><code><br />
mysql -u root -p<br />
Enter password:<br />
CREATE DATABASE [nome_db];<br />
quit;<br />
</code></p>
<p>Importiamo il dump SQL del server master:</p>
<p><code><br />
mysql -u root -p  [nome_db] &lt; [path_dove_e_salvato_il_file]/[nome_db].sql<br />
</code></p>
<p>Adesso bisogna editare il file <em>/etc/mysql/my.cnf</em>  per abilitare la lettura del file di log del <em>master</em>:<br />
<code><br />
server-id=2<br />
master-host=[ip_master]<br />
master-user=[user_creato_sul_master]<br />
master-password=[password]<br />
master-connect-retry=60<br />
replicate-do-db=[nome_db]<br />
</code><br />
Le direttive per il log bin sul server <em>slave</em> possono essere disabilitate.</p>
<p>Bene, abbiamo finito, un bel riavvio e siamo a posto:<br />
<code><br />
/etc/init.d/mysql restart</code></p>
<p>Ogni cosa che scrivete sul <em>master</em> verrà (forse <img src='http://ideafactory.it/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) replicato in pochi millesimi di secondo sullo <em>slave</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ideafactory.it/debian/mysql-replicazione-database.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Trovare ed eliminare record duplicati</title>
		<link>http://ideafactory.it/mysql/trovare-ed-eliminare-record-duplicati.html</link>
		<comments>http://ideafactory.it/mysql/trovare-ed-eliminare-record-duplicati.html#comments</comments>
		<pubDate>Thu, 26 Jul 2007 17:25:47 +0000</pubDate>
		<dc:creator>Gianluca</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.ideafactory.it/?p=29</guid>
		<description><![CDATA[Oggi mentre aggiornavo Roundcube alla versione corrente sono incappato in un problema che in teoria non di dovrebbe mai verificare in un db: tuple duplicate. L&#8217;errore è venuto fuori eseguendo questa query: ALTER TABLE `messages` DROP `body`, DROP INDEX `cache_key`, ADD `structure` TEXT, ADD UNIQUE `uniqueness` (`user_id`, `cache_key`, `uid`); Che ha lo scopo di adeguare [...]]]></description>
			<content:encoded><![CDATA[<p>Oggi mentre aggiornavo <a href="http://www.roudcube.net" onclick="pageTracker._trackPageview('/outgoing/www.roudcube.net?referer=');">Roundcube</a> alla versione corrente sono incappato in un problema che in teoria non di dovrebbe mai verificare in un db: tuple duplicate.</p>
<p>L&#8217;errore è venuto fuori eseguendo questa query:<br />
<code>ALTER TABLE `messages`<br />
DROP `body`,<br />
DROP INDEX `cache_key`,<br />
ADD `structure` TEXT,<br />
ADD UNIQUE `uniqueness` (`user_id`, `cache_key`, `uid`);<br />
</code><br />
Che ha lo scopo di adeguare il vecchio db con la struttura nuova.<br />
In particolare il problema si verificava aggiungendo l&#8217;indice univoco composto da <code>`user_id`, `cache_key`, `uid`.</code><br />
Siccome seguo <a href="http://www.roudcube.net" onclick="pageTracker._trackPageview('/outgoing/www.roudcube.net?referer=');">Roundcube</a> da prima che gli spuntassero i primi dentini è normale che ci sono stati errori nello sviluppo e quindi è logico che si è arrivati ad un problema simile.<br />
<span id="more-23"></span><br />
Come si procede per risolvere l&#8217;inconveniente? In due semplici step:</p>
<ol>
<li>Si elencano i valori duplicati</li>
<li>Si eliminano i valori duplicati</li>
</ol>
<p>Prima di togliere i valori duplicati l&#8217;errore era questo:</p>
<p><code>#1062 - Duplicate entry '8-INBOX.msg-1' for key 2</code></p>
<p>Giusto per rendere il più pratico possibile l&#8217;articolo&#8230;</p>
<p>Procediamo con il passo1:<br />
Per elencare i valori duplicati basta usare questa query:<br />
<code><br />
SELECT `cache_key` , `uid` , `user_id`, COUNT(*) AS quanti<br />
FROM `messages`<br />
GROUP BY `cache_key` , `uid` , `user_id`<br />
HAVING quanti > 1;</code><br />
Seleziono i campi coinvolti nella creazione dell&#8217;indice univoco ed in più conto le occorrenze, infine raggruppo i valori per i campi selezionati e mostro solo quelli che hanno occorrenza maggiore di 1.<br />
Il risultato <em>spaventoso</em> della query è:<br />
<code><br />
cache_key 	uid 	user_id 	quanti<br />
INBOX.msg 	1 		8 			2<br />
INBOX.msg 	2 		70 			2<br />
INBOX.msg 	3 		30 			2<br />
INBOX.msg 	5 		101 		3<br />
INBOX.msg 	28 		43 			4<br />
INBOX.msg 	40 		43 			3<br />
INBOX.msg 	42 		43 			2<br />
INBOX.msg 	45 		43 			2<br />
INBOX.msg 	52 		43 			2<br />
INBOX.msg 	53 		43 			2<br />
INBOX.msg 	57 		101 		3<br />
INBOX.msg 	63 		101 		5<br />
INBOX.msg 	84 		101 		2<br />
INBOX.msg 	85 		101 		2<br />
INBOX.msg 	1155 	68 			2<br />
INBOX.msg 	1156 	68 			2<br />
INBOX.msg 	1920 	7 			3<br />
INBOX.msg 	3362 	7 			2<br />
INBOX.msg 	3363 	7 			2<br />
</code><br />
Bene adesso occorre visualizzare e distruggere!<br />
Con questa query:<br />
<code><br />
SELECT *<br />
FROM `messages`<br />
WHERE `cache_key` = 'INBOX.msg'<br />
AND `uid` =1<br />
AND `user_id` =8</code><br />
si selezionano le occorenze della prima tupla duplicata e quindi è sufficiente cancellare quelle in eccesso. Io ho sempre lasciato la più vecchia, massimo rispetto per gli anziani. <img src='http://ideafactory.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Ripetere la query modificando opportunamente parametri per tutte le tuple duplicate.</p>
<p>Finito?<br />
Proviamo adesso a rieseguire la query&#8230;.FUNZIONA!<br />
Infine voglio regalare una chicca, mettendo dopo <em>ALTER</em>, prima di <em>TABLE</em>, la clausola <em>IGNORE</em> il DBMS non si ferma al primo errore di record duplicato, ma va avanti, e di fatto salta l&#8217;inserimento dei record con valori già inseriti.<br />
Quindi la fatica di prima era evitabile!<br />
Hihihi che dispettoso vero? Sento gli insulti&#8230;<br />
Non l&#8217;ho detto subito perché non l&#8217;ho mai provato e a me piace fare le cose a manina per verificare con i miei occhi che tutto sia a posto.<br />
Quando riavrò il medesimo problema userò <em>IGNORE</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ideafactory.it/mysql/trovare-ed-eliminare-record-duplicati.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

