<!-- Module User's Guide -->

<chapter>

	<title>&adminguide;</title>

	<section id="overview" xreflabel="Overview">
		<title>Overview</title>

		<section>
			<title> The idea</title>
			<para>
				A virtual DB will expose the same front DB api however, it will
				backed by many real DB. This means that a virtual DB URL 
				translates to many real DB URLs. This virtual layer also 
				enables us to use the real dbs in multiple ways such as: 
				parallel, failover(hotswap) and round-robin.

				Therefore:
					each virtual DB URL with associated real dbs and
					a way to use(mode) it's real dbs must be specified.
			</para>
		</section>


		<section>
			<title>Modes</title>
			<para>
					The implemented modes are:
				<itemizedlist>
					<listitem>
							FAILOVER
						<para>
								Use the first URL; if it fails, take the next
								URL and redo the operation.
						</para>
					</listitem>
					<listitem>
							PARALLEL
						<para>
								Use all the URLs in the virtual DB URL set.
								Fails if all the URLs fail.
						</para>
					</listitem>
					<listitem>
							ROUND (round-robin)
						<para>
								Use the next URL each time; if it fails, 
								use the next one, redo operation.
						</para>
					</listitem>
				</itemizedlist>
			</para>
			<para>
			When choosing the db virtual mode, be sure that there is a full
			compatibility between the DB operations you want to do (inserts, 
			updates, deletes,...) and the relation (if any) between the real
			DB URLs you have in the set - can be completely independent, can be
			nodes of the same cluster, or any other combination.
			</para>
		</section>
		<section>
			<title>Capabilities</title>
			<para>
			For each set (or new virtual DB URL), the capabilities are
			automatically calculated based on the capabilities provided by the
			real DB URLs from the set. A logical AND is done for each
			cabability over all the URLs in the set. Shortly, in order for the
			virtual URL to provide a certain capability, ALL its real URLs 
			must provide that capability.
			</para>
			<para>
			Note that starting with version 2.2 db_virtual supports 
			async_raw_query and async_raw_resume functions currently
			implemented only by the mysql database engine.
			</para>
		</section>

		<section>
			<title> Failures</title>
			<para>
				<programlisting>
	When an operation from a process on a real DB fails:
		it is marked (global and local CAN flag down)
		its connection closed

	Later a timer process (probe):
	foreach virtual db_url
		foreach real db_url
			if global CAN down
				try to connect
			if ok
				global CAN up
				close connection

	Later each process:
		if local CAN down and global CAN up
			if db_max_consec_retrys *
				try to connect
		if ok
			local CAN up

				</programlisting>
			</para>
			<para>
				Note *: there could be inconsistencies between the probe and each process so a retry limit is in order.
				It is reset and ignored by an MI command.
			</para>
		</section>

		<section>
			<title>The timer process</title>
			<para>
				The timer process(probe) is a process that tries to reconnect to failed dbs from time to time.
				It is a separate process so that when it blocks (for a timeout on the connection) it doesn't matter.
			</para>
		</section>

	</section>

	<section id="dependencies" xreflabel="Dependencies">
		<title>Dependencies</title>
		<section>
			<title>&osips; Modules</title>
			<para>
		The following modules must be loaded before this module:
				<itemizedlist>
					<listitem>
						<para>
				<!--<emphasis>No dependencies on other &osips; modules</emphasis>.-->
							<emphasis>At least one real DB module</emphasis>.
						</para>
					</listitem>
				</itemizedlist>
			</para>
		</section>
		<section>
			<title>External Libraries or Applications</title>
			<para>
		The following libraries or applications must be installed before running
		&osips; with this module loaded:
				<itemizedlist>
					<listitem>
						<para>
				<!--<emphasis>libmysqlclient-dev</emphasis> - the development libraries of mysql-client.-->
							<emphasis>None</emphasis>.
						</para>
					</listitem>
				</itemizedlist>
			</para>
		</section>
	</section>
	<section id="exported_parameters" xreflabel="Exported Parameters">
		<title>Exported Parameters</title>
		<section>
			<title>
				<varname>db_urls</varname> (str)
			</title>
			<para>
		Multiple value parameter used for virtual DB URLs declaration.
			</para>
			<example>
				<title>Set
					<varname>db_urls</varname> parameter
				</title>
				<programlisting format="linespecific">
...

modparam("group","db_url","virtual://set1")
modparam("presence|presence_xml", "db_url","virtual://set2")

modparam("db_virtual", "db_urls", "define set1 PARALLEL")
modparam("db_virtual", "db_urls", "mysql://opensips:opensipsrw@localhost/testa")
modparam("db_virtual", "db_urls", "postgres://opensips:opensipsrw@localhost/opensips")

modparam("db_virtual", "db_urls", "define set2 FAILOVER")
modparam("db_virtual", "db_urls", "mysql://opensips:opensipsrw@localhost/testa")
...
				</programlisting>
			</example>

		</section>
		<section>
			<title>
				<varname>db_probe_time</varname> (integer)
			</title>
			<para>
		Time interval after which a registered timer process attempts to check
		failed(as reported by other processes) connections to real dbs. The probe will connect and
		disconnect to the failed real DB and announce others.
			</para>
			<para>
				<emphasis>
			Default value is 10 (10 sec).
				</emphasis>
			</para>
			<example>
				<title>Set
					<varname>db_probe_time</varname> parameter
				</title>
				<programlisting format="linespecific">
...
modparam("db_virtual", "db_probe_time", 20)
...
				</programlisting>
			</example>
		</section>

		<section>
			<title>
				<varname>db_max_consec_retrys</varname> (integer)
			</title>
			<para>
		After the timer process has reported that it can connect to the real db,
		other processes will try to reconnect to it. There are cases where although
		the probe could connect some might fail. This parameter represents the number
		of consecutive failed retries that a process will do before it gives up.
		This value is reset and suppressed by a MI function(db_set).
			</para>
			<para>
				<emphasis>
			Default value is 10 (10 consecutive times).
				</emphasis>
			</para>
			<example>
				<title>Set
					<varname>db_max_consec_retrys</varname> parameter
				</title>
				<programlisting format="linespecific">
...
modparam("db_virtual", "db_max_consec_retrys", 20)
...

				</programlisting>
			</example>
		</section>
	</section>

	<section id="exported_mi_functions" xreflabel="Exported MI Functions">
		<title>Exported MI Functions</title>
		<section id="mi_db_get" xreflabel="db_get">
			<title>
				<function moreinfo="none">db_get</function>
			</title>
			<para>
		Return information about global state of the real dbs.
			</para>
			<para>
		Name:
				<emphasis>db_get</emphasis>
			</para>
			<para>Parameters:</para>
			<itemizedlist>
				<listitem>
					<para>None.
					</para>
				</listitem>
			</itemizedlist>

			<para>
		MI FIFO Command Format:
			</para>
			<programlisting  format="linespecific">
				opensips-cli -x mi db_get
			</programlisting>
		</section>



		<section id="mi_db_set" xreflabel="db_set">
			<title>
				<function moreinfo="none">db_set</function>
			</title>
			<para>Sets the permissions for real dbs access per set per db.</para>
			<para>Sets the reconnect reset flag.</para>
			<para>
		Name:
				<emphasis>db_set</emphasis>
			</para>
			<para>Parameters:</para>
			<itemizedlist>
				<listitem>set_index [int]</listitem>
				<listitem>db_url_index [int]</listitem>
				<listitem>may_use_db_flag [boolean]</listitem>
				<listitem>ignore_retries[boolean](optional)</listitem>
			</itemizedlist>

			<para>db_set 3 2 0 1 means: </para>
			<itemizedlist>
				<listitem> 3 - the fourth set (must exist)</listitem>
				<listitem> 2 - the third URL in the fourth set(must exist)</listitem>
				<listitem> 0 - processes are not allowed to use that URL</listitem>
				<listitem> 1 - reset and suppress db_max_consec_retrys</listitem>
			</itemizedlist>

			<para>
		MI FIFO Command Format:
			</para>
			<programlisting  format="linespecific">
				opensips-cli -x mi db_set 3 2 0 1
			</programlisting>
		</section>
	</section>

</chapter>

