We are pleased to announce the release of Recital 10.0.2.
Here is a brief list of features and functionality that you will find in the 10.0.2 release.
- New commands
SAVE/RESTORE DATASESSION [TO variable]
CONNECT "connectString"
DISCONNECT - New functions (OData compatible)
startsWith(haystack as character, needle as character)
endsWith(haystack as character, needle as character)
indexOf(haystack as character, needle as character)
substringOf(haystack as character, needle as character)
concat(expC1, expC2) - New system variables
_LASTINSERTEDSYNCNUM - Enhanced commands
Added CONNSTRING "connectingString" to the USE command to connect to remote servers (Recital, MySQL, PostgreSQL, Oracle, ODBC) - Further SQL query optimizer improvements to boost performance
- Performance improvements in Recital Web
- Forced all temporary files into temp directory (improves performance when local tmpfs is used as temp directory and reduces network i/o)
- Fixed cookie and session variable problems in Recital Web
- Fixed problem with temporary files being left after some server queries involving memos and object data types
- Improved performance of the Windows ODBC driver
- Fixed a security flaw in Recital Web
- Fixed all reported bugs
$ lsof | grep db.exe | grep accounts db.exe 16897 john 6uw REG 253,0 20012 3413872 /usr/recital100/qa/accounts.dbf db.exe 16897 john 7u REG 253,0 4176 3413885 /usr/recital100/qa/accounts.dbxIf you want to check for locks you can use lslk, for example;
$ lslk | grep db.exe | grep accounts db.exe 16897 253,0 3413872 20012 w 0 0 0 12319 0 /usr/recital100/qa/accounts.dbfIf you don't have lslk installed you can install it with one of the updaters, for example on redhat linux:
$ yum update lslk
In this article Barry Mavin, CEO and Chief Software Architect for Recital, details how to use the Client Drivers provided with the Recital Database Server to work with local or remote server-side OLE DB data sources.
Overview
The Recital Universal .NET Data Provider provides connectivity to the Recital Database Server running on any supported platform (Windows, Linux, Unix, OpenVMS) using the RecitalConnection object.
The Recital Universal JDBC Driver provides the same functionality for java applications.
The Recital Universal ODBC Driver provides the same functionality for applications that use ODBC.
Each of the above Client Drivers use a connection string to describe connections parameters.
The basic format of a connection string consists of a series of keyword/value pairs separated by semicolons. The equal sign (=) connects each keyword and its value.
The following table lists the valid names for keyword/values.
| Name | Default | Description |
|---|---|---|
|
Data Source
|
The name or network address of the instance of the Recital Database Server which to connect to. | |
| Directory | The target directory on the remote server where data to be accessed resides. This is ignored when a Database is specified. | |
|
Encrypt |
false | When true, DES3 encryption is used for all data sent between the client and server. |
| Initial Catalog -or- Database |
The name of the database on the remote server. | |
| Password -or- Pwd |
The password used to authenticate access to the remote server. | |
| User ID | The user name used to authenticate access to the remote server. | |
|
Connection Pooling |
false | Enable connection pooling to the server. This provides for one connection to be shared. |
| Logging | false | Provides for the ability to log all server requests for debugging purposes |
| Rowid | true | When Rowid is true (the default) a column will be post-fixed to each SELECT query that is a unique row identifier. This is used to provide optimised UPDATE and DELETE operations. If you use the RecitalSqlGrid, RecitalSqlForm, or RecitalSqlGridForm components then this column is not visible but is used to handle updates to the underlying data source. |
| Logfile | The name of the logfile for logging | |
| Gateway |
Opens an SQL gateway(Connection) to a foreign SQL data source on the remote server. Using Gateways, you can transparently access the following local or remote data sources:
The gateway can be specified in several formats: servertype@nodename:username/password-database e.g. oracle@nodename:username/password-database mysql@nodename:username/password-database postgresql@nodename:username/password-database -or- odbc:odbc_data_source_name_on_server oledb:oledb_connection_string_on_server jdbc:jdbc_driver_path_on_server;jdbc:Recital:args |
To connect to a server-side OLE DB data source, you use the gateway=value key/value pair in the following way.
gateway=oledb:oledb_connection_string_on_server
ImportantWhen specifying the connection string be sure to quote the gateway= with "...".
You can find examples of connection strings for most ODBC and OLE DB data sources by clicking here.
Example in C# using the Recital Universal .NET Data Provider:
////////////////////////////////////////////////////////////////////////
// include the references below
using System.Data;
using Recital.Data;
////////////////////////////////////////////////////////////////////////
// The following code example creates an instance of a DataAdapter that
// uses a Connection to the Recital Database Server, and a gateway to
// the SQL server Northwind database. It then populates a DataTable
// in a DataSet with the list of customers. The SQL statement and
// Connection arguments passed to the DataAdapter constructor are used
// to create the SelectCommand property of the DataAdapter.
public DataSet SelectCustomers()
{
string gateway = "oledb:Provider=sqloledb;Initial Catalog=Northwind;
Data Source=localhost;Integrated Security=SSPI";
RecitalConnection swindConn = new
RecitalConnection("Data Source=localhost;gateway=\""+gateway+"\");
RecitalCommand selectCMD = new
RecitalCommand("SELECT CustomerID, CompanyName FROM Customers", swindConn);
selectCMD.CommandTimeout = 30;
RecitalDataAdapter custDA = new RecitalDataAdapter();
custDA.SelectCommand = selectCMD;
swindConn.Open();
DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");
swindConn.Close();
return custDS;
}
Example in Java using the Recital Universal JDBC Driver:
////////////////////////////////////////////////////////////////////////
// standard imports required by the JDBC driver
import java.sql.*;
import java.io.*;
import java.net.URL;
import java.math.BigDecimal;
import Recital.sql.*;
////////////////////////////////////////////////////////////////////////
// The following code example creates a Connection to the Recital
// Database Server, and a gateway to the SQL server Northwind database.
// It then retrieves all the customers.
public void SelectCustomers()
{
// setup the Connection URL for JDBC
String gateway = "oledb:Provider=sqloledb;Initial Catalog=Northwind;
Data Source=localhost;Integrated Security=SSPI";
String url = "jdbc:Recital:Data Source=localhost;gateway=\""+gateway+"\";
// load the Recital Universal JDBC Driver
new RecitalDriver();
// create the connection
Connection con = DriverManager.getConnection(url);
// create the statement
Statement stmt = con.createStatement();
// perform the SQL query
ResultSet rs = stmt.executeQuery("SELECT CustomerID, CompanyName FROM Customers");
// fetch the data
while (rs.next())
{
String CompanyID = rs.getString("CustomerID");
String CompanyName = rs.getString("CompanyName");
// do something with the data...
}
// Release the statement
stmt.close();
// Disconnect from the server
con.close();
} DRBD:
DRBD (Distributed Replicated Block Device) forms the storage redundancy portition of a HA cluster setup. Explained in basic terms DRBD provides a means of achieving RAID 1 behavoir over a network, where whole block devices are mirrored accross the network.
To start off you will need 2 indentically sized raw drives or partitions. Many how-to's on the internet assume the use of whole drives, of course this will be better performance, but if you are simply getting familar with the technology you can repartition existing drives to allow for two eqaully sized raw partitions, one on each of the systems you will be using.
There are 3 DRBD replication modes:
• Protocol A: Write I/O is reported as completed as soon as it reached local disk and local TCP send buffer
• Protocol B: Write I/O is reported as completed as soon as it reached local disk and remote TCP buffer cache
• Protocol C: Write I/O is reported as completed as soon as it reached both local and remote disks.
If we were installing the HA cluster on a slow LAN or if the geogrphical seperation of the systems involved was great, then I recommend you opt for asyncronous mirroring (Protocol A) where the notifcation of a completed write operation occurs as soon as the local disk write is performed. This will greatly improve performance.
As we are setting up our HA cluster connected via a fast LAN, we will be using DRBD in fully syncronous mode, protocol C.
Protocol C involves the file system on the active node only being notified that the write operation was finished when the block is written to both disks of the cluster. Protocol C is the most commonly used mode of DRBD.
/etc/drbd.conf
global { usage-count yes; }
common { syncer { rate 10M; } }
resource r0 {
protocol C;
net {
max-buffers 2048;
ko-count 4;
}
on bailey {
device /dev/drbd0;
disk /dev/sda4;
address 192.168.1.125:7789;
meta-disk internal;
}
on giskard {
device /dev/drbd0;
disk /dev/sda3;
address 192.168.1.127:7789;
meta-disk internal;
}
}
drbd.conf explained:
Global section, usage-count. The DRBD project keeps statistics about the usage of DRBD versions. They do this by contacting a HTTP server each time a new DRBD version is installed on a system. This can be disabled by setting usage-count no;.
The common seciton contains configurations inhereted by all resources defined.
Setting the syncronisation rate, this is accoimplished by going to the syncer section and then assigning a value to the rate setting. The syncronisation rate refers to rate in which the data is being mirrored in the background. The best setting for the syncronsation rate is related to the speed of the network with which the DRBD systems are communicating on. 100Mbps ethernet supports around 12MBps, Giggabit ethernet somewhere around 125MBps.
in the configuration above, we have a resource defined as r0, the nodes are configured in the "on" host subsections.
"Device" configures the path of the logical block device that will be created by DRBD
"Disk" configures the block device that will be used to store the data.
"Address" configures the IP address and port number of the host that will hold this DRBD device.
"Meta-disk" configures the location where the metadata about the DRBD device will be stored.
You can set this to internal and DRBD will use the physical block device to store the information, by recording the metadata within the last sections of the disk.
Once you have created your configuration file, you must conduct the following steps on both the nodes.
Create device metadata.
$ drbdadm create-md r0
v08 Magic number not found
Writing meta data...
initialising activity log
NOT initialized bitmap
New drbd meta data block sucessfully created.
success
Attach the backing device.
$ drbdadm attach r0
Set the syncronisation parameters.
$ drbdadm syncer r0
Connect it to the peer.
$ drbdadm connect r0
Run the service.
$ service drbd start
Heartbeat:
Heartbeat provides the IP redundancy and the service HA functionailty.
On the failure of the primary node the VIP is assigned to the secondary node and the services configured to be HA are started on the secondary node.
Heartbeat configuration:
/etc/ha/ha.conf
## /etc/ha.d/ha.cf on node1
## This configuration is to be the same on both machines
## This example is made for version 2, comment out crm if using version 1
// replace the node variables with the names of your nodes.
crm no
keepalive 1
deadtime 5
warntime 3
initdead 20
bcast eth0
auto_failback yes
node bailey
node giskard
/etc/ha.d/authkeys
// The configuration below set authentication off, and encryption off for the authentication of nodes and their packets.
//Note make sure the authkeys file has the correct permisisions chmod 600
## /etc/ha.d/authkeys
auth 1
1 crc
/etc/ha.d/haresources
//192.168.1.40 is the VIP (Virtual IP) assigned to the cluster.
//the "smb" in the configuration line represents the service we wish to make HA
// /devdrbd0 represents the resource name you configured in the drbd.conf
## /etc/ha.d/haresources
## This configuration is to be the same on both nodes
bailey 192.168.1.40 drbddisk Filesystem::/dev/drbd0::/drbdData::ext3 smb
Usually, you do not need to setup an email server under Linux. Most GUI email clients support Gmail POP3 and IMAP configurations. But, how do you send mail via the standard /usr/bin/mail user agents in a shell script? Programs such as sendmail / postfix / exim can be configured as a gmail smarthost but they are largely overkill for this use. The ssmtp program is a neat utility that does just that for you via gmail.
In this article Barry Mavin, CEO and Chief Software Architect for Recital, details Working with Stored Procedures in the Recital Database Server.
Overview
Stored procedures and user-defined functions are collections of SQL statements and optional control-of-flow statements written in the Recital 4GL (compatible with VFP) stored under a name and saved in a Database. Both stored procedures and user-defined functions are just-in-time compiled by the Recital database engine. Using the Database Administrator in Recital Enterprise Studio, you can easily create, view, modify, and test Stored Procedures, Triggers, and user-defined functions
Creating and Editing Stored Procedures
To create a new Stored Procedure, right-click the Procedures node in the Databases tree of the Project Explorer and choose Create. To modify an existing stored procedure select the Stored Procedure in the Databases Tree in the Project Explorer by double-clicking on it or selecting Modify from the context menu . By convertion we recommend that you name your Stored Procedures beginning with "sp_xxx_", user-defined functions with "f_xxx_", and Triggers with "dt_xxx_", where xxx is the name of the table that they are associated with.
Testing the Procedure
To test run the Stored Procedure, select the Stored Procedure in the Databases Tree in the Project Explorer by double-clicking on it. Once the Database Administrator is displayed, click the Run button to run the procedure.
Getting return values
Example Stored Procedure called "sp_myproc":
parameter arg1, arg2 return arg1 + arg2
Example calling the Stored Procedure from C# .NET:
////////////////////////////////////////////////////////////////////////
// include the references below
using System.Data;
using Recital.Data;
////////////////////////////////////////////////////////////////////////
// sample code to call a Stored Procedure that adds to numeric values together
public int CallStoredProcedure()
{
RecitalConnection conn = new
RecitalConnection("Data Source=localhost;Database=southwind;uid=?;pwd=?");
RecitalCommand cmd = new RecitalCommand();
cmd.Connection = conn;
cmd.CommandText = "sp_myproc(@arg1, @arg2)";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters["@arg1"].Value = 10;
cmd.Parameters["@arg2"].Value = 20;
conn.Open();
cmd.ExecuteNonQuery();
int result = (int)(cmd.Parameters["retvalue"].Value); // get the return value from the sp
conn.Close();
return result;
}
Writing Stored Procedures that return a Resultset
If you want to write a Stored Procedure that returns a ResultSet, you use the SETRESULTSET() function of the 4GL. Using the Universal .NET Data Provider, you can then execute the 4GL Stored Procedure and return the ResultSet to the client application for processing. ResultSets that are returned from Stored Procedures are read-only.
Example Stored Procedure called "sp_myproc":
parameter query
select * from customers &query into cursor "mydata"
return setresultset("mydata")
Example calling the Stored Procedure from C# .NET:
////////////////////////////////////////////////////////////////////////
// include the references below
using System.Data;
using Recital.Data;
////////////////////////////////////////////////////////////////////////
// sample code to call a stored procedure that returns a ResultSet
public void CallStoredProcedure()
{
RecitalConnection conn = new
RecitalConnection("Data Source=localhost;Database=southwind;uid=?;pwd=?");
RecitalCommand cmd = new RecitalCommand();
cmd.Connection = conn;
cmd.CommandText = "sp_myproc(@query)";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters["@query"].Value = "where not deleted()";
conn.Open();
RecitalDataReader dreader = cmd.ExecuteReader();
int sqlcnt = (int)(cmd.Parameters["sqlcnt"].Value); // returns number of affected rows
while (dreader.Read())
{
// read and process the data
}
dreader.Close();
conn.Close();
} After split brain has been detected, one node will always have the resource in a StandAlone connection state. The other might either also be in the StandAlone state (if both nodes detected the split brain simultaneously), or in WFConnection (if the peer tore down the connection before the other node had a chance to detect split brain).
At this point, unless you configured DRBD to automatically recover from split brain, you must manually intervene by selecting one node whose modifications will be discarded (this node is referred to as the split brain victim). This intervention is made with the following commands:
# drbdadm secondary resource
# drbdadm disconnect resource
# drbdadm -- --discard-my-data connect resource
On the other node (the split brain survivor), if its connection state is also StandAlone, you would enter:
# drbdadm connect resource
You may omit this step if the node is already in the WFConnection state; it will then reconnect automatically.
If all else fails and the machines are still in a split-brain condition then on the secondary (backup) machine issue:
drbdadm invalidate resource
If you are using the Oracle Gateway in Recital, make sure the Oracle environment (ORACLE_HOME, ORACLE_SID etc.) is set up before starting the Recital Server. If not, you will see the error ORA-01019. A call to the Oracle environment setup script can be added to the /etc/init.d/recital script if your Recital Server is set to run on startup.
The Openfiler NAS/SAN Appliance (NSA) is a Storage Management Operating System / NAS Appliance distribution. It is powered by the Linux 2.6 kernel and Open Source applications such as Apache, Samba, LVM2, ext3, Linux NFS and iSCSI Enterprise Target. Openfiler combines these ubiquitous technologies into a small, easy to manage solution fronted by a powerful web-based management interface. Openfiler allows you to build a Network Attached Storage (NAS) and/or Storage Area Network (SAN) appliance, using industry-standard hardware, in less than 10 minutes of installation time.
Building upon the popularity of server virtualization technologies such as VMware, Virtual Iron, and Xen, Openfiler can also be deployed as a virtual machine instance or on a bare metal machine.
This deployment flexibility of Openfiler ensures that storage administrators are able to make the best use of system performance and storage capacity resources when allocating and managing networked storage in a multi-platform environment.
Openfiler is ideally suited for use with High Availability Recital applications as it incorporates:
- Heartbeat cluster manager
- drbd disk replication
- CIFS
- NFS
- Software and hardware RAID
- FTP
- rsync
- HTTP/DAV
- iSCSI
- LVM2
- Multiple NIC bonding for High Availability
- Powerful web-based GUI
./configure CFLAGS='-arch x86_64' APXSLDFLAGS='-arch x86_64' --with-apxs=/usr/sbin/apxsThen you must pass the these additional flags to the apxs command in order to generate a Universal Binary shared module.
-Wl,-dynamic -Wl,'-arch ppc' -Wl,'-arch ppc64' -Wl,'-arch i386' -Wl,'-arch x86_64' -Wc,-dynamic -Wc,'-arch ppc' -Wc,'-arch ppc64' -Wc,'-arch i386' -Wc,'-arch x86_64'If you then do a file command on the shared module it should return;
$ file mod_recital.so mod_recital2.2.so: Mach-O universal binary with 4 architectures mod_recital2.2.so (for architecture ppc7400): Mach-O bundle ppc mod_recital2.2.so (for architecture ppc64): Mach-O 64-bit bundle ppc64 mod_recital2.2.so (for architecture i386): Mach-O bundle i386 mod_recital2.2.so (for architecture x86_64): Mach-O 64-bit bundle x86_64The apache module files are stored in the /usr/libexec/apache2/ directory on a default apache install on the Mac and the configuration file is /private/etc/apache2/httpd.conf