<?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>guzik &#187; mysql-proxy</title>
	<atom:link href="http://guzik.net.pl/blog/tag/mysql-proxy/feed/" rel="self" type="application/rss+xml" />
	<link>http://guzik.net.pl/blog</link>
	<description>Mój blog</description>
	<lastBuildDate>Wed, 28 Jul 2010 20:35:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Trochę Lua w mysql-proxy</title>
		<link>http://guzik.net.pl/blog/2009/11/troche-lua-w-mysql-proxy/</link>
		<comments>http://guzik.net.pl/blog/2009/11/troche-lua-w-mysql-proxy/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 12:31:38 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[LUA]]></category>
		<category><![CDATA[mysql-proxy]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=1181</guid>
		<description><![CDATA[Replikacja baz MySQL działa jako tako. Jeśli to typ MASTER &#8211; SLAVE, to na ogół ten drugi serwer się nudzi. Skoro się nudzi, można wykorzystać go do zapytań, które nie zmieniają niczego (SELECT). Jeśli oddamy go w takim stanie programiście, to pewne jest, że prędzej czy później będzie to jego serwer testowy i dziać się [...]]]></description>
			<content:encoded><![CDATA[<p><a title="http://guzik.net.pl/blog/2008/07/replikacja-baz-mysql/" href="http://forge.mysql.com/wiki/MySQL_Proxy"><img class="alignleft" title="mysql-proxy logo" src="http://forge.mysql.com/w/images/9/93/Sakila_proxy_256x298.jpg" alt="" width="256" height="298" />Replikacja baz MySQL</a> działa jako tako. Jeśli to typ MASTER &#8211; SLAVE, to na ogół ten drugi serwer się nudzi. Skoro się nudzi, można wykorzystać go do zapytań, które nie zmieniają niczego (<a title="http://dev.mysql.com/doc/refman/5.0/en/select.html" href="http://dev.mysql.com/doc/refman/5.0/en/select.html"><code>SELECT</code></a>). Jeśli oddamy go w takim stanie programiście, to pewne jest, że prędzej czy później będzie to jego serwer testowy i dziać się będą na nim różne rzeczy.<br />
<span id="more-1181"></span><br />
Pewnie sposobów na ograniczenie tego jest parę, ja zrobiłem to wykorzystując <a title="http://forge.mysql.com/wiki/MySQL_Proxy" href="http://forge.mysql.com/wiki/MySQL_Proxy">mysql-proxy</a> i odpowiedni skrypt <a title="http://www.lua.org/" href="http://www.lua.org/">Lua</a>. A wygląda to tak:</p>
<blockquote><p><code>function read_query( packet )<br />
--      local log_file = '/var/log/mysql-proxy.log'<br />
--      local fh = io.open(log_file, 'a+')<br />
if string.byte(packet) == proxy.COM_QUERY then<br />
local query = string.sub(packet, 2)<br />
if not (string.match(string.upper(query), '^%s*SELECT') or string.match(string.upper(query), '^%s*SHOW')) then<br />
--                      fh:write(string.format("%s %s\t%s\t%s\t%s\n", os.date('%Y-%m-%d %H:%M:%S'), proxy.connection.client.address, proxy.connection.client.username, proxy.connection.client.default_db, query))<br />
proxy.response.type = proxy.MYSQLD_PACKET_ERR<br />
proxy.response.errmsg = "Only SELECT and SHOW queries are available"<br />
return proxy.PROXY_SEND_RESULT<br />
end<br />
end<br />
--      fh:flush()<br />
end</code></p></blockquote>
<p>W powyższym kodzie zakomentowałem linijki odpowiadające za logowanie wszystkiego, co nie zaczyna się od <code>SELECT</code> lub <code>SHOW</code>.</p>
<p>Przy okazji poznałem głębiej jak działają takie skrypty (<a title="http://guzik.net.pl/blog/2008/07/sprawdzanie-aktywnosci-uzytkownikow-mysql/" href="http://guzik.net.pl/blog/2008/07/sprawdzanie-aktywnosci-uzytkownikow-mysql/">kiedyś coś tam już grzebałem</a>). Do tego doszedłem:</p>
<ul>
<li><a title="http://dev.mysql.com/doc/refman/5.0/en/mysql-proxy-scripting-structures.html#mysql-proxy-scripting-structures-queries" href="http://dev.mysql.com/doc/refman/5.0/en/mysql-proxy-scripting-structures.html#mysql-proxy-scripting-structures-queries"><code>proxy.queries</code></a> to kolejka zapytań, które sami (w skrypcie) stworzymy. <code>reset()</code> nie usunie nam zapytania, które przesyła klient (tym samym <code>len()</code> zawsze pokaże 0),</li>
<li>jeżeli nie będziemy manipulować kolejką, to do serwera zawsze dojdzie to co wysłał klient,</li>
<li>manipulować kolejką możemy poprzez np. <code>append()</code>, a następnie wysyłać zapytania przez <a title="http://dev.mysql.com/doc/refman/5.0/en/mysql-proxy-scripting-structures.html#mysql-proxy-scripting-structures-return-states" href="http://dev.mysql.com/doc/refman/5.0/en/mysql-proxy-scripting-structures.html#mysql-proxy-scripting-structures-return-states"><code>proxy.PROXY_SEND_QUERY</code></a>,</li>
<li>możemy zupełnie pominąć to co wysyła klient i przygotować dla niego <a title="http://dev.mysql.com/doc/refman/5.0/en/mysql-proxy-scripting-structures.html#mysql-proxy-scripting-structures-response" href="http://dev.mysql.com/doc/refman/5.0/en/mysql-proxy-scripting-structures.html#mysql-proxy-scripting-structures-response">własną odpowiedź lub błąd</a> (jak w skrypcie wyżej).</li>
</ul>
<p>Warto zajrzeć na:</p>
<ul>
<li><a title="http://www.lua.org/manual/5.1/manual.html" href="http://www.lua.org/manual/5.1/manual.html">Lua 5.1 Reference Manual</a></li>
<li><a title="http://dev.mysql.com/tech-resources/articles/proxy-gettingstarted.html" href="http://dev.mysql.com/tech-resources/articles/proxy-gettingstarted.html">Getting started with MySQL Proxy</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2009/11/troche-lua-w-mysql-proxy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sprawdzanie aktywności użytkowników MySQL</title>
		<link>http://guzik.net.pl/blog/2008/07/sprawdzanie-aktywnosci-uzytkownikow-mysql/</link>
		<comments>http://guzik.net.pl/blog/2008/07/sprawdzanie-aktywnosci-uzytkownikow-mysql/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 10:16:13 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[LUA]]></category>
		<category><![CDATA[mysql-proxy]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=32</guid>
		<description><![CDATA[Podłoże problemu: bazy zakładane na serwerze na żądanie użytkowników / klientów nie były usuwane. Po pewnym czasie ilość baz urosła, z czego spory odsetek była nieużywana. Nie obciąża to serwera, ale zabiera miejsce na dysku i ogólnie powoduje bałagan. Trzeba to jakoś posprzątać! Prosty sposób &#8211; REVOKE i telefon. Mało elegancki! My szukamy czegoś na [...]]]></description>
			<content:encoded><![CDATA[<p>Podłoże problemu: bazy zakładane na serwerze na żądanie użytkowników / klientów nie były usuwane. Po pewnym czasie ilość baz urosła, z czego spory odsetek była nieużywana. Nie obciąża to serwera, ale zabiera miejsce na dysku i ogólnie powoduje bałagan. Trzeba to jakoś posprzątać!</p>
<p>Prosty sposób &#8211; <a title="http://dev.mysql.com/doc/refman/5.0/en/revoke.html" href="http://dev.mysql.com/doc/refman/5.0/en/revoke.html">REVOKE</a> i telefon. Mało elegancki! My szukamy czegoś na poziomie ;-)</p>
<p>Od pewnego czasu śledzę projekt <a title="http://forge.mysql.com/wiki/MySQL_Proxy" href="http://forge.mysql.com/wiki/MySQL_Proxy">mysql-proxy</a>. Wprawdzie już jakiś czas projekt jest nieuaktualniany (<em>At revision 511.</em>), ale mam nadzieję, że <a title="http://jan.kneschke.de/" href="http://jan.kneschke.de/">Jan Kneschke</a> cały czas pracuje&#8230;</p>
<p>Początkowo używałem mysql-proxy jako typowego pośrednika, co było pomocne przy przenoszeniu baz (sporo klientów łączyło się przez <em>UNIX socket</em>). Nie sprawdzał się za dobrze (ostatnia testowana wersja nie zawsze łączyła z PHP, wcześniejsze miały duże problemy ze stabilną pracą w ogóle). Na podobny projekt &#8211; <a title="http://pgpool.projects.postgresql.org/" href="http://pgpool.projects.postgresql.org/">pgpool-II</a> (dla <a title="http://www.postgresql.org/" href="http://www.postgresql.org/">PostgreSQL</a>) nie narzekałem nigdy. Niemniej z racji długości życia nie ma ich co porównywać.</p>
<p>Dla śledzenia użytkowników z tematu napisałem skrypt (<a title="http://www.lua.org/" href="http://www.lua.org/">LUA</a>), który każde połączenie zapisuje do pliku dziennika (można przerobić na zapisywanie do bazy + jakiś licznik). Informacją wystarczającą jest IP klienta, nazwa użytkownika oraz baza, do której się podłączył. Do posprzątania nic więcej nas nie interesuje.<br />
Sposób uruchomienia mysql-proxy opisany jest w dokumentacji, więc warto tam zajrzeć.<br />
Skrypt wygląda tak:</p>
<blockquote><p>local log_file = &#8216;/tmp/mysql.log&#8217;<br />
local fh = io.open(log_file, &#8222;a+&#8221;)</p>
<p>function read_auth_result(auth)<br />
if auth.packet:byte() == proxy.MYSQLD_PACKET_OK then<br />
fh:write(<br />
string.format(&#8222;%s %s\t%s\t%s\n&#8221;,<br />
os.date(&#8216;%Y-%m-%d %H:%M:%S&#8217;),<br />
proxy.connection.client.address,<br />
proxy.connection.client.username,<br />
proxy.connection.client.default_db))<br />
end<br />
fh:flush()<br />
end</p></blockquote>
<p>Ze struktury <em>proxy.connection.client</em> przyda nam się <em>address</em> (adres IP klienta), <em>username</em> (nazwa uzytkownika) oraz <em>default_db</em> (baza, do której zostało wykonane połączenie). Jest jeszcze <em>scrambled_password</em>, ale logowanie tego podpada pod <a title="http://portalwiedzy.onet.pl/polszczyzna.html?qs=inwigilacja&amp;tr=pol-pol&amp;ch=1&amp;x=0&amp;y=0" href="http://portalwiedzy.onet.pl/polszczyzna.html?qs=inwigilacja&amp;tr=pol-pol&amp;ch=1&amp;x=0&amp;y=0">inwigilację</a>. Logujemy <span style="text-decoration: underline;">tylko</span> uwierzytelnionych użytkowników (MYSQLD_PACKET_OK &#8211; 0, ale jest jeszcze możliwość użycia MYSQLD_PACKET_ERR &#8211; 255). I w wyniku otrzymujemy:</p>
<blockquote><p>2008-07-18 11:52:40 127.0.0.1:43228    root    test<br />
2008-07-18 12:00:16 127.0.0.1:62133    exg    exg<br />
2008-07-18 12:00:32 127.0.0.1:62901    root    mysql<br />
2008-07-18 12:07:54 10.74.0.254:11243	guzik<br />
2008-07-18 12:08:00 10.74.0.254:16369	guzik	test</p></blockquote>
<p>Log bez bazy, to połączenie z konsoli. <em>\u</em> czy <em>USE</em> nie loguje się w ogóle.<br />
Po długoterminowym zbieraniu informacji (do miesiąca) mamy już listę wykorzystywanych baz. Pozostaje <a title="http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html" href="http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html"><em>dump</em></a> i <a title="http://dev.mysql.com/doc/refman/5.0/en/drop-database.html" href="http://dev.mysql.com/doc/refman/5.0/en/drop-database.html">DROP</a> :&gt;</p>
<p>Pamiętajmy też, że baza widzi połączenie z <em>mysql-proxy</em>, więc należy dać stosowne uprawnienia dla tego hosta.</p>
<p>Więcej do poczytania:</p>
<ul>
<li> <a title="http://dev.mysql.com/doc/refman/5.0/en/mysql-proxy-scripting.html" href="http://dev.mysql.com/doc/refman/5.0/en/mysql-proxy-scripting.html">MySQL ::   MySQL 5.0 Reference Manual :: 16.4 MySQL Proxy Scripting</a></li>
<li> <a title="http://dev.mysql.com/tech-resources/articles/proxy-gettingstarted.html" href="http://dev.mysql.com/tech-resources/articles/proxy-gettingstarted.html">MySQL ::  Getting started with MySQL Proxy</a></li>
<li> <a title="http://mystic-one.com/2008/05/13/partial-mysql-proxy-api-doc/" href="http://mystic-one.com/2008/05/13/partial-mysql-proxy-api-doc/">Mystic&#8217;s Random Blog » (partial) MySQL Proxy API Doc</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2008/07/sprawdzanie-aktywnosci-uzytkownikow-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
