<?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; DB</title>
	<atom:link href="http://guzik.net.pl/blog/category/tech/db/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>FortiAnalyzer i MySQL</title>
		<link>http://guzik.net.pl/blog/2010/04/fortianalyzer-i-mysql/</link>
		<comments>http://guzik.net.pl/blog/2010/04/fortianalyzer-i-mysql/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 20:51:52 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[FortiAnalyzer]]></category>
		<category><![CDATA[Fortinet]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=1769</guid>
		<description><![CDATA[W dokumencie FortiAnalyzer v4.0 MR2 Release Notes w rozdziale &#8217;1.1 Summary of Enhancements Provided by FortiAnalyzer v4.0 MR2 Release&#8217; można znaleźć między innymi coś takiego: Remote SQL database (MySQL) support SQL DB PostgreSQL support Przyznam, że zaintrygowało mnie to na tyle, że postanowiłem od razu sprawdzić z czym to się je i co można z tego [...]]]></description>
			<content:encoded><![CDATA[<p>W dokumencie <a title="ftp://support.fortinet.com/FortiAnalyzer/v4.00/4.0MR2/MR2/FortiAnalyzer-v4.0-MR2-Release-Notes.pdf" href="ftp://support.fortinet.com/FortiAnalyzer/v4.00/4.0MR2/MR2/FortiAnalyzer-v4.0-MR2-Release-Notes.pdf">FortiAnalyzer v4.0 MR2 Release Notes</a> w rozdziale &#8217;1.1 Summary of Enhancements Provided by FortiAnalyzer v4.0 MR2 Release&#8217; można znaleźć między innymi coś takiego:</p>
<ul>
<li>Remote SQL database (MySQL) support</li>
<li>SQL DB PostgreSQL support</li>
</ul>
<p>Przyznam, że zaintrygowało mnie to na tyle, że postanowiłem od razu sprawdzić z czym to się je i co można z tego wycisnąć.<br />
<span id="more-1769"></span><br />
Konfiguracja prosta &#8211; jak na załączonym obrazku:</p>
<p><a href="http://guzik.net.pl/blog/wp-content/uploads/2010/04/famysql.jpg"><img class="aligncenter size-medium wp-image-1770" title="famysql" src="http://guzik.net.pl/blog/wp-content/uploads/2010/04/famysql-300x133.jpg" alt="" width="300" height="133" /></a><br />
Podajemy sposób przechowywania danych (<em>Location</em>): lokalny to prawdopodobnie PostgreSQL i zdalny, czyli MySQL. Wybrałem ten ostatni. Po uzupełnieniu niezbędnych danych (serwer, użytkownik, hasło, baza) zaznaczyłem logowanie wszystkich typów zdarzeń.<br />
Jeśli użytkownik, którego podamy ma prawo do zakładania baz, nic więcej nie musimy robić. W przeciwnym razie należy mu pomóc.<br />
Poniżej kawałek mojego <em>query log</em>&#8216;a:</p>
<blockquote><p><code>Connect fa@A.B.C.D on<br />
Query create database if not exists `fortianalyzer`<br />
Query use `fortianalyzer`<br />
Query select tbl_name from table_ref where tbl_name like 'FG100A3907510579-elog-%' and row_num=0<br />
</code></p></blockquote>
<p>Czyli mamy połączenie z serwerem, próbę założenia oraz podłączenie do bazy, a następnie przeszukanie tabeli <code>table_ref</code> (założona wcześniej). Tabela ta zawiera informacje o innych tablicach z logami &#8211; podejrzewam, że zaplanowana została jakaś rotacja (wskazują na to kolumny <code>itime_start</code>, <code>itime_end</code>, <code>dtime_start</code>, <code>dtime_end</code>, <code>row_num</code>). Czemu tylko podejrzewam, a nie wiem? Otóż w przypadku, gdy nie zostanie znaleziony żaden wynik, FortiAnalyzer próbuje stworzyć nową tablicę. U mnie próbuje, bo nikt nie pomyslał, że baza może mieć domyślne kodowanie ustawione na <code>utf8</code> zamiast np. <code>latin1</code>, a przy ograniczeniach MySQL nie każdą tablicę da się założyć. Jakiej się nie da? Wyczerpująco opisuje to dodatek <a title="http://dev.mysql.com/doc/refman/5.1/en/column-count-limit.html" href="http://dev.mysql.com/doc/refman/5.1/en/column-count-limit.html">D.7.2. The Maximum Number of Columns Per Table</a> dokumentacji MySQL.<br />
Zapytanie jak poniżej:</p>
<blockquote><p><code>create table `FG100A3907510579-elog-20100409220517` (`id` bigint unsigned not null primary key,`itime` datetime,`dtime` datetime,`cluster_id` varchar(24),`device_id` varchar(16),`log_id` smallint unsigned default 0,`subtype` varchar(255),`type` varchar(255),`timestamp` int unsigned default 0,`pri` varchar(255),`vd` varchar(255),`user` varchar(255),`msg` varchar(255),`ssid` varchar(255),`action` varchar(255),`session_id` int unsigned default 0,`count` int unsigned default 0,`proto` varchar(255),`profile` varchar(255),`cpu` tinyint unsigned default 0,`src` varchar(40),`epoch` int unsigned default 0,`mem` tinyint unsigned default 0,`duration` int unsigned default 0,`infected` int unsigned default 0,`from` varchar(255),`dst` varchar(40),`ha_group` tinyint unsigned default 0,`tunnel_id` int unsigned default 0,`status` varchar(255),`bssid` varchar(255),`tunnel_type` varchar(255),`event_id` int unsigned default 0,`ip` varchar(40),`ha_role` varchar(255),`rem_ip` varchar(40),`src_int` varchar(255),`suspicious` int unsigned default 0,`sn` varchar(255),`to` varchar(255),`total_session` int unsigned default 0,`ap` varchar(255),`scanned` int unsigned default 0,`vcluster` int unsigned default 0,`remote_ip` varchar(40),`carrier_ep` varchar(255),`imsi` varchar(255),`loc_ip` varchar(40),`dst_int` varchar(255),`from_vcluster` int unsigned default 0,`rem_port` smallint unsigned default 0,`src_port` smallint unsigned default 0,`msisdn` varchar(255),`tunnel_ip` varchar(40),`intercepted` int unsigned default 0,`vap` varchar(255),`service` varchar(255),`apn` varchar(255),`out_intf` varchar(255),`blocked` int unsigned default 0,`dst_port` smallint unsigned default 0,`mac` varchar(255),`to_vcluster` int unsigned default 0,`acct_stat` varchar(255),`selection` varchar(255),`reason` varchar(255),`group` varchar(255),`rate` tinyint unsigned default 0,`loc_port` smallint unsigned default 0,`vcluster_member` int unsigned default 0,`vcluster_state` varchar(255),`app-type` varchar(255),`nsapi` tinyint unsigned default 0,`dport` smallint unsigned default 0,`channel` tinyint unsigned default 0,`cookies` varchar(255),`checksum` int unsigned default 0,`dst_host` varchar(255),`nf_type` varchar(255),`vdname` varchar(255),`linked-nsapi` tinyint unsigned default 0,`next_stats` int unsigned default 0,`virus` varchar(255),`imei-sv` varchar(255),`devintfname` varchar(255),`security` varchar(255),`policy_id` int unsigned default 0,`rai` varchar(255),`hostname` varchar(255),`xauth_user` varchar(255),`uli` varchar(255),`xauth_group` varchar(255),`sent` bigint unsigned default 0,`policyid` int unsigned default 0,`rcvd` bigint unsigned default 0,`sess_duration` int unsigned default 0,`hbdn_reason` varchar(255),`banned_src` varchar(255),`end-usr-address` varchar(40),`msg-type` tinyint unsigned default 0,`sync_type` varchar(255),`banned_rule` varchar(255),`state` varchar(255),`vpn_tunnel` varchar(255),`sync_status` varchar(255),`alert` varchar(255),`sensor` varchar(255),`endpoint` varchar(255),`stage` tinyint unsigned default 0,`voip_proto` varchar(255),`deny_cause` varchar(255),`desc` varchar(255),`dir` varchar(255),`kind` varchar(255),`init` varchar(255),`mode` varchar(255),`cert-type` varchar(255),`ui` varchar(255),`exch` varchar(255),`rat-type` varchar(255),`c-gsn` varchar(40),`error_num` varchar(255),`u-gsn` varchar(40),`method` varchar(255),`phase2_name` varchar(255),`spi` varchar(255),`name` varchar(255),`c-sgsn` varchar(40),`request_name` varchar(255),`seq` varchar(255),`c-ggsn` varchar(40),`in_spi` varchar(255),`u-sgsn` varchar(40),`out_spi` varchar(255),`u-ggsn` varchar(40),`c-sgsn-teid` int unsigned default 0,`enc_spi` varchar(255),`c-ggsn-teid` int unsigned default 0,`dec_spi` varchar(255),`message_type` varchar(255),`malform_desc` varchar(255),`tunnel` varchar(255),`u-sgsn-teid` int unsigned default 0,`u-ggsn-teid` int unsigned default 0,`malform_data` int unsigned default 0,`tunnel-idx` int unsigned default 0,`line` varchar(255),`column` int unsigned default 0,`c-pkts` bigint unsigned default 0,`phone` varchar(255),`profile_group` varchar(255),`c-bytes` bigint unsigned default 0,`u-pkts` bigint unsigned default 0,`u-bytes` bigint unsigned default 0,`next_stat` int unsigned default 0,`user_data` varchar(255),`role` varchar(255),`result` varchar(255),`xauth_result` varchar(255),`esp_transform` varchar(255),`esp_auth` varchar(255),`error_reason` varchar(255),`peer_notif` varchar(255))</code></p></blockquote>
<p>zakończy się niepowodzeniem, a serwer zwróci błąd:</p>
<blockquote><p><code>ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs</code></p></blockquote>
<p>Nie chce mi się nawet liczyć ile bajtów to zajmuje. A wystarczyło dopisać <code>CHARACTER SET latin1</code>&#8230;</p>
<p>Podejrzewam, że po poprawnym założeniu tabeli dopisze się coś do <code>table_ref</code>, ale jest już zbyt późno, a ja mam za dużo lat, żeby dochodzić jak to powinno wyglądać.</p>
<p>Tak czy inaczej &#8211; inżynierowie Fortinet tracą jeden punkt.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2010/04/fortianalyzer-i-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LOCATE() na innym podwórku</title>
		<link>http://guzik.net.pl/blog/2010/03/locate-na-innym-podworku/</link>
		<comments>http://guzik.net.pl/blog/2010/03/locate-na-innym-podworku/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 21:00:56 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[DB]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=1700</guid>
		<description><![CDATA[Rozpędziłem się z tym wpisem dot. Blind SQL injection i nie wspomniałem o innych bazach. LOCATE() to oczywiście funkcja MySQL. PostgreSQL ma swoją POSITION(substing in string), a MS SQL &#8211; CHARINDEX(substring, string[, position]). Jest jeszcze INSTR(string, substring [,position [,occurrence]]) dla Oracle. Innych nie znam, bo nie używałem. No, ale co tam z PHP może jeszcze [...]]]></description>
			<content:encoded><![CDATA[<p>Rozpędziłem się z tym wpisem dot. <em><a title="http://guzik.net.pl/blog/2010/03/kolo-fortuny-blind-sql-injection/" href="http://guzik.net.pl/blog/2010/03/kolo-fortuny-blind-sql-injection/">Blind SQL injection</a></em> i nie wspomniałem o innych bazach. <code>LOCATE()</code> to oczywiście funkcja MySQL. PostgreSQL ma swoją <code>POSITION(substing in string)</code>, a MS SQL &#8211; <code>CHARINDEX(substring, string[, position])</code>. Jest jeszcze <code>INSTR(string, substring [,position [,occurrence]])</code> dla Oracle.</p>
<p>Innych nie znam, bo nie używałem. No, ale co tam z PHP może jeszcze być? SQLite? Ten akurat ma ograniczoną w ogóle liczbę funkcji (w dokumentacji nie znalazłem żadnego odpowiednika).</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2010/03/locate-na-innym-podworku/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Koło fortuny (Blind SQL injection)</title>
		<link>http://guzik.net.pl/blog/2010/03/kolo-fortuny-blind-sql-injection/</link>
		<comments>http://guzik.net.pl/blog/2010/03/kolo-fortuny-blind-sql-injection/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 14:01:00 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[SQL injection]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=1695</guid>
		<description><![CDATA[Od wczoraj przeglądam blog Michała Ławickiego i w komentarzach uzupełniam artykuły dot. baz danych (vide Analiza struktury bazy danych czy Obsługa plików, a SQL Injection). Dziś przyjrzałem się jego podejściu do Blind SQL injection czyli ataku na stronę, która nie wyświetla błędów. Metoda na odgadywanie hasła znak po znaku jest rzeczywiście toporna. Biorąc pod uwagę [...]]]></description>
			<content:encoded><![CDATA[<p>Od wczoraj przeglądam blog <a title="http://www.goldenline.pl/michal-lawicki" href="http://www.goldenline.pl/michal-lawicki">Michała Ławickiego</a> i w komentarzach uzupełniam artykuły dot. baz danych (vide <a title="Analiza struktury bazy danych" rel="bookmark" href="http://www.beldzio.com/analiza-struktury-bazy-danych">Analiza struktury bazy danych</a> czy <a title="Obsługa plików, a SQL Injection" rel="bookmark" href="http://www.beldzio.com/obsluga-plikow-a-sql-injection">Obsługa plików, a SQL Injection</a>). Dziś przyjrzałem się jego podejściu do <em><a title="http://www.beldzio.com/blind-sql-injection" href="http://www.beldzio.com/blind-sql-injection">Blind SQL injection</a></em> czyli ataku na stronę, która nie wyświetla błędów.<br />
Metoda na odgadywanie hasła znak po znaku jest rzeczywiście toporna. Biorąc pod uwagę 95 dostępnych znaków i hasło o długości 16, możliwych kombinacji jest dość sporo. Wysyłanie 1k5 zapytań zajmie trochę czasu. Dlatego można to zmodyfikować wstawiając pomiędzy <code>LENGTH(passwd)</code>, a <code>SUBSTRING(passwd, x, y)</code> funkcję <code>LOCATE(char, passwd)</code>, która pokaże jakie znaki mamy w ogóle dostępne (jak w teleturnieju &#8211; stąd temat wiadomości).<br />
<span id="more-1695"></span><br />
Nie znam się prawie w ogóle na atakach i bezpieczeństwie, ale wydaje mi się, że jeżeli ktokolwiek stosuje tą metodę, to pewnie chce sam proces skrócić do minimum. Tu <code>LOCATE()</code> wywołujemy maksymalnie 95 razy i jeśli się znaki w haśle nie powtarzają to po sprawie. Jeśli natomiast któryś się powtarza, możemy jeszcze raz wykonać tą funkcję, podając jako trzeci argument pozycję, od której zaczynamy szukać &#8211; <code>LOCATE(char, passwd, pos)</code>, ew. męczymy <code>SUBSTRING()</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2010/03/kolo-fortuny-blind-sql-injection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL: konwersja daty i import plików &#8211; studium przypadku</title>
		<link>http://guzik.net.pl/blog/2010/01/mysql-konwersja-daty-i-import-plikow-studium-przypadku/</link>
		<comments>http://guzik.net.pl/blog/2010/01/mysql-konwersja-daty-i-import-plikow-studium-przypadku/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 14:07:28 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OTC]]></category>
		<category><![CDATA[OTC Terminal]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=1495</guid>
		<description><![CDATA[Niniejszy wpis powstał przy rozwiązywaniu konkretnego problemu. Jest tu opis polecenia LOAD DATA INFILE (import danych z pliku) oraz sposób wykonania konwersji daty podczas importu danych, co może komuś się przydać (niekoniecznie przy walce z takim samym problemem). Opis problemu: Potrzebujemy wyciągnąć wszystkie próby logowania z wykorzystaniem programu OTC Terminal konkretnego dnia, albo o konkretnej [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" title="MySQL logo" src="http://www.mysql.com/common/logos/sakila.png" alt="" width="121" height="79" />Niniejszy wpis powstał przy rozwiązywaniu konkretnego problemu. Jest tu opis polecenia <a title="http://dev.mysql.com/doc/refman/5.1/en/load-data.html" href="http://dev.mysql.com/doc/refman/5.1/en/load-data.html">LOAD DATA INFILE</a> (import danych z pliku) oraz sposób wykonania konwersji daty podczas importu danych, co może komuś się przydać (niekoniecznie przy walce z takim samym problemem).<br />
<span id="more-1495"></span><br />
<strong>Opis problemu</strong>: Potrzebujemy wyciągnąć wszystkie próby logowania z wykorzystaniem programu <a title="http://www.otc.pl/index.asp?s=84&amp;l=1" href="http://www.otc.pl/index.asp?s=84&amp;l=1">OTC Terminal</a> konkretnego dnia, albo o konkretnej godzinie każdego dnia zdefiniowanego użytkownika.</p>
<p><strong>Rozeznanie terenu</strong>: Wspomniany program tworzy log w następującym formacie:</p>
<blockquote><p><code> 4. BS2          LOGIN ERROR   25.03.2009 07:02:08  Password expired.<br />
4. BS2          CHPWD OK      25.03.2009 07:02:16  Password for user 'BS2' successfully changed.<br />
0. BS2          LOGIN OK      30.03.2009 06:54:25<br />
1. BS2          LOGIN OK      30.03.2009 06:54:29<br />
0. BS2          LOGOUT OK     30.03.2009 06:54:29<br />
1. BS2          LOGOUT OK     30.03.2009 06:54:42<br />
10. BS2          LOGOUT ERROR  24.04.2009 11:47:58  Login limit (session)<br />
6. BS2          LOGIN ERROR   21.05.2009 14:32:57  No such name<br />
</code></p></blockquote>
<p>Nie wnikam co oznacza pierwsza kolumna w logach, kolejne to: nazwa użytkownika, akcja, data oraz godzina, a także dodatkowa informacja dla akcji. Nie interesuje nas zarówno pierwsza, jak i ostatnia kolumna. Plik tekstowy ma kolumny o stałej szerokości (tutaj tego nie widać).<br />
Do realizacji zadania można użyć <a title="http://www.gnu.org/software/gawk/" href="http://www.gnu.org/software/gawk/">awk</a>, <a title="http://sed.sourceforge.net/" href="http://sed.sourceforge.net/">sed</a>, <a title="http://www.gnu.org/software/grep/" href="http://www.gnu.org/software/grep/">grep</a>, <a title="http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/find.mspx?mfr=true" href="http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/find.mspx?mfr=true">find</a> (Windows) lub innych podobnych narzędzi w połączeniu z wyrażeniami regularnymi, ale można też skorzystać z bazy danych, która będzie przechowywać wspomniane informacje w konkretnym formacie, a samo przeszukiwanie będzie wygodniejsze, szybsze i bardziej elastyczne.</p>
<p><strong>Realizacja</strong>: Za pomocą arkusza kalkulacyjnego przekształciłem logi w format CSV (najszybsze, co przyszło mi do głowy). Wyrzuciłem niepotrzebne kolumny. Utworzyłem tabelę w MySQL, która może wciągnąć te dane:</p>
<blockquote><p><code>CREATE TABLE `trmlog` (<br />
`user` char(3) NOT NULL,<br />
`action` varchar(24) DEFAULT NULL,<br />
`date` date DEFAULT NULL,<br />
`time` time DEFAULT NULL,<br />
KEY `useridx` (`user`),<br />
KEY `dateidx` (`date`)<br />
) ENGINE=InnoDB DEFAULT CHARSET=utf8</code></p></blockquote>
<p>Data i godzina są osobno. Jako, że data ma postać DD.MM.YYYY, a chcemy YYYY-MM-DD, stworzyłem funkcję, która może to skonwertować (nie wiem czy MySQL w locie coś może sam zrobić):</p>
<blockquote><p><code>delimiter //</code></p>
<p><code><a title="http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html" href="http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html">CREATE FUNCTION</a> dateconv (date CHAR(10)) RETURNS DATE<br />
BEGIN<br />
RETURN CONCAT(<a title="http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring" href="http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring">SUBSTRING</a>(date, 7), "-", SUBSTRING(date, 4, 2), "-", SUBSTRING(date, 1, 2));<br />
END//</code></p>
<p><code>delimiter ;</code></p></blockquote>
<p>I ostatecznie zaimportowałem dane:</p>
<blockquote><p><code>LOAD DATA INFILE 'E:\\temp\\termlog\\log.csv' INTO TABLE trmlog FIELDS TERMINATED BY ';' (user, action, @var1, time) SET date = dateconv(@var1);</code></p></blockquote>
<p>Uwagi wymaga proces konwersji kolumny z datą. Domyślnie LOAD DATA INFILE zakłada, że każde pole w pliku CSV odpowiada jednej kolumnie w tabeli. Jeśli chcemy zaimportować dane tylko do niektórych kolumn, musimy podać ich nazwy (czy sam ich porządek). Jeśli natomiast chcemy je w jakiś sposób przekształcić, używamy klauzuli <code>SET</code>, która może przybrać różne formy. Po przykłady odsyłam do <a title="http://dev.mysql.com/doc/refman/5.1/en/" href="http://dev.mysql.com/doc/refman/5.1/en/">dokumentacji MySQL</a>. U mnie wygląda to tak, że do kolumny <code>date</code> wciągamy dane, które wyrzuci nam (nasza własna) funkcja <code>dateconv()</code>. Może nie do końca intuicyjne, ale nie tak trudne.<br />
Dalej obrabiamy to jak chcemy w SQL.</p>
<p>Oczywiście nie musimy używać MySQL, a jeśli już użyliśmy, zawsze możemy migrować do innej bazy:</p>
<li><a title="http://www.heise-online.pl/newsticker/news/item/Microsoft-chce-pomoc-w-migracji-z-MySQL-a-na-SQL-Server-902665.html" href="http://www.heise-online.pl/newsticker/news/item/Microsoft-chce-pomoc-w-migracji-z-MySQL-a-na-SQL-Server-902665.html">Microsoft chce pomóc w migracji z MySQL-a na SQL Server</a></li>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2010/01/mysql-konwersja-daty-i-import-plikow-studium-przypadku/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>nagios: check_mysql-replication.pl</title>
		<link>http://guzik.net.pl/blog/2009/10/nagios-check_mysql-replication-pl/</link>
		<comments>http://guzik.net.pl/blog/2009/10/nagios-check_mysql-replication-pl/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 11:27:49 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[check_mysql-replication]]></category>
		<category><![CDATA[Nagios]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=1139</guid>
		<description><![CDATA[Do monitorowania replikacji MySQL pod Nagios postanowiłem użyć wtyczki mysql_check-replication.pl, ktrej autorem jest Erwan Labynocle Ben Souiden. Instrukcja mówi o nadaniu prawa REPLICATION CLIENT użytkownikowi, który łączył się będzie z bazą. Sam skrypt napisany jest w Perl, gdzie w DSN podana jest baza, do której użytkownik będzie się podłączał. Wspomniane prawa dają tylko możliwość wywołania [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nagios.org/"><img class="alignright" title="Nagios logo" src="http://assets.nagios.com/images/header/Nagios.png" alt="" width="212" height="50" /></a>Do monitorowania <a title="http://dev.mysql.com/doc/refman/5.0/en/replication.html" href="http://dev.mysql.com/doc/refman/5.0/en/replication.html">replikacji MySQL</a> pod <a title="http://nagios.org/" href="http://nagios.org/">Nagios</a> postanowiłem użyć <a title="http://exchange.nagios.org/directory/Plugins/Databases/MySQL/check_mysql%252Dreplication-2Epl/details" href="http://exchange.nagios.org/directory/Plugins/Databases/MySQL/check_mysql%252Dreplication-2Epl/details">wtyczki mysql_check-replication.pl</a>, ktrej autorem jest <a title="http://www.aleikoum.net/" href="http://www.aleikoum.net/">Erwan Labynocle Ben Souiden</a>. Instrukcja mówi o nadaniu prawa <a title="http://dev.mysql.com/doc/refman/5.0/en/privileges-provided.html#priv_replication-client" href="http://dev.mysql.com/doc/refman/5.0/en/privileges-provided.html#priv_replication-client">REPLICATION CLIENT</a> użytkownikowi, który łączył się będzie z bazą. Sam skrypt napisany jest w <a title="http://www.perl.org/" href="http://www.perl.org/">Perl</a>, gdzie w DSN podana jest baza, do której użytkownik będzie się podłączał. Wspomniane prawa dają tylko możliwość wywołania <a title="http://dev.mysql.com/doc/refman/5.0/en/show-master-status.html" href="http://dev.mysql.com/doc/refman/5.0/en/show-master-status.html">SHOW MASTER STATUS</a> oraz <a title="http://dev.mysql.com/doc/refman/5.0/en/show-slave-status.html" href="http://dev.mysql.com/doc/refman/5.0/en/show-slave-status.html">SHOW SLAVE STATUS</a> i nie dają praw do <span style="text-decoration: underline;">żadnej</span> bazy. Tym samym skrypt się nie wykona.</p>
<p>Proponuję (wersja 0.1) przerobić DSN (linia 298) i wyrzucić nazwę bazy zupełnie (pozostawić `:&#8217; &#8211; dwukropek) lub zmienić nazwę na <a title="http://dev.mysql.com/doc/refman/5.0/en/information-schema.html" href="http://dev.mysql.com/doc/refman/5.0/en/information-schema.html"><code>information_schema</code></a>, bo do tego prawo ma każdy użytkownik (dla wersji &gt; 5.0).</p>
<blockquote><p><code>--- /usr/lib64/nagios/plugins/check_mysql-replication.pl        2009-10-22 13:17:26.000000000 +0200<br />
+++ check_mysql-replication.pl  2009-10-22 13:17:33.000000000 +0200<br />
@@ -295,7 +295,7 @@ EOT<br />
# ------------------------------<br />
sub request_executor() {<br />
my ($host,$port,$user,$pwd,$request) = @_;<br />
-    my $dsn = "DBI:mysql:mysql;host=$host:$port";<br />
+    my $dsn = "DBI:mysql:;host=$host:$port";<br />
my $dbh = DBI-&gt;connect($dsn, $user, $pwd) or die "connexion failed $DBI::errstr\n";<br />
my $sth = $dbh-&gt;prepare($request);<br />
$sth-&gt;execute();</code></p></blockquote>
<p>Autor obiecał, że wprowadzi stosowną poprawkę &#8211; tymczasem można łatać.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2009/10/nagios-check_mysql-replication-pl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MS SQL 2008</title>
		<link>http://guzik.net.pl/blog/2009/09/ms-sql-2008/</link>
		<comments>http://guzik.net.pl/blog/2009/09/ms-sql-2008/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 09:00:49 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[Pudełko]]></category>
		<category><![CDATA[Płatnik]]></category>
		<category><![CDATA[SQL 2008]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=975</guid>
		<description><![CDATA[Przeniosłem bazy Płatnika i Pudełko z MSDE 2000 na MS SQL 2008 (Express). Nic trudnego, ale dostawcy obu rozwiązań nie wspierają (jeszcze) oficjalnie tej bazy, wiec można mieć wątpliwości. Działa poprawnie, łącznie ze zmianą poziomu kompatybilności baz. ALTER DATABASE [platnik] SET COMPATIBILITY_LEVEL = 100 GO ALTER DATABASE [pudelko] SET COMPATIBILITY_LEVEL = 100 GO Przeniesienie w [...]]]></description>
			<content:encoded><![CDATA[<p>Przeniosłem bazy <a title="http://www.platnik.info.pl/" href="http://www.platnik.info.pl/">Płatnika</a> i <a title="http://guzik.net.pl/blog/2008/12/msde-w-pudelku/" href="http://guzik.net.pl/blog/2008/12/msde-w-pudelku/">Pudełko</a> z MSDE 2000 na MS SQL 2008 (Express). Nic trudnego, ale dostawcy obu rozwiązań nie wspierają (jeszcze) oficjalnie tej bazy, wiec można mieć wątpliwości. Działa poprawnie, łącznie ze zmianą poziomu kompatybilności baz.</p>
<blockquote><p><code>ALTER DATABASE [platnik] SET COMPATIBILITY_LEVEL = 100<br />
GO<br />
ALTER DATABASE [pudelko] SET COMPATIBILITY_LEVEL = 100<br />
GO</code></p></blockquote>
<p>Przeniesienie w najprostszy z możliwych sposobów &#8211; <em>detach</em> i <em>attach</em>. Pamiętać należy, że jeśli nie uwierzytelniamy się na <code>sa</code> (!!!), w nowej instancji założyć trzeba <em>login</em> i powiązać go z użytkownikiem w bazie. Co ciekawe przy robieniu tego z GUI (<a title="http://www.microsoft.com/downloadS/details.aspx?familyid=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&amp;displaylang=en" href="http://www.microsoft.com/downloadS/details.aspx?familyid=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&amp;displaylang=en">Microsoft SQL Server Management Studio</a>) możemy wybrać <span style="text-decoration: underline;">istniejącego</span> użytkownika, a narzędzie będzie próbowało go założyć (<code>CREATE</code>) zamiast zmienić (<code>ALTER</code>) i zgłosi błąd (login zostanie założony, ale mapowania nie będzie). Dla niedomyślnych pomocny przykład:</p>
<blockquote><p><code>USE [pudelko]<br />
GO<br />
<a title="http://msdn.microsoft.com/en-us/library/ms176060.aspx" href="http://msdn.microsoft.com/en-us/library/ms176060.aspx">ALTER USER</a> [opek] WITH LOGIN = [opek]<br />
GO</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2009/09/ms-sql-2008/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL slow_queries</title>
		<link>http://guzik.net.pl/blog/2009/02/mysql-slow_queries/</link>
		<comments>http://guzik.net.pl/blog/2009/02/mysql-slow_queries/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 19:49:15 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[slow-queries]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=550</guid>
		<description><![CDATA[Już kiedyś płakałem z tego powodu &#8211; Analiza log-slow-queries (z życia wzięte…), a tu stary klient narzeka na wydajność swojego serwera. I co my tu mamy? tabela 1 &#8211; 117&#8217;608 wierszy, tabela 2 &#8211; 730 wierszy, tabela 3 &#8211; 709 wierszy. Niby niewiele, ale da się z tego zrobić taki wynik: # Query_time: 11'005  Lock_time: [...]]]></description>
			<content:encoded><![CDATA[<p>Już kiedyś płakałem z tego powodu &#8211; <a title="http://guzik.net.pl/blog/2008/07/analiza-log-slow-queries-z-zycia-wziete/" href="http://guzik.net.pl/blog/2008/07/analiza-log-slow-queries-z-zycia-wziete/">Analiza log-slow-queries (z życia wzięte…)</a>, a tu stary klient narzeka na wydajność swojego serwera. I co my tu mamy?</p>
<ul>
<li> tabela 1 &#8211; 117&#8217;608 wierszy,</li>
<li>tabela 2 &#8211; 730 wierszy,</li>
<li>tabela 3 &#8211; 709 wierszy.</li>
</ul>
<p>Niby niewiele, ale da się z tego zrobić taki wynik:</p>
<blockquote><p><code># Query_time: 11'005  Lock_time: 0  Rows_sent: 1  Rows_examined: 88'891'086</code></p></blockquote>
<p>Dla porównania 10 miesięcy temu to samo zapytanie:</p>
<blockquote><p><code># Query_time: 53  Lock_time: 0  Rows_sent: 615  Rows_examined: 8'674'949</code></p></blockquote>
<p>Nie mam pytań. Zdecydowanie potrzeba nowego procesora, więcej pamięci i szybszych dysków. Programisty przecież nie przekonamy&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2009/02/mysql-slow_queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DBD::Sybase na Gentoo</title>
		<link>http://guzik.net.pl/blog/2008/12/dbdsybase-na-gentoo/</link>
		<comments>http://guzik.net.pl/blog/2008/12/dbdsybase-na-gentoo/#comments</comments>
		<pubDate>Wed, 24 Dec 2008 10:59:59 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[DBD::Sybase]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=450</guid>
		<description><![CDATA[Gdyby ktoś chciał robić DBD::Sybase (ja potrzebowałem do monitorowania bazy MS SQL) na Gentoo, to poniżej Manifest (dla 1.07 i 1.09): DIST DBD-Sybase-1.07.tar.gz 189553 SHA1 881fc8f1c65e39e8537f4cc2e93308caeab87eed SHA256 be41f930fda27447b520773a1461ba3f43d20e0a859bef0504c40f3f3fe067b0 DIST DBD-Sybase-1.09.tar.gz 194414 SHA1 23cad59ab7892732175336087093b1e3c2bda09a SHA256 516d44567f1c76aa6aba76879a371d3a44f4a69da3b06b304f375eb57bb2daf1 EBUILD DBD-Sybase-1.07.ebuild 669 SHA1 03a85b4da544032957b312dde5b0cf44e910e562 SHA256 14a2eca747ad29e297299ad3282e9f000a6e61f5eb63783f9c79f481250c465a EBUILD DBD-Sybase-1.09.ebuild 661 SHA1 8719cb6544289ed71d74d9a06c8cab5a60ba021d SHA256 e49e709405fc2b5c3ddf4bf1d27be1925c47446b1b2927b09dad571079aba93b Ebuild można pobrać z Gentoo Bug [...]]]></description>
			<content:encoded><![CDATA[<p>Gdyby ktoś chciał robić <a title="http://search.cpan.org/~mewp/DBD-Sybase-1.09/Sybase.pm" href="http://search.cpan.org/~mewp/DBD-Sybase-1.09/Sybase.pm"><code>DBD::Sybase</code></a> (ja potrzebowałem do monitorowania bazy MS SQL) na Gentoo, to poniżej <code>Manifest</code> (dla 1.07 i 1.09):</p>
<blockquote><p><code>DIST DBD-Sybase-1.07.tar.gz 189553 SHA1 881fc8f1c65e39e8537f4cc2e93308caeab87eed SHA256 be41f930fda27447b520773a1461ba3f43d20e0a859bef0504c40f3f3fe067b0<br />
DIST DBD-Sybase-1.09.tar.gz 194414 SHA1 23cad59ab7892732175336087093b1e3c2bda09a SHA256 516d44567f1c76aa6aba76879a371d3a44f4a69da3b06b304f375eb57bb2daf1<br />
EBUILD DBD-Sybase-1.07.ebuild 669 SHA1 03a85b4da544032957b312dde5b0cf44e910e562 SHA256 14a2eca747ad29e297299ad3282e9f000a6e61f5eb63783f9c79f481250c465a<br />
EBUILD DBD-Sybase-1.09.ebuild 661 SHA1 8719cb6544289ed71d74d9a06c8cab5a60ba021d SHA256 e49e709405fc2b5c3ddf4bf1d27be1925c47446b1b2927b09dad571079aba93b</code></p></blockquote>
<p><em>Ebuild</em> można pobrać z <a title="http://bugs.gentoo.org/42040" href="http://bugs.gentoo.org/42040">Gentoo Bug</a> (42040 &#8211; DBD-Sybase-1.02 (new package)). Przeróbka tego do 1.09 nie powinna być problemem.<br />
Oczywiście wszystko do <code>/usr/portage/dev-perl/DBD-Sybase</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2008/12/dbdsybase-na-gentoo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DBD::Oracle &#8211; problem z kompilacją</title>
		<link>http://guzik.net.pl/blog/2008/12/dbdoracle-problem-z-kompilacja/</link>
		<comments>http://guzik.net.pl/blog/2008/12/dbdoracle-problem-z-kompilacja/#comments</comments>
		<pubDate>Wed, 24 Dec 2008 08:14:30 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[DBD::Oracle]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=447</guid>
		<description><![CDATA[Budowałem DBD::Oracle na Gentoo 1.12.11.1 (Linux 2.6.18-xen-r12 x86_64), ale nie wyszło. Błędy po make: [...] x86_64-pc-linux-gnu-gcc -c  -I/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux/auto/DBI -I../ -DLINUX -D_GNU_SOURCE -D_REENTRANT -g -fno-strict-aliasing -pipe -Wdeclaration-after-statement -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -O2 -pipe -march=nocona   -DVERSION=\"1.22\" -DXS_VERSION=\"1.22\" -fPIC "-I/usr/lib64/perl5/5.8.8/x86_64-linux/CORE"  -Wall -Wno-comment -DUTF8_SUPPORT -DNEW_OCI_INIT -DORA_OCI_VERSION=\"10.2.0.3\" Oracle.c In file included from Oracle.xs:1: Oracle.h:37:17: error: oci.h: No such file or directory [...]]]></description>
			<content:encoded><![CDATA[<p>Budowałem <a title="http://search.cpan.org/~pythian/DBD-Oracle-1.22/Oracle.pm" href="http://search.cpan.org/~pythian/DBD-Oracle-1.22/Oracle.pm"><code>DBD::Oracle</code></a> na Gentoo 1.12.11.1 (Linux 2.6.18-xen-r12 x86_64), ale nie wyszło. Błędy po <code>make</code>:</p>
<blockquote><p><code>[...]<br />
x86_64-pc-linux-gnu-gcc -c  -I/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux/auto/DBI -I../ -DLINUX -D_GNU_SOURCE -D_REENTRANT -g -fno-strict-aliasing -pipe -Wdeclaration-after-statement -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -O2 -pipe -march=nocona   -DVERSION=\"1.22\" -DXS_VERSION=\"1.22\" -fPIC "-I/usr/lib64/perl5/5.8.8/x86_64-linux/CORE"  -Wall -Wno-comment -DUTF8_SUPPORT -DNEW_OCI_INIT -DORA_OCI_VERSION=\"10.2.0.3\" Oracle.c<br />
In file included from Oracle.xs:1:<br />
Oracle.h:37:17: error: oci.h: No such file or directory<br />
Oracle.h:38:22: error: oratypes.h: No such file or directory<br />
Oracle.h:39:20: error: ocidfn.h: No such file or directory<br />
[...]</code></p></blockquote>
<p>Rzeczywiście nigdzie nie ma ścieżki do katalogu z <code>oci.h</code>. Po instalacji <a title="http://packages.gentoo.org/package/dev-db/oracle-instantclient-basic" href="http://packages.gentoo.org/package/dev-db/oracle-instantclient-basic"><code>dev-db/oracle-instantclient-basic</code></a> (na Gentoo) wszystkie pliki nagłówkowe są w <code>/usr/lib64/oracle/10.2.0.3/client/include</code>. Żeby budowanie się powiodło, do <code>x86_64-pc-linux-gnu-gcc</code> trzeba dodać tą ścieżkę (<code>-I</code>).</p>
<p>Wszystko po to, by z <a title="http://www.nagios.org/" href="http://www.nagios.org/">Nagios</a> można było monitorować stan <a title="http://www.oracle.com/technology/software/products/database/index.html" href="http://www.oracle.com/technology/software/products/database/index.html">Oracle</a> (poprzez <a title="http://www.consol.de/opensource/nagios/check-oracle-health" href="http://www.consol.de/opensource/nagios/check-oracle-health"><code>check_oracle_health</code></a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2008/12/dbdoracle-problem-z-kompilacja/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
