<?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>Журнал системного программиста &#187; c-jdbc</title>
	<atom:link href="http://sadko.xskernel.org/archives/tag/c-jdbc/feed" rel="self" type="application/rss+xml" />
	<link>http://sadko.xskernel.org</link>
	<description>блог обо всём и ни о чём</description>
	<lastBuildDate>Wed, 14 Dec 2011 20:21:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Sequoia изнутри: заключение</title>
		<link>http://sadko.xskernel.org/archives/1403</link>
		<comments>http://sadko.xskernel.org/archives/1403#comments</comments>
		<pubDate>Fri, 28 Aug 2009 13:51:56 +0000</pubDate>
		<dc:creator>SadKo</dc:creator>
				<category><![CDATA[Кодинг]]></category>
		<category><![CDATA[Одминское]]></category>
		<category><![CDATA[c-jdbc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[sequoia]]></category>

		<guid isPermaLink="false">http://sadko.xskernel.org/?p=1403</guid>
		<description><![CDATA[Tweet Разбор полётов В общем, сегодня решил, что ну её нафиг, эту Sequoia. Ибо я так и не нашёл в сети реализации класса, выполняющего бэкап данных СУБД ORACLE для Sequoia. Разработчики много чего обещают, пророчат чуть ли не светлое будущее, а на самом деле ничего сверхнового и революционного в ней нет. Изначально я думал, что [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin: 0 0 5px 10px; " class="vk-button">
<!-- vkontakte share button -->
<script type="text/javascript">
<!--
document.write(VK.Share.button(
{
  url: 'http://sadko.xskernel.org/archives/1403',
  title: 'Sequoia изнутри: заключение',
  description: 'Разбор полётов\nВ общем, сегодня решил, что ну её нафиг, эту Sequoia. Ибо я так и не нашёл в сети реализации класса, выполняющего бэкап данных СУБД ORACLE для Sequoia.\nРазработчики много чего обещают, прор...',
  noparse: true 
}, 
{
  type: 'button',
  text: 'Скопировать'
}));
-->
</script>
<!-- / vkontakte share button -->
</div><div style="height:21px; padding-top:2px;" class="really_simple_share"><div style="float:left; " class="really_simple_share_linkedin"> 
				<script type="text/javascript" src="http://platform.linkedin.com/in.js"></script>
				<script type="in/share" data-counter="right" data-url="http://sadko.xskernel.org/archives/1403"></script>
			</div><div style="float:left; padding-left:10px;" class="really_simple_share_twitter"> 
				<a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" 
					data-text="Sequoia &ETH;&cedil;&ETH;&middot;&ETH;&frac12;&Ntilde;&Ntilde;&Ntilde;&ETH;&cedil;: &ETH;&middot;&ETH;&deg;&ETH;&ordm;&ETH;&raquo;&Ntilde;&Ntilde;&ETH;&micro;&ETH;&frac12;&ETH;&cedil;&ETH;&micro;" data-url="http://sadko.xskernel.org/archives/1403">Tweet</a> 
				<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script> 
			</div></div>
	<br style="clear:both;" /><h3>Разбор полётов</h3>
<p>В общем, сегодня решил, что ну её нафиг, эту Sequoia. Ибо я так и не нашёл в сети реализации класса, выполняющего бэкап данных СУБД ORACLE для Sequoia.<br />
Разработчики много чего обещают, пророчат чуть ли не светлое будущее, а на самом деле ничего сверхнового и революционного в ней нет.<br />
Изначально я думал, что разработчики написали свой парсер SQL-выражений под каждый движок, на деле же всё оказалось проще и прозаичнее: SQL-запросы тупо транслировались в базы.<br />
Про атомарность транзакций я вообще молчу: в подобной архитектуре она в принципе не может быть реализована.<br />
<span id="more-1403"></span><br />
Также очень сомнительна предсказуемость работы такой &#171;распределённой&#187; БД: в случае, если будет, например, использоваться СУБД ORACLE, и в нём будут введены Sequences (которые инкрементируются независимо от того, прошла транзакция, или был выполнен rollback), рассинхронизация данных таблиц при частых распараллеленных commit/rollback очевидна.<br />
Качая пакеты и исходники, я думал, что Sequoia &#8212; действительно серьёзный проект, так как архивы весили очень внушительно (21 метр для сорцов &#8212; не хухры-мухры), а на деле оказалось, что большую часть там занимали 3rd-party packages, а из исходников было только 86 файлов самого менеджера и примерно столько же файлов гламурной консоли управления.</p>
<h3>Концепция</h3>
<p>Несмотря на то, что Sequoia оказалось откровенной поделкой, концепция распределённой БД по принципу RAID достаточно интересна. Например, моё представление контроллера такой БД &#8212; это контроллер, который сам работает как БД, то есть имеет свой SQL-синтаксис, который потом адаптируется под синтаксис конкретного движка СУБД.<br />
Пример: на вход контроллера подаётся такое выражение:</p>

<div class="wp_codebox"><table><tr id="p14036"><td class="code" id="p1403code6"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">&#40;</span>nID<span style="color: #66cc66;">,</span> strMessage<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> Tm_First
<span style="color: #993333; font-weight: bold;">WHERE</span> strMessage <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'%Hello%'</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> nID <span style="color: #993333; font-weight: bold;">DESC</span> <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">2</span>;</pre></td></tr></table></div>

<p>Для MySQL это транслируется в:</p>

<div class="wp_codebox"><table><tr id="p14037"><td class="code" id="p1403code7"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`C_nID`</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">`C_strMessage`</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`T_Tm_First`</span>
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #ff0000;">`C_strMessage`</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'%Hello%'</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">`C_nID`</span> <span style="color: #993333; font-weight: bold;">DESC</span> <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">2</span></pre></td></tr></table></div>

<p>А для Oracle, например, вот так:</p>

<div class="wp_codebox"><table><tr id="p14038"><td class="code" id="p1403code8"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;C_nID&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;C_strMessage&quot;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span>
	<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;C_nID&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;C_strMessage&quot;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">&quot;T_Tm_First&quot;</span>
	<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #ff0000;">&quot;C_strMessage&quot;</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">&quot;%Hello%&quot;</span>
	<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">&quot;C_nID&quot;</span> <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">WHERE</span> rownum<span style="color: #66cc66;">&lt;=</span><span style="color: #cc66cc;">2</span></pre></td></tr></table></div>

<p>Как видно, в СУБД используется своя нотация, чтобы была возможность ведения системных таблиц для реализации транзакционности в распределённой базе.<br />
Для этого в таблицы, например, при создании можно дописывать поля, такие как transaction_id, а также вести дополнительную таблицу незавершённых транзакций, чтобы обеспечить возможность отката, а также исключить видимость данных до вызова commit.<br />
Таким образом, предыдущий пример усложняется для MySQL:</p>

<div class="wp_codebox"><table><tr id="p14039"><td class="code" id="p1403code9"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`C_nID`</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">`C_strMessage`</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`T_Tm_First`</span>
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #ff0000;">`C_strMessage`</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'%Hello%'</span>
<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">`trID`</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">`nID`</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`transactions`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">`C_nID`</span> <span style="color: #993333; font-weight: bold;">DESC</span> <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">2</span></pre></td></tr></table></div>

<p>И для ORACLE:</p>

<div class="wp_codebox"><table><tr id="p140310"><td class="code" id="p1403code10"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;C_nID&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;C_strMessage&quot;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span>
	<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;C_nID&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;C_strMessage&quot;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">&quot;T_Tm_First&quot;</span>
	<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #ff0000;">&quot;C_strMessage&quot;</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">&quot;%Hello%&quot;</span>
	<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">&quot;trID&quot;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;nID&quot;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">&quot;transactions&quot;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">&quot;C_nID&quot;</span> <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">WHERE</span> rownum<span style="color: #66cc66;">&lt;=</span><span style="color: #cc66cc;">2</span></pre></td></tr></table></div>

<p>Ну а про Recovery Log я вообще молчу: он должен быть в каждой БД, чтобы в случае отказа по другой БД можно было бы восстановить любую вновь введённую в строй.<br />
Тем не менее, это очень ограничивает реальные рамки использования таких фич СУБД, как:</p>
<ul>
<li>Триггеры (сложно, практически нереально сэмулировать сложные триггеры при batch-операциях без потери производительности);</li>
<li>Sequences (в принципе, можно сэмулировать);</li>
<li>PL/SQL (вообще непонятно как делать);</li>
<li>И т.д., и т.п. вещи, которые есть в одной СУБД, но отсутствуют или по-другому реализованы в другой.</li>
</ul>
<p>Если подобные фичи не нужны, то, в принципе, можно написать адаптер под любую СУБД. Но тогда встаёт вопрос, зачем использовать столь мощную СУБД, если все её возможности не используются по максимуму.</p>
<h3>Противопоставление</h3>
<p>Естественно, ничего из предложенной мною концепции Sequoia не делает. Мало того, усугубляет всю свою &#171;надёжную&#187; схему в RAIDb1 введением дополнительной СУБД для Recovery Log и ведением дампов, которые должны храниться на хосте контроллера.<br />
Да, она обеспечивает обратную совместимость с приложениями, но на этом всё и заканчивается.<br />
Если и делать кластер &#8212; то либо средствами разработчиков СУБД, либо таким костылём, который предложил я. Третье вряд ли дано.</p>
<h3>Резюме</h3>
<p>Проект закрыть, исходники закопать и больше не выкапывать.</p>
]]></content:encoded>
			<wfw:commentRss>http://sadko.xskernel.org/archives/1403/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sequoia изнутри #3</title>
		<link>http://sadko.xskernel.org/archives/1385</link>
		<comments>http://sadko.xskernel.org/archives/1385#comments</comments>
		<pubDate>Thu, 27 Aug 2009 14:46:01 +0000</pubDate>
		<dc:creator>SadKo</dc:creator>
				<category><![CDATA[Кодинг]]></category>
		<category><![CDATA[Одминское]]></category>
		<category><![CDATA[Свободное ПО]]></category>
		<category><![CDATA[Туториалы]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[c-jdbc]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[sequoia]]></category>

		<guid isPermaLink="false">http://sadko.xskernel.org/?p=1385</guid>
		<description><![CDATA[Tweet Пролог В предыдущем посте я описал, на какие грабли пришлось наступить, чтобы заставить Sequoia создавать таблицы в RecoveryLog и запускать backends. Тем не менее, сама работа контроллера по-прежнему оставалась некорректной, и, как выяснилось, без правки исходников решить проблему никак не получалось. Ковыряем исходники Исходники Sequoia точно так же, как дистрибутив и документация, доступны на [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin: 0 0 5px 10px; " class="vk-button">
<!-- vkontakte share button -->
<script type="text/javascript">
<!--
document.write(VK.Share.button(
{
  url: 'http://sadko.xskernel.org/archives/1385',
  title: 'Sequoia изнутри #3',
  description: 'Пролог\nВ предыдущем посте я описал, на какие грабли пришлось наступить, чтобы заставить Sequoia создавать таблицы в RecoveryLog и запускать backends. Тем не менее, сама работа контроллера по-прежнему оста...',
  noparse: true 
}, 
{
  type: 'button',
  text: 'Скопировать'
}));
-->
</script>
<!-- / vkontakte share button -->
</div><div style="height:21px; padding-top:2px;" class="really_simple_share"><div style="float:left; " class="really_simple_share_linkedin"> 
				<script type="text/javascript" src="http://platform.linkedin.com/in.js"></script>
				<script type="in/share" data-counter="right" data-url="http://sadko.xskernel.org/archives/1385"></script>
			</div><div style="float:left; padding-left:10px;" class="really_simple_share_twitter"> 
				<a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" 
					data-text="Sequoia &ETH;&cedil;&ETH;&middot;&ETH;&frac12;&Ntilde;&Ntilde;&Ntilde;&ETH;&cedil; #3" data-url="http://sadko.xskernel.org/archives/1385">Tweet</a> 
				<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script> 
			</div></div>
	<br style="clear:both;" /><h3>Пролог</h3>
<p>В <a href="http://sadko.xskernel.org/archives/1379">предыдущем посте</a> я описал, на какие грабли пришлось наступить, чтобы заставить Sequoia создавать таблицы в RecoveryLog и запускать backends. Тем не менее, сама работа контроллера по-прежнему оставалась некорректной, и, как выяснилось, без правки исходников решить проблему никак не получалось.<br />
<span id="more-1385"></span></p>
<h3>Ковыряем исходники</h3>
<p>Исходники Sequoia точно так же, как дистрибутив и документация, доступны <a href="http://www.continuent.com/community/lab-projects/sequoia">на официальном сайте</a>. После разархивации объём исходников меня разочаровал, я ожидал от подобной супер-системы большего числа файлов. Но не в количестве файлов суть.<br />
Ещё раз поглядев на генерируемое исключение, я дополз до проблемного кода в файле src/org/continuent/sequoia/controller/recoverylog/events/LogRequestEvent.java. Вот он:</p>
<pre>  <span style="color: #008000; font-weight: bold">public</span> <span style="color: #B00040">void</span> <span style="color: #0000FF">execute</span><span style="color: #666666">(</span>LoggerThread loggerThread<span style="color: #666666">,</span>
      RecoveryLogConnectionManager manager<span style="color: #666666">)</span>
  <span style="color: #666666">{</span>

    Trace logger <span style="color: #666666">=</span> loggerThread<span style="color: #666666">.</span><span style="color: #7D9029">getLogger</span><span style="color: #666666">();</span>
    <span style="color: #008000; font-weight: bold">try</span>
    <span style="color: #666666">{</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span>Translate<span style="color: #666666">.</span><span style="color: #7D9029">get</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;recovery.jdbc.loggerthread.log.info&quot;</span><span style="color: #666666">,</span>
            logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getLogId</span><span style="color: #666666">()));</span>

      PreparedStatement pstmt <span style="color: #666666">=</span> manager<span style="color: #666666">.</span><span style="color: #7D9029">getLogPreparedStatement</span><span style="color: #666666">();</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_LOG_ID</span><span style="color: #666666">,</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getLogId</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_VLOGIN</span><span style="color: #666666">,</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getLogin</span><span style="color: #666666">());</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_SQL</span><span style="color: #666666">,</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getQuery</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_SQL_PARAMS</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getQueryParams</span><span style="color: #666666">());</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_AUTO_CONN_TRAN</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getAutoConnTrans</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_TRANSACTION_ID</span><span style="color: #666666">,</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getTid</span><span style="color: #666666">());</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_REQUEST_ID</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getRequestId</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_EXEC_STATUS</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getExecutionStatus</span><span style="color: #666666">());</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_EXEC_TIME</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getExecutionTimeInMs</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_UPDATE_COUNT</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getUpdateCountResult</span><span style="color: #666666">());</span>

      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span>pstmt<span style="color: #666666">.</span><span style="color: #7D9029">toString</span><span style="color: #666666">());</span>
      <span style="color: #008000; font-weight: bold">try</span>
      <span style="color: #666666">{</span>
        pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setEscapeProcessing</span><span style="color: #666666">(</span>logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getEscapeProcessing</span><span style="color: #666666">());</span>

      <span style="color: #666666">}</span>
      <span style="color: #008000; font-weight: bold">catch</span> <span style="color: #666666">(</span>Exception ignore<span style="color: #666666">)</span>
      <span style="color: #666666">{</span>
      <span style="color: #666666">}</span>
      <span style="color: #408080; font-style: italic">// Здесь бросается исключение:</span>

      <span style="color: #B00040">int</span> updatedRows <span style="color: #666666">=</span> pstmt<span style="color: #666666">.</span><span style="color: #7D9029">executeUpdate</span><span style="color: #666666">();</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">((</span>updatedRows <span style="color: #666666">!=</span> <span style="color: #666666">1)</span> <span style="color: #666666">&amp;&amp;</span> logger<span style="color: #666666">.</span><span style="color: #7D9029">isWarnEnabled</span><span style="color: #666666">())</span>

        logger
            <span style="color: #666666">.</span><span style="color: #7D9029">warn</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;Recovery log did not update a single entry while executing: &quot;</span>
                <span style="color: #666666">+</span> pstmt<span style="color: #666666">.</span><span style="color: #7D9029">toString</span><span style="color: #666666">());</span>
    <span style="color: #666666">}</span>

    <span style="color: #008000; font-weight: bold">catch</span> <span style="color: #666666">(</span>SQLException e<span style="color: #666666">)</span>
    <span style="color: #666666">{</span>
      manager<span style="color: #666666">.</span><span style="color: #7D9029">invalidate</span><span style="color: #666666">();</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span><span style="color: #BA2121">&quot;T&quot;</span><span style="color: #666666">.</span><span style="color: #7D9029">equals</span><span style="color: #666666">(</span>logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getAutoConnTrans</span><span style="color: #666666">()))</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">error</span><span style="color: #666666">(</span>Translate<span style="color: #666666">.</span><span style="color: #7D9029">get</span><span style="color: #666666">(</span>
            <span style="color: #BA2121">&quot;recovery.jdbc.loggerthread.log.failed.transaction&quot;</span><span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">new</span> String<span style="color: #666666">[]{</span>

                logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getQuery</span><span style="color: #666666">(),</span> String<span style="color: #666666">.</span><span style="color: #7D9029">valueOf</span><span style="color: #666666">(</span>logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getTid</span><span style="color: #666666">())}),</span> e<span style="color: #666666">);</span>

      <span style="color: #008000; font-weight: bold">else</span>
        logger<span style="color: #666666">.</span><span style="color: #7D9029">error</span><span style="color: #666666">(</span>Translate<span style="color: #666666">.</span><span style="color: #7D9029">get</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;recovery.jdbc.loggerthread.log.failed&quot;</span><span style="color: #666666">,</span>
            logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getQuery</span><span style="color: #666666">()),</span> e<span style="color: #666666">);</span>

      <span style="color: #408080; font-style: italic">// Push object back in the queue, it needs to be logged again</span>
      loggerThread<span style="color: #666666">.</span><span style="color: #7D9029">putBackAtHeadOfQueue</span><span style="color: #666666">(</span><span style="color: #008000; font-weight: bold">this</span><span style="color: #666666">,</span> e<span style="color: #666666">);</span>
    <span style="color: #666666">}</span>

  <span style="color: #666666">}</span>
</pre>
<p>От этого кода я и стал плясать, в результате чего всё-таки смог найти место, где можно выплюнуть создаваемое SQL-выражение. Дело осталось за небольшим &#8212; скомпилить исходники.</p>
<h3>Сборка Sequoia</h3>
<p>Сборка, в принципе, несложна и выполняется через Ant. Но предварительно следовало сконфигурировать файл build.properties, в котором я прописал версию используемой JDK &#8212; 1.5:</p>
<pre>
javac.target = 1.5
javac.source = 1.5
</pre>
<p>После этого, немного поизучав build.xml, я запустил в shell следующую команду:</p>
<pre>
ant clean &#038;&#038; ant jar
</pre>
<p>Исходники собрались (правда, с ворнингами, ARGH!!!), и у меня на руках уже были новые JAR, которые я и подпихнул взамен штатных.</p>
<h3>Патчинг</h3>
<p>После перезапуска контроллера пропатченный код выплюнул в лог SQL-выражения, используемые для вставки/обновления данных RecoveryLog:</p>
<pre>
2009-08-26 19:17:25,368 DEBUG sequoia.controller.recoverylog Insert statement: INSERT INTO T_RECOVERY VALUES(?,?,?,?,?,?,?,?,?,?)
2009-08-26 19:17:25,372 DEBUG sequoia.controller.recoverylog Update statement: UPDATE T_RECOVERY SET exec_status=?,update_count=?,exec_time=? WHERE log_id=?
</pre>
<p>Синтаксис INSERT-выражения меня просто убил, так как в нём не учтено, что поля могут поменяться местами. Потратив час на модификацию кода, я, в конце-концов, пропатчил создаваемые SQL-выражения, а также добавил отладочную инфу к проблемной функции в файле src/org/continuent/sequoia/controller/recoverylog/events/LogRequestEvent.java:</p>
<pre>  <span style="color: #008000; font-weight: bold">public</span> <span style="color: #B00040">void</span> <span style="color: #0000FF">execute</span><span style="color: #666666">(</span>LoggerThread loggerThread<span style="color: #666666">,</span>
      RecoveryLogConnectionManager manager<span style="color: #666666">)</span>
  <span style="color: #666666">{</span>

    Trace logger <span style="color: #666666">=</span> loggerThread<span style="color: #666666">.</span><span style="color: #7D9029">getLogger</span><span style="color: #666666">();</span>
    <span style="color: #008000; font-weight: bold">try</span>
    <span style="color: #666666">{</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span>Translate<span style="color: #666666">.</span><span style="color: #7D9029">get</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;recovery.jdbc.loggerthread.log.info&quot;</span><span style="color: #666666">,</span>
            logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getLogId</span><span style="color: #666666">()));</span>

      PreparedStatement pstmt <span style="color: #666666">=</span> manager<span style="color: #666666">.</span><span style="color: #7D9029">getLogPreparedStatement</span><span style="color: #666666">();</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_LOG_ID</span><span style="color: #666666">,</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getLogId</span><span style="color: #666666">());</span>

      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>
        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;logID = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getLogId</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_VLOGIN</span><span style="color: #666666">,</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getLogin</span><span style="color: #666666">());</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;login = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getLogin</span><span style="color: #666666">());</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_SQL</span><span style="color: #666666">,</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getQuery</span><span style="color: #666666">());</span>

      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>
        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;query = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getQuery</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_SQL_PARAMS</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getQueryParams</span><span style="color: #666666">());</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;queryParams = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getQueryParams</span><span style="color: #666666">());</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_AUTO_CONN_TRAN</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getAutoConnTrans</span><span style="color: #666666">());</span>

      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>
        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;autoConnTrans = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getAutoConnTrans</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_TRANSACTION_ID</span><span style="color: #666666">,</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getTid</span><span style="color: #666666">());</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;transactionID = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getTid</span><span style="color: #666666">());</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_REQUEST_ID</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getRequestId</span><span style="color: #666666">());</span>

      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>
        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;RequestID = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getRequestId</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setString</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_EXEC_STATUS</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getExecutionStatus</span><span style="color: #666666">());</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;executionStatus = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getExecutionStatus</span><span style="color: #666666">());</span>
      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_EXEC_TIME</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getExecutionTimeInMs</span><span style="color: #666666">());</span>

      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>
        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;executionTimeMs = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getExecutionTimeInMs</span><span style="color: #666666">());</span>

      pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setLong</span><span style="color: #666666">(</span>RecoveryLog<span style="color: #666666">.</span><span style="color: #7D9029">COLUMN_INDEX_UPDATE_COUNT</span><span style="color: #666666">,</span> logEntry
          <span style="color: #666666">.</span><span style="color: #7D9029">getUpdateCountResult</span><span style="color: #666666">());</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;updateCount = &quot;</span> <span style="color: #666666">+</span> logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getUpdateCountResult</span><span style="color: #666666">());</span>

      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span>logger<span style="color: #666666">.</span><span style="color: #7D9029">isDebugEnabled</span><span style="color: #666666">())</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">debug</span><span style="color: #666666">(</span>pstmt<span style="color: #666666">.</span><span style="color: #7D9029">toString</span><span style="color: #666666">());</span>
      <span style="color: #008000; font-weight: bold">try</span>
      <span style="color: #666666">{</span>
        pstmt<span style="color: #666666">.</span><span style="color: #7D9029">setEscapeProcessing</span><span style="color: #666666">(</span>logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getEscapeProcessing</span><span style="color: #666666">());</span>

      <span style="color: #666666">}</span>
      <span style="color: #008000; font-weight: bold">catch</span> <span style="color: #666666">(</span>Exception ignore<span style="color: #666666">)</span>
      <span style="color: #666666">{</span>
      <span style="color: #666666">}</span>

      <span style="color: #B00040">int</span> updatedRows <span style="color: #666666">=</span> pstmt<span style="color: #666666">.</span><span style="color: #7D9029">executeUpdate</span><span style="color: #666666">();</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">((</span>updatedRows <span style="color: #666666">!=</span> <span style="color: #666666">1)</span> <span style="color: #666666">&amp;&amp;</span> logger<span style="color: #666666">.</span><span style="color: #7D9029">isWarnEnabled</span><span style="color: #666666">())</span>

        logger
            <span style="color: #666666">.</span><span style="color: #7D9029">warn</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;Recovery log did not update a single entry while executing: &quot;</span>
                <span style="color: #666666">+</span> pstmt<span style="color: #666666">.</span><span style="color: #7D9029">toString</span><span style="color: #666666">());</span>
    <span style="color: #666666">}</span>

    <span style="color: #008000; font-weight: bold">catch</span> <span style="color: #666666">(</span>SQLException e<span style="color: #666666">)</span>
    <span style="color: #666666">{</span>
      manager<span style="color: #666666">.</span><span style="color: #7D9029">invalidate</span><span style="color: #666666">();</span>
      <span style="color: #008000; font-weight: bold">if</span> <span style="color: #666666">(</span><span style="color: #BA2121">&quot;T&quot;</span><span style="color: #666666">.</span><span style="color: #7D9029">equals</span><span style="color: #666666">(</span>logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getAutoConnTrans</span><span style="color: #666666">()))</span>

        logger<span style="color: #666666">.</span><span style="color: #7D9029">error</span><span style="color: #666666">(</span>Translate<span style="color: #666666">.</span><span style="color: #7D9029">get</span><span style="color: #666666">(</span>
            <span style="color: #BA2121">&quot;recovery.jdbc.loggerthread.log.failed.transaction&quot;</span><span style="color: #666666">,</span> <span style="color: #008000; font-weight: bold">new</span> String<span style="color: #666666">[]{</span>

                logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getQuery</span><span style="color: #666666">(),</span> String<span style="color: #666666">.</span><span style="color: #7D9029">valueOf</span><span style="color: #666666">(</span>logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getTid</span><span style="color: #666666">())}),</span> e<span style="color: #666666">);</span>

      <span style="color: #008000; font-weight: bold">else</span>
        logger<span style="color: #666666">.</span><span style="color: #7D9029">error</span><span style="color: #666666">(</span>Translate<span style="color: #666666">.</span><span style="color: #7D9029">get</span><span style="color: #666666">(</span><span style="color: #BA2121">&quot;recovery.jdbc.loggerthread.log.failed&quot;</span><span style="color: #666666">,</span>
            logEntry<span style="color: #666666">.</span><span style="color: #7D9029">getQuery</span><span style="color: #666666">()),</span> e<span style="color: #666666">);</span>

      <span style="color: #408080; font-style: italic">// Push object back in the queue, it needs to be logged again</span>
      loggerThread<span style="color: #666666">.</span><span style="color: #7D9029">putBackAtHeadOfQueue</span><span style="color: #666666">(</span><span style="color: #008000; font-weight: bold">this</span><span style="color: #666666">,</span> e<span style="color: #666666">);</span>
    <span style="color: #666666">}</span>

  <span style="color: #666666">}</span>
</pre>
<p>Ряд исключений сразу исчез. Тем не менее, остались ещё проблемы, которые были исправлены только за счёт комментирования этих строчек кода:</p>
<pre><span style="color: #408080; font-style: italic">/*      try</span>
<span style="color: #408080; font-style: italic">      {</span>
<span style="color: #408080; font-style: italic">        pstmt.setEscapeProcessing(logEntry.getEscapeProcessing());</span>
<span style="color: #408080; font-style: italic">      }</span>
<span style="color: #408080; font-style: italic">      catch (Exception ignore)</span>

<span style="color: #408080; font-style: italic">      {</span>
<span style="color: #408080; font-style: italic">      }*/</span>
</pre>
<p>Только после этого и очередной, N-надцатой пересборки пакетов перезапускаемый контроллер перестал ругаться на вставку и выборку данных при прогонке теста. Краш тест?</p>
<h3>Краш-тест (leightweight version)</h3>
<p>В качестве leightweight-теста я решил воспользоваться Sequoia Console и вырубить второй backend:</p>
<pre>
CJDBC(admin) > disable oracle02
Disabling backend oracle02 with automatic checkpoint.
</pre>
<p>Прогнав тест, я убедился, что в первую базу запись была вставлена, а в отключенную &#8212; нет. При чём, содержимое Recovery Log пополнилось записями:</p>
<pre>
LOG_ID                 VLOGIN                                                           SQL_QUERY                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SQL_QUERY_PARAM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  AUTO_CONN_TRAN TRANSACTION_ID         REQUEST_ID             EXEC_STATUS EXEC_TIME              UPDATE_COUNT
---------------------- ---------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------- ---------------------- ---------------------- ----------- ---------------------- ----------------------
1                      user                                                             begin                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             T              0                      0                      S           0                      -1
2                      user                                                             INSERT INTO Tm_First (nID, strMessage, nCode) VALUES (?, ?, ?)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   <!%I|666|!%><!%S|Hello, World!|!%><!%I|13|!%>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    T              0                      0                      S           118                    1
3                      user                                                             commit                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            T              0                      0                      S           0                      0
4                      user                                                             rollback                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          T              1                      0                      S           0                      0
</pre>
<p>Что ж, впечатляет! Попробуем заново поднять backend:</p>
<pre>
CJDBC(admin) > enable oracle02
Enabling backend oracle02 from its last known checkpoint
</pre>
<p>После некоторых раздумий и логописательств, контроллер-таки остановился, и я убедился, что недостающая запись во второй базе появилась. Только это никак не ура, возвращаемся к краш-тестам.</p>
<h3>Краш-тест (hardcore version)</h3>
<p>Что ж, этот краш-тест, как и в предыдущих случаях, заключался в блокировке пользователя и обрубании коннекций с последующим запуском теста.<br />
Что же в результате? В RecoveryLog появилась запись о вставке, и в первый backend запись была вставлена. Я, было, обрадовался такому положению дел и разлочил пользовательскую учётку, что не вызвало никакой реакции со стороны контроллера. Последующие запуски теста не накладывали никаких отпечатков на вторую доступную базу.<br />
Тогда я решил перезапустить backend через консоль:</p>
<pre>
CJDBC(admin) > disable oracle02
Disabling backend oracle02 with automatic checkpoint.
CJDBC(admin) > enable oracle02
Enabling backend oracle02 from its last known checkpoint
Cannot enable backend oracle02 from a known state. Resynchronize this backend by restoring a dump.
</pre>
<p>Оппаньки! Это, значит, после временной потери коннекта я должен восстанавливать базу из бэкапа? Что за бред!!!</p>
<p>В поисках лекарства решил заглянуть в Administration Guide, но там нашёл инфу только про дампы.</p>
<h3>Резюме</h3>
<p>Фу и фи. Чем больше ковыряюсь в этой софтине, тем больше убеждаюсь в её реальной непродуманности и ненадёжности. Может быть, я чего-то упускаю, но за эти четыре дня у меня уже порой лезут глаза на лоб от её выходок. Больше всего поражают танцы с бубном вокруг, казалось бы, простых вещей. В общем, завтра ещё поковыряюсь с ней, может всё-таки докопаюсь до истины.</p>
]]></content:encoded>
			<wfw:commentRss>http://sadko.xskernel.org/archives/1385/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sequoia изнутри #2</title>
		<link>http://sadko.xskernel.org/archives/1379</link>
		<comments>http://sadko.xskernel.org/archives/1379#comments</comments>
		<pubDate>Thu, 27 Aug 2009 13:19:02 +0000</pubDate>
		<dc:creator>SadKo</dc:creator>
				<category><![CDATA[Кодинг]]></category>
		<category><![CDATA[Одминское]]></category>
		<category><![CDATA[Туториалы]]></category>
		<category><![CDATA[c-jdbc]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[log4j]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[sequoia]]></category>

		<guid isPermaLink="false">http://sadko.xskernel.org/?p=1379</guid>
		<description><![CDATA[Tweet Введение Собственно, после первой неудачи с RAIDb1, изложенной в этом посте, я решил воспользоваться такой фичей, как RecoveryLog. Для этого ещё раз перечитывал туториал по созданию виртуальной БД. RecoveryLog Что ж, для того, чтобы запустить RecoveryLog, нужно чётко прописать параметры каждой таблицы, а также заиметь ещё одну базу. Но, если мы заимеем ещё одну [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin: 0 0 5px 10px; " class="vk-button">
<!-- vkontakte share button -->
<script type="text/javascript">
<!--
document.write(VK.Share.button(
{
  url: 'http://sadko.xskernel.org/archives/1379',
  title: 'Sequoia изнутри #2',
  description: 'Введение\nСобственно, после первой неудачи с RAIDb1, изложенной в этом посте, я решил воспользоваться такой фичей, как RecoveryLog. Для этого ещё раз перечитывал туториал по созданию виртуальной БД.\n\nR...',
  noparse: true 
}, 
{
  type: 'button',
  text: 'Скопировать'
}));
-->
</script>
<!-- / vkontakte share button -->
</div><div style="height:21px; padding-top:2px;" class="really_simple_share"><div style="float:left; " class="really_simple_share_linkedin"> 
				<script type="text/javascript" src="http://platform.linkedin.com/in.js"></script>
				<script type="in/share" data-counter="right" data-url="http://sadko.xskernel.org/archives/1379"></script>
			</div><div style="float:left; padding-left:10px;" class="really_simple_share_twitter"> 
				<a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" 
					data-text="Sequoia &ETH;&cedil;&ETH;&middot;&ETH;&frac12;&Ntilde;&Ntilde;&Ntilde;&ETH;&cedil; #2" data-url="http://sadko.xskernel.org/archives/1379">Tweet</a> 
				<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script> 
			</div></div>
	<br style="clear:both;" /><h3>Введение</h3>
<p>Собственно, после первой неудачи с RAIDb1, изложенной <a href="http://sadko.xskernel.org/archives/1365">в этом посте</a>, я решил воспользоваться такой фичей, как RecoveryLog. Для этого ещё раз перечитывал туториал по созданию виртуальной БД.<br />
<span id="more-1379"></span></p>
<h3>RecoveryLog</h3>
<p>Что ж, для того, чтобы запустить RecoveryLog, нужно чётко прописать параметры каждой таблицы, а также заиметь ещё одну базу. Но, если мы заимеем ещё одну базу, надёжность такой системы резко снижается, так как в случае отказа RecoveryLog всё накрывается медным тазом. Как вариант, разработчики Sequoia предлагают создать для RecoveryLog отдельную виртуальную базу, объединённую&#8230; в RAIDb1! Это, получается, матрёшка в матрёшке. Поэтому такой бредятины я делать не стал, а просто-напросто создал в первой базе дополнительную схему (ну не было у меня ещё одного сервера БД), а вторую базу оставил под краш-тесты. Согласно заверениям разработчиков:</p>
<blockquote><p>The C-JDBC Recovery Log stores write queries and transactions between logical checkpoints defined by the user. The log can be only be stored in a database (or cluster of databases) using a JDBCRecoveryLog element.</p>
<p>The JDBCRecoveryLog stores the recovery information in a database. To access this database, you must provide the driver class name to load (driver), an optional jar file or directory where to find the class to load (driverPath), the JDBC url to access the database as well as a valid login/password.</p>
<p>A timeout in seconds can be defined for the sql requests. If no value is given, the default timeout is set to 60 seconds. Warning! 0 means no timeout and wait forever until completion.
</p></blockquote>
<p>Вроде бы, всё понятно. То есть, я теперь должен описать все типы полей для таблиц, чем я кропотливо и занялся.</p>
<h3>Грабли как они есть</h3>
<p>Для экономии времени я скопировал пример из каталога config и прописал вместо указанных типов соответствующие им типы ORACLE. После этого я запустил систему, контроллер стартовал и, вроде бы, в лог никаких исключений не сыпалось, я решил запустить тест (см. предыдущий пост), который повис на коннекте, потому что контроллер почему-то не поднял ни одного backend. Что за ерунда?<br />
После получаса гугления я-таки выполз на вот эту страничку:<br />
<a href="http://blogs.sun.com/JagadishPrasath/entry/using_sequoia_with_glassfish">Using Sequoia with GlassFish</a>.<br />
Собственно, оттуда почерпал сакральные знания о том, что нужно воспользоваться консолью, прилагаемой к дистрибутиву.</p>
<h3>Sequoia controller console</h3>
<p>Консоль запускается shell-скриптом из каталога bin, имеет гламурный вид (используются цветастые надписи). Примерно так:</p>
<pre>
sadovnikov:/opt/sequoia # bin/console.sh
Launching the Sequoia controller console
Initializing Controller module...
Initializing VirtualDatabase Administration module...
Initializing SQL Console module...
Sequoia driver (Sequoia core v2.10.10) successfully loaded.
localhost:1090 >
</pre>
<p>При этом, контроллер тоже должен быть запущен.<br />
Далее надо указать, какую виртуальную базу мы хотим админить:</p>
<pre>
localhost:1090 > admin CJDBC
Virtual database Administrator Login > admin
Virtual database Administrator Password >
Ready to administrate virtual database CJDBC
</pre>
<p>Для того, чтобы вся эта дребедень заработала, надо проинициализировать каждый backend:</p>
<pre>
CJDBC(admin) > initialize oracle01 force
Virtual Database CJDBC has been successfully initialized from backend oracle01
CJDBC(admin) > initialize oracle02 force
Virtual Database CJDBC has been successfully initialized from backend oracle02
</pre>
<p>После этого надо стартануть backends:</p>
<pre>
CJDBC(admin) > enable oracle01
Enabling backend oracle01 from its last known checkpoint
CJDBC(admin) > enable oracle02
Enabling backend oracle02 from its last known checkpoint
CJDBC(admin) >
</pre>
<p>Всё бы хорошо, но вот на включение backend система посыпала кучу исключений, потому что в примерах были описаны типы не для всех колонок.</p>
<h3>Мытарства с описанием RecoveryLog</h3>
<p>Скрипя сердцем я взял документацию и стал построчно сравнивать каждый параметр с целью поиска недостающих описаний колонок таблицы. После добавления недостающих колонок и присваивания им соответствующих типов я снова попытался поднять backend и&#8230; облом. Оказывается, даже в доках были описаны не все поля и требуемые для них типы. Вспомнив, что Sequoia использует для ведения логов <b>log4j</b>, полез в конфигу log4j.properties, где заменил строчку:<br />
<code>log4j.logger.org.continuent.sequoia.controller.recoverylog=INFO, Console,Filetrace</code><br />
На следующую:<br />
<code>log4j.logger.org.continuent.sequoia.controller.recoverylog=ALL, Console,Filetrace</code><br />
Вычислить, для кого нужно было включить логи, было несложно, так как в Stack Trace выплёвываемого исключения было написано, какой класс какого пакета его вызывал.<br />
Это мне сильно помогло, так как в лог стали писаться SQL Statements, используемые backend&#8217;ом для создания таблиц Recovery Log. Вот их пример:</p>
<pre>
2009-08-26 17:21:50,679 DEBUG sequoia.controller.recoverylog Log table create statement: CREATE TABLE RECOVERY (log_id INTEGER NOT NULL ENABLE,vlogin VARCHAR2(32) NOT NULL,sql VARCHAR2(32) NOT NULL,sql_param VARCHAR,auto_conn_tran NUMBER NOT NULL,transaction_id INTEGER NOT NULL,request_id INTEGER,exec_status NUMBER NOT NULL,exec_time INTEGER,update_count NUMBER, CONSTRAINT RECOVERY_PK PRIMARY KEY (log_id))
2009-08-26 17:21:50,681 DEBUG sequoia.controller.recoverylog Checkpoint table create statement: CREATE TABLE CHECKPOINT (name VARCHAR2(64) NOT NULL,log_id INTEGER, CONSTRAINT CHECKPOINT_PK PRIMARY KEY (name))
2009-08-26 17:21:50,682 DEBUG sequoia.controller.recoverylog Backend table create statement: CREATE TABLE BACKEND (database_name VARCHAR2(32) NOT NULL, backend_name VARCHAR2(32) NOT NULL,backend_state INTEGER, checkpoint_name VARCHAR2(32) NOT NULL )
2009-08-26 17:21:50,684 DEBUG sequoia.controller.recoverylog Dump table create statement: CREATE TABLE DUMP (dump_name VARCHAR2(32) NOT NULL,dump_date TIMESTAMP(6),dump_path VARCHAR2(64) NOT NULL,dump_format VARCHAR2(64) NOT NULL,checkpoint_name VARCHAR2(64) NOT NULL,backend_name VARCHAR2(64) NOT NULL,tables VARCHAR2(64) NOT NULL)
</pre>
<p>Только благодаря этому логу я смог выяснить, почему SQL statement у меня не прошёл (оказывается, ВНЕЗАПНО вылез тип VARCHAR для поля, которое не было описано в доке). Стыдно, господа-разработчики!</p>
<h3>Итоговый конфиг???</h3>
<p>После мытарств с конфигом я в конце-концов получил следующий конфиг контроллера:</p>
<pre><span style="color: #BC7A00">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;</span>
<span style="color: #BC7A00">&lt;!DOCTYPE SEQUOIA-CONTROLLER PUBLIC &quot;-//Continuent//DTD SEQUOIA-CONTROLLER 2.10.10//EN&quot;  &quot;http://sequoia.continuent.org/dtds/sequoia-controller-2.10.10.dtd&quot;&gt;</span>
<span style="color: #008000; font-weight: bold">&lt;SEQUOIA-CONTROLLER&gt;</span>

  <span style="color: #008000; font-weight: bold">&lt;Controller</span> <span style="color: #7D9029">port=</span><span style="color: #BA2121">&quot;25322&quot;</span><span style="color: #008000; font-weight: bold">&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;Report</span> <span style="color: #7D9029">hideSensitiveData=</span><span style="color: #BA2121">&quot;true&quot;</span> <span style="color: #7D9029">generateOnShutdown=</span><span style="color: #BA2121">&quot;true&quot;</span> <span style="color: #7D9029">generateOnFatal=</span><span style="color: #BA2121">&quot;true&quot;</span> <span style="color: #7D9029">enableFileLogging=</span><span style="color: #BA2121">&quot;true&quot;</span> <span style="color: #008000; font-weight: bold">/&gt;</span>

    <span style="color: #008000; font-weight: bold">&lt;JmxSettings&gt;</span>
      <span style="color: #008000; font-weight: bold">&lt;RmiJmxAdaptor/&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;/JmxSettings&gt;</span>

    <span style="color: #008000; font-weight: bold">&lt;VirtualDatabase</span> <span style="color: #7D9029">configFile=</span><span style="color: #BA2121">&quot;/opt/sequoia/config/virtualdatabase/sequoia.xml&quot;</span> <span style="color: #7D9029">virtualDatabaseName=</span><span style="color: #BA2121">&quot;CJDBC&quot;</span> <span style="color: #7D9029">autoEnableBackends=</span><span style="color: #BA2121">&quot;true&quot;</span> <span style="color: #7D9029">checkpointName=</span><span style="color: #BA2121">&quot;cjdbc_checkpoint&quot;</span> <span style="color: #008000; font-weight: bold">/&gt;</span>

  <span style="color: #008000; font-weight: bold">&lt;/Controller&gt;</span>
<span style="color: #008000; font-weight: bold">&lt;/SEQUOIA-CONTROLLER&gt;</span>
</pre>
<p>И следующий конфиг виртуальной базы:</p>
<pre><span style="color: #BC7A00">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span style="color: #BC7A00">&lt;!DOCTYPE SEQUOIA PUBLIC &quot;-//Continuent//DTD SEQUOIA 2.10.10//EN&quot; &quot;http://sequoia.continuent.org/dtds/sequoia-2.10.10.dtd&quot;&gt;</span>
<span style="color: #008000; font-weight: bold">&lt;SEQUOIA&gt;</span>

  <span style="color: #008000; font-weight: bold">&lt;VirtualDatabase</span> <span style="color: #7D9029">name=</span><span style="color: #BA2121">&quot;CJDBC&quot;</span> <span style="color: #7D9029">maxNbOfConnections=</span><span style="color: #BA2121">&quot;150&quot;</span> <span style="color: #7D9029">minNbOfThreads=</span><span style="color: #BA2121">&quot;40&quot;</span> <span style="color: #7D9029">maxNbOfThreads=</span><span style="color: #BA2121">&quot;150&quot;</span> <span style="color: #7D9029">sqlDumpLength=</span><span style="color: #BA2121">&quot;80&quot;</span> <span style="color: #008000; font-weight: bold">&gt;</span>

    <span style="color: #008000; font-weight: bold">&lt;AuthenticationManager&gt;</span>
      <span style="color: #008000; font-weight: bold">&lt;Admin&gt;</span>
        <span style="color: #008000; font-weight: bold">&lt;User</span> <span style="color: #7D9029">username=</span><span style="color: #BA2121">&quot;admin&quot;</span> <span style="color: #7D9029">password=</span><span style="color: #BA2121">&quot;sql&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>
      <span style="color: #008000; font-weight: bold">&lt;/Admin&gt;</span>

      <span style="color: #008000; font-weight: bold">&lt;VirtualUsers&gt;</span>
        <span style="color: #008000; font-weight: bold">&lt;VirtualLogin</span> <span style="color: #7D9029">vLogin=</span><span style="color: #BA2121">&quot;user&quot;</span> <span style="color: #7D9029">vPassword=</span><span style="color: #BA2121">&quot;sql&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>
      <span style="color: #008000; font-weight: bold">&lt;/VirtualUsers&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;/AuthenticationManager&gt;</span>

    <span style="color: #408080; font-style: italic">&lt;!--</span>
<span style="color: #408080; font-style: italic">        Here is a list (non-exhaustive) of backends that can be used with C-JDBC.</span>
<span style="color: #408080; font-style: italic">    --&gt;</span>

    <span style="color: #408080; font-style: italic">&lt;!-- Database # 1 --&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;DatabaseBackend</span> <span style="color: #7D9029">name=</span><span style="color: #BA2121">&quot;oracle01&quot;</span> <span style="color: #7D9029">driver=</span><span style="color: #BA2121">&quot;oracle.jdbc.OracleDriver&quot;</span> <span style="color: #7D9029">url=</span><span style="color: #BA2121">&quot;jdbc:oracle:thin:@192.168.0.140:1521:oracle&quot;</span> <span style="color: #7D9029">connectionTestStatement=</span><span style="color: #BA2121">&quot;select * from dual&quot;</span><span style="color: #008000; font-weight: bold">&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;DatabaseSchema</span> <span style="color: #7D9029">dynamicPrecision=</span><span style="color: #BA2121">&quot;table&quot;</span> <span style="color: #7D9029">gatherSystemTables=</span><span style="color: #BA2121">&quot;false&quot;</span> <span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;ConnectionManager</span> <span style="color: #7D9029">vLogin=</span><span style="color: #BA2121">&quot;user&quot;</span> <span style="color: #7D9029">rLogin=</span><span style="color: #BA2121">&quot;cjdbc&quot;</span> <span style="color: #7D9029">rPassword=</span><span style="color: #BA2121">&quot;cjdbc&quot;</span><span style="color: #008000; font-weight: bold">&gt;</span>

                <span style="color: #008000; font-weight: bold">&lt;VariablePoolConnectionManager</span> <span style="color: #7D9029">initPoolSize=</span><span style="color: #BA2121">&quot;10&quot;</span> <span style="color: #7D9029">minPoolSize=</span><span style="color: #BA2121">&quot;5&quot;</span> <span style="color: #7D9029">maxPoolSize=</span><span style="color: #BA2121">&quot;50&quot;</span> <span style="color: #7D9029">idleTimeout=</span><span style="color: #BA2121">&quot;180&quot;</span> <span style="color: #7D9029">waitTimeout=</span><span style="color: #BA2121">&quot;120&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;/ConnectionManager&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;/DatabaseBackend&gt;</span>

    <span style="color: #408080; font-style: italic">&lt;!-- Database # 2 --&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;DatabaseBackend</span> <span style="color: #7D9029">name=</span><span style="color: #BA2121">&quot;oracle02&quot;</span> <span style="color: #7D9029">driver=</span><span style="color: #BA2121">&quot;oracle.jdbc.OracleDriver&quot;</span> <span style="color: #7D9029">url=</span><span style="color: #BA2121">&quot;jdbc:oracle:thin:@192.168.0.141:1521:oracle&quot;</span> <span style="color: #7D9029">connectionTestStatement=</span><span style="color: #BA2121">&quot;select * from dual&quot;</span><span style="color: #008000; font-weight: bold">&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;DatabaseSchema</span> <span style="color: #7D9029">dynamicPrecision=</span><span style="color: #BA2121">&quot;table&quot;</span> <span style="color: #7D9029">gatherSystemTables=</span><span style="color: #BA2121">&quot;false&quot;</span> <span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;ConnectionManager</span> <span style="color: #7D9029">vLogin=</span><span style="color: #BA2121">&quot;user&quot;</span> <span style="color: #7D9029">rLogin=</span><span style="color: #BA2121">&quot;cjdbc&quot;</span> <span style="color: #7D9029">rPassword=</span><span style="color: #BA2121">&quot;cjdbc&quot;</span><span style="color: #008000; font-weight: bold">&gt;</span>

                <span style="color: #008000; font-weight: bold">&lt;VariablePoolConnectionManager</span> <span style="color: #7D9029">initPoolSize=</span><span style="color: #BA2121">&quot;10&quot;</span> <span style="color: #7D9029">minPoolSize=</span><span style="color: #BA2121">&quot;5&quot;</span> <span style="color: #7D9029">maxPoolSize=</span><span style="color: #BA2121">&quot;50&quot;</span> <span style="color: #7D9029">idleTimeout=</span><span style="color: #BA2121">&quot;180&quot;</span> <span style="color: #7D9029">waitTimeout=</span><span style="color: #BA2121">&quot;120&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;/ConnectionManager&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;/DatabaseBackend&gt;</span>

    <span style="color: #408080; font-style: italic">&lt;!--</span>
<span style="color: #408080; font-style: italic">        Request Manager</span>
<span style="color: #408080; font-style: italic">    --&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;RequestManager&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;RequestScheduler&gt;</span>
            <span style="color: #008000; font-weight: bold">&lt;RAIDb-1Scheduler</span> <span style="color: #7D9029">level=</span><span style="color: #BA2121">&quot;passThrough&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>
        <span style="color: #008000; font-weight: bold">&lt;/RequestScheduler&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;RequestCache&gt;</span>

            <span style="color: #008000; font-weight: bold">&lt;MetadataCache</span> <span style="color: #7D9029">maxNbOfMetadata=</span><span style="color: #BA2121">&quot;10000&quot;</span> <span style="color: #7D9029">maxNbOfField=</span><span style="color: #BA2121">&quot;0&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

            <span style="color: #008000; font-weight: bold">&lt;ParsingCache</span> <span style="color: #7D9029">backgroundParsing=</span><span style="color: #BA2121">&quot;false&quot;</span> <span style="color: #7D9029">maxNbOfEntries=</span><span style="color: #BA2121">&quot;5000&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

            <span style="color: #008000; font-weight: bold">&lt;ResultCache</span> <span style="color: #7D9029">granularity=</span><span style="color: #BA2121">&quot;table&quot;</span> <span style="color: #7D9029">maxNbOfEntries=</span><span style="color: #BA2121">&quot;100000&quot;</span> <span style="color: #7D9029">pendingTimeout=</span><span style="color: #BA2121">&quot;0&quot;</span> <span style="color: #008000; font-weight: bold">/&gt;</span>
        <span style="color: #008000; font-weight: bold">&lt;/RequestCache&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;LoadBalancer&gt;</span>
            <span style="color: #008000; font-weight: bold">&lt;RAIDb-1&gt;</span>
                <span style="color: #008000; font-weight: bold">&lt;WaitForCompletion</span> <span style="color: #7D9029">policy=</span><span style="color: #BA2121">&quot;first&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

                <span style="color: #008000; font-weight: bold">&lt;RAIDb-1-LeastPendingRequestsFirst/&gt;</span>

            <span style="color: #008000; font-weight: bold">&lt;/RAIDb-1&gt;</span>
        <span style="color: #008000; font-weight: bold">&lt;/LoadBalancer&gt;</span>

      <span style="color: #008000; font-weight: bold">&lt;RecoveryLog</span> <span style="color: #7D9029">driver=</span><span style="color: #BA2121">&quot;oracle.jdbc.OracleDriver&quot;</span> <span style="color: #7D9029">url=</span><span style="color: #BA2121">&quot;jdbc:oracle:thin:@192.168.0.140:1521:oracle&quot;</span> <span style="color: #7D9029">login=</span><span style="color: #BA2121">&quot;cjdbcrec&quot;</span> <span style="color: #7D9029">password=</span><span style="color: #BA2121">&quot;cjdbcrec&quot;</span><span style="color: #008000; font-weight: bold">&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;RecoveryLogTable</span> <span style="color: #7D9029">tableName=</span><span style="color: #BA2121">&quot;RECOVERY&quot;</span>
            <span style="color: #7D9029">logIdColumnType=</span><span style="color: #BA2121">&quot;INTEGER NOT NULL ENABLE&quot;</span>
            <span style="color: #7D9029">vloginColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(64) NOT NULL&quot;</span>
            <span style="color: #7D9029">sqlColumnName=</span><span style="color: #BA2121">&quot;sql&quot;</span>

            <span style="color: #7D9029">sqlColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(2048) NOT NULL&quot;</span>
            <span style="color: #7D9029">sqlParamColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(2048)&quot;</span>
            <span style="color: #7D9029">autoConnTranColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(4) NOT NULL&quot;</span>
            <span style="color: #7D9029">transactionIdColumnType=</span><span style="color: #BA2121">&quot;INTEGER NOT NULL&quot;</span>
            <span style="color: #7D9029">requestIdColumnType=</span><span style="color: #BA2121">&quot;INTEGER&quot;</span>

            <span style="color: #7D9029">execTimeColumnType=</span><span style="color: #BA2121">&quot;INTEGER&quot;</span>
            <span style="color: #7D9029">updateCountColumnType=</span><span style="color: #BA2121">&quot;NUMBER&quot;</span>
            <span style="color: #7D9029">extraStatementDefinition=</span><span style="color: #BA2121">&quot;, CONSTRAINT RECOVERY_PK PRIMARY KEY (log_id)&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;CheckpointTable</span> <span style="color: #7D9029">tableName=</span><span style="color: #BA2121">&quot;CHECKPOINT&quot;</span>

            <span style="color: #7D9029">checkpointNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span>
            <span style="color: #7D9029">logIdColumnType=</span><span style="color: #BA2121">&quot;INTEGER&quot;</span>
            <span style="color: #7D9029">extraStatementDefinition=</span><span style="color: #BA2121">&quot;, CONSTRAINT CHECKPOINT_PK PRIMARY KEY (name)&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;BackendTable</span> <span style="color: #7D9029">tableName=</span><span style="color: #BA2121">&quot;BACKEND&quot;</span>

            <span style="color: #7D9029">databaseNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(64) NOT NULL&quot;</span>
            <span style="color: #7D9029">backendNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span>
            <span style="color: #7D9029">checkpointNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;DumpTable</span> <span style="color: #7D9029">tableName=</span><span style="color: #BA2121">&quot;DUMP&quot;</span>

            <span style="color: #7D9029">dumpNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(64) NOT NULL&quot;</span>
            <span style="color: #7D9029">dumpDateColumnType=</span><span style="color: #BA2121">&quot;TIMESTAMP(6)&quot;</span>
            <span style="color: #7D9029">dumpPathColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span>
            <span style="color: #7D9029">dumpFormatColumnType=</span><span style="color: #BA2121">&quot;CLOB NOT NULL&quot;</span>
            <span style="color: #7D9029">checkpointNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR(128) NOT NULL&quot;</span>

            <span style="color: #7D9029">backendNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span>
            <span style="color: #7D9029">tablesColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>
      <span style="color: #008000; font-weight: bold">&lt;/RecoveryLog&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;/RequestManager&gt;</span>
  <span style="color: #008000; font-weight: bold">&lt;/VirtualDatabase&gt;</span>

<span style="color: #008000; font-weight: bold">&lt;/SEQUOIA&gt;</span>enableFileLogging=&quot;true&quot; /&gt;
    <span style="color: #008000; font-weight: bold">&lt;JmxSettings&gt;</span>
      <span style="color: #008000; font-weight: bold">&lt;RmiJmxAdaptor/&gt;</span>
    <span style="color: #008000; font-weight: bold">&lt;/JmxSettings&gt;</span>

    <span style="color: #008000; font-weight: bold">&lt;VirtualDatabase</span> <span style="color: #7D9029">configFile=</span><span style="color: #BA2121">&quot;/opt/sequoia/config/virtualdatabase/sequoia.xml&quot;</span> <span style="color: #7D9029">virtualDatabaseName=</span><span style="color: #BA2121">&quot;CJDBC&quot;</span> <span style="color: #7D9029">autoEnableBackends=</span><span style="color: #BA2121">&quot;true&quot;</span> <span style="color: #7D9029">checkpointName=</span><span style="color: #BA2121">&quot;cjdbc_checkpoint&quot;</span> <span style="color: #008000; font-weight: bold">/&gt;</span>

  <span style="color: #008000; font-weight: bold">&lt;/Controller&gt;</span>
<span style="color: #008000; font-weight: bold">&lt;/SEQUOIA-CONTROLLER&gt;</span>
</pre>
<p>Добившись, наконец, того, что система создавала таблицы (важно &#8212; искомые типы полей брались по спецификации из доков и примеров) и запускала оба backend, я решился прогнать тест.</p>
<h3>Пока ещё не краш-тест</h3>
<p>Вставка данных прошла, но вот контроллер снова высыпал кучу исключений. Я искренне удивился, когда увидел, что он пытается вставлять null-значения в not-nullable колонки. Помимо этого, названия таблиц и колонка &#8216;log&#8217; были такими же, что и функции ORACLE, то есть, пришлось всё это переименовывать, в результате чего я получил-таки финальную версию конфиги для RecoveryLog:</p>
<pre>        <span style="color: #008000; font-weight: bold">&lt;RecoveryLogTable</span> <span style="color: #7D9029">tableName=</span><span style="color: #BA2121">&quot;T_RECOVERY&quot;</span>
            <span style="color: #7D9029">logIdColumnType=</span><span style="color: #BA2121">&quot;INTEGER NOT NULL ENABLE&quot;</span>
            <span style="color: #7D9029">vloginColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(64) NOT NULL&quot;</span>
            <span style="color: #7D9029">sqlColumnName=</span><span style="color: #BA2121">&quot;sql_query&quot;</span>

            <span style="color: #7D9029">sqlColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(2048) NOT NULL&quot;</span>
            <span style="color: #7D9029">sqlParamColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(2048)&quot;</span>
            <span style="color: #7D9029">autoConnTranColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(4) NOT NULL&quot;</span>
            <span style="color: #7D9029">transactionIdColumnType=</span><span style="color: #BA2121">&quot;INTEGER NOT NULL&quot;</span>
            <span style="color: #7D9029">requestIdColumnType=</span><span style="color: #BA2121">&quot;INTEGER&quot;</span>

            <span style="color: #7D9029">execTimeColumnType=</span><span style="color: #BA2121">&quot;INTEGER&quot;</span>
            <span style="color: #7D9029">updateCountColumnType=</span><span style="color: #BA2121">&quot;NUMBER&quot;</span>
            <span style="color: #7D9029">extraStatementDefinition=</span><span style="color: #BA2121">&quot;, CONSTRAINT RECOVERY_PK PRIMARY KEY (log_id)&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;CheckpointTable</span> <span style="color: #7D9029">tableName=</span><span style="color: #BA2121">&quot;T_CHECKPOINT&quot;</span>

            <span style="color: #7D9029">checkpointNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span>
            <span style="color: #7D9029">logIdColumnType=</span><span style="color: #BA2121">&quot;INTEGER&quot;</span>
            <span style="color: #7D9029">extraStatementDefinition=</span><span style="color: #BA2121">&quot;, CONSTRAINT CHECKPOINT_PK PRIMARY KEY (name)&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;BackendTable</span> <span style="color: #7D9029">tableName=</span><span style="color: #BA2121">&quot;T_BACKEND&quot;</span>

            <span style="color: #7D9029">databaseNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(64) NOT NULL&quot;</span>
            <span style="color: #7D9029">backendNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span>
            <span style="color: #7D9029">checkpointNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128)&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>

        <span style="color: #008000; font-weight: bold">&lt;DumpTable</span> <span style="color: #7D9029">tableName=</span><span style="color: #BA2121">&quot;T_DUMP&quot;</span>

            <span style="color: #7D9029">dumpNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(64) NOT NULL&quot;</span>
            <span style="color: #7D9029">dumpDateColumnType=</span><span style="color: #BA2121">&quot;TIMESTAMP(6)&quot;</span>
            <span style="color: #7D9029">dumpPathColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span>
            <span style="color: #7D9029">dumpFormatColumnType=</span><span style="color: #BA2121">&quot;CLOB NOT NULL&quot;</span>
            <span style="color: #7D9029">checkpointNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR(128) NOT NULL&quot;</span>

            <span style="color: #7D9029">backendNameColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span>
            <span style="color: #7D9029">tablesColumnType=</span><span style="color: #BA2121">&quot;VARCHAR2(128) NOT NULL&quot;</span><span style="color: #008000; font-weight: bold">/&gt;</span>
</pre>
<p>Думаете, это было последняя битва с Recovery Log? Ошибаетесь! При попытке вставить в таблицу контроллер продолжал стабильно сыпать исключения такого вида:</p>
<pre>
2009-08-26 17:59:53,394 ERROR sequoia.controller.recoverylog Failed to log begin for transaction 0
java.sql.SQLException: ORA-00911: invalid character

        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
        at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
        at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:955)
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1168)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
        at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3368)
        at org.continuent.sequoia.controller.recoverylog.events.LogRequestEvent.execute(LogRequestEvent.java:104)
        at org.continuent.sequoia.controller.recoverylog.LoggerThread.run(LoggerThread.java:678)
</pre>
<p>Вот вам и опровержение абзаца из мануала:</p>
<blockquote><p>Users reported successful usage of Sequoia with the following RDBMS: Oracle®, PostgreSQL, MySQL, Apache Derby, IBM DB2®, Sybase®, SAP DB (MySQL MaxDB), HyperSonic SQL, Firebird, MS SQL Server and InstantDB.</p></blockquote>
<p>В общем, Google помог слабо, нашёл один хиленький баг-тред, из которого вынес только то, что для достижения совместимости с ORACLE придётся патчить исходники.</p>
<h3>Резюме</h3>
<p>Проковырявшись с настройками RecoveryLog целый рабочий день, я так и не смог до конца заставить его работать. Видать, разработчики очень плохо тестировали свой продукт на СУБД ORACLE. Что самое обидное, в сети по возникающим проблемам с Sequoia найти ответ на свой вопрос очень тяжело.<br />
В следующей части я опишу процесс сборки Sequoia и её краш-тест.</p>
]]></content:encoded>
			<wfw:commentRss>http://sadko.xskernel.org/archives/1379/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

