Wednesday, October 30, 2013

High Availability Demo, Revised

This article is a complete revision of Demonstrating High Availability published wayyyy back in April 2009. It has been revised

  • to use SQL Anywhere 12 instead of version 11,

  • to show all the code in the article instead of forcing you to download a file, and

  • to use the funky new CREATE MIRROR SERVER and CREATE MIRROR OPTION statements instead of coding everything on the command line.

Step 1: Prepare the folders and the database file in server1.

All the databases and associated files will be stored in three subfolders immediately below the current folder: server1, server2 and arbiter.
REM Create the HA subfolders...

MD server1
MD server2
MD arbiter

REM Copy the V12 demo as a working database in server1...

PUSHD server1
COPY "C:\Documents and Settings\All Users\Documents\SQL Anywhere 12\Samples\demo.db" 
"%SQLANY12%\bin32\dblog.exe"^
  -t demo.log^
  demo.db 
"%SQLANY12%\bin32\dbspawn.exe"^
  -f "%SQLANY12%\bin32\dbeng12.exe"^
  -o "dbsrv12_demo_log.txt"^
  demo.db 
"%SQLANY12%\bin32\dbstop.exe"^
  -c "ENG=demo; UID=dba; PWD=sql"^
  -y^
  demo
POPD
The COPY command on line 10 copies the SQL Anywhere 12 demo database to the server1 subfolder.

The dblog, dbeng12 and dbstop commands on lines 11 through 21 ensure there is a functioning transaction log accompanying the database file.

Step 2: Start the partner1_demo server.

The following command starts the database in the server1 subfolder, and gives it the server name "partner1_demo":
"%SQLANY12%\bin32\dbspawn.exe"^
  -f "%SQLANY12%\bin32\dbsrv12.exe"^
  -n partner1_demo^
  -o "server1\dbsrv12_partner1_demo_log.txt"^
  -su sql^
  -x tcpip(port=55501;dobroadcast=no)^
  "server1\demo.db"^
  -xp on
Here's what the dbsrv12 command line options do:
-n partner1_demo^                             the server name for the first physical server
-o "server1\dbsrv12_partner1_demo_log.txt"^   where to write the diagnostic console log text file
-su sql^                                      the DBA password for connecting via DBN=utility_db
-x tcpip(port=55501;                          the port for direct connections to the first physical server
   dobroadcast=no)^                           to speed up connections between HA servers
"server1\demo.db"^                            the first physical database file   
-xp on                                        enables mirroring and read-only scale-out
Other than the -xp on option, there's nothing at all "HA" about this database yet. Those who remember the earlier way of doing things may notice that the new -xp option is quite a bit simpler than it used to be:
-xp partner=(eng=server2;links=tcpip(host=localhost;port=55502;timeout=1));mode=sync;
   auth=dJCnj8nUx3Lijoa8;arbiter=(eng=arbiter;links=tcpip(host=localhost;port=55500;timeout=1))

Step 3: Wait until the partner1_demo server is REALLY up and running.

All the commands in Steps 1 through 8 can be combined into one single command file, but if you do that, the commands in THIS step prevent the NEXT step from starting until the server started in the PREVIOUS step is ready to accept connections.

Other than that, this step is completely optional... go ahead, leave it out, see what happens :)
PAUSE Wait until partner1_demo is up and running...

ECHO OFF
:dbping
ECHO Waiting until partner1_demo is up and running...
"%SQLANY12%\bin32\dbping.exe"^
  -c "SERVER=partner1_demo; DBN=demo; UID=dba; PWD=sql; HOST=localhost:55501;"^
  -d
IF ERRORLEVEL 1 ( GOTO dbping ) ELSE ( GOTO continue )
:continue
ECHO ON
The dbping command on lines 6 through 8 tries connecting to the partner1_demo database, and if the connection fails the IF ERRORLEVEL 1 ( GOTO dbping ) command loops back to try again:
Press any key to continue . . .

Waiting until partner1_demo is up and running...
SQL Anywhere Server Ping Utility Version 12.0.1.3298
Ping database failed -- Specified database not found.
Waiting until partner1_demo is up and running...
SQL Anywhere Server Ping Utility Version 12.0.1.3298
Ping database failed -- Specified database not found.
...
Waiting until partner1_demo is up and running...
SQL Anywhere Server Ping Utility Version 12.0.1.3298
Connected to SQL Anywhere 12.0.1.3298 server "partner1_demo" and database "demo"
at address 127.0.0.1.
Ping database successful.

Step 4: Create the database objects to support HA.

Here's the dbisql command that runs the CREATE MIRROR SERVER and other SQL statements contained in the script that follows:
"%SQLANY12%\bin32\dbisql.com"^
  -c "SERVER=partner1_demo; DBN=demo; UID=dba; PWD=sql; HOST=localhost:55501;"^
  READ ENCODING Cp1252 "04s_script_to_create_supporting_objects.sql"
There are only three physical servers in this HA setup, but lines 5 through 31 in the script below show five separate CREATE MIRROR SERVER statements. These statements don't create actual servers (only a dbsrv12 command can do that), they just store descriptions of all the servers in the first physical database file. That physical database is the only database file that exists at this point in time, but Step 5 will copy it to create the second physical database, along with all five CREATE MIRROR SERVER definitions... so both physical databases will contain all the necessary information about each other and about the arbiter.
CREATE MIRROR SERVER    
   partner1_demo     the first "AS PARTNER" physical server, with a name matching the 
                        dbsrv12 -n option in Step 2, plus a state_file in the server1 folder
   partner2_demo     the second "AS PARTNER" physical server, with a name matching the 
                        dbsrv12 -n option in Step 6, plus a state_file in the server2 folder
   primary_demo      the logical "AS PRIMARY" server name for whichever partner happens to be the 
                        HA primary server at any point in time (hence the two ports).
   secondary_demo    the logical "AS MIRROR" Server name for whichever partner happens to be the
                        HA secondary or mirror server at any point in time (hence the two ports).
   arbiter_demo      the physical arbiter server, which doesn't have an actual database
                        or state file.
-----------------------------------------------------------------------------------------------
-- Describe the first of two physical mirror partners.
-- When this script is first executed, this is the only server actually running.

CREATE MIRROR SERVER partner1_demo AS PARTNER
   connection_string = 'SERVER=partner1_demo; host=localhost:55501'
   state_file        = 'server1/partner1_demo.state';

-- Describe the second of two physical mirror partners.

CREATE MIRROR SERVER partner2_demo AS PARTNER
   connection_string = 'SERVER=partner2_demo; host=localhost:55502'
   state_file        = 'server2/partner2_demo.state';

-- Describe the logical primary server.

CREATE MIRROR SERVER primary_demo AS PRIMARY
   connection_string = 'SERVER=primary_demo; host=localhost:55501,localhost:55502';

-- Describe the logical secondary (mirror) server.

CREATE MIRROR SERVER secondary_demo AS MIRROR
   connection_string = 'SERVER=secondary_demo; host=localhost:55501,localhost:55502';

-- Describe the physical arbiter server.
-- The information recorded here is only for use by the partner servers. The arbiter
-- server itself doesn't have any physical database associated with it, so all the options
-- required by the arbiter server must be specified on the arbiter server command line.

CREATE MIRROR SERVER arbiter_demo AS ARBITER
   connection_string ='SERVER=arbiter_demo; HOST=localhost:55500';

-- Define the authentication string.

SET MIRROR OPTION authentication_string = 'abc';

-- Set the HA synchronization mode to synchronous (default), asynchronous or asyncfullpage.

SET MIRROR OPTION synchronization_mode = 'synchronous';

-- Request automatic failover when synchronization_mode set to asynchronous or asyncfullpage.

SET MIRROR OPTION auto_failover = 'on';

-----------------------------------------------------------------------------------------------
CREATE FUNCTION which_database()
RETURNS LONG VARCHAR
BEGIN

   RETURN STRING (
      'PROPERTY ( ''MachineName'' )     = ', PROPERTY ( 'MachineName' ),     '\x0d\x0a',
      'PROPERTY ( ''Name'' )            = ', PROPERTY ( 'Name' ),            '\x0d\x0a',
      'PROPERTY ( ''ServerName'' )      = ', PROPERTY ( 'ServerName' ),      '\x0d\x0a',
      'PROPERTY ( ''TcpIpAddresses'' )  = ', PROPERTY ( 'TcpIpAddresses' ),  '\x0d\x0a',
      'DB_PROPERTY ( ''Name'' )         = ', DB_PROPERTY ( 'Name' ),         '\x0d\x0a',
      'DB_PROPERTY ( ''ReadOnly'' )     = ', DB_PROPERTY ( 'ReadOnly' ),     '\x0d\x0a',
      'DB_PROPERTY ( ''ArbiterState'' ) = ', DB_PROPERTY ( 'ArbiterState' ), '\x0d\x0a', 
      'DB_PROPERTY ( ''PartnerState'' ) = ', DB_PROPERTY ( 'PartnerState' ), '\x0d\x0a', 
      'DB_PROPERTY ( ''MirrorState'' )  = ', DB_PROPERTY ( 'MirrorState' ),  '\x0d\x0a', 
      'DB_PROPERTY ( ''File'' )         = ', DB_PROPERTY ( 'File' ),         '\x0d\x0a', 
      'CONNECTION_PROPERTY ( ''Number'' )          = ', CONNECTION_PROPERTY ( 'Number' ),   '\x0d\x0a',
      'CONNECTION_PROPERTY ( ''Name'' )            = ', CONNECTION_PROPERTY ( 'Name' ),     '\x0d\x0a',
      'CONNECTION_PROPERTY ( ''CommLink'' )        = ', CONNECTION_PROPERTY ( 'CommLink' ), '\x0d\x0a',
      'CONNECTION_PROPERTY ( ''CommNetworkLink'' ) = ', CONNECTION_PROPERTY ( 'CommNetworkLink' ) );

END; 
The SET MIRROR OPTION statements on lines 35 through 43 fill in some values the HA setup needs, only one of which (authentication_string) is actually required in this demo:
SET MIRROR OPTION 
   authentication_string = 'abc';         to be used by all the servers in the HA setup
   synchronization_mode = 'synchronous';  the default
   auto_failover = 'on';                  in case synchronization_mode is changed
The CREATE FUNCTION on lines 46 through 66 can be used to answer the question, "Who am I connected to?" Here's what it shows for one of the connections in Step 8:
MESSAGE which_database() TO CLIENT;

PROPERTY ( 'MachineName' )     = ENVY
PROPERTY ( 'Name' )            = primary_demo
PROPERTY ( 'ServerName' )      = partner1_demo
PROPERTY ( 'TcpIpAddresses' )  = 
DB_PROPERTY ( 'Name' )         = demo
DB_PROPERTY ( 'ReadOnly' )     = Off
DB_PROPERTY ( 'ArbiterState' ) = connected
DB_PROPERTY ( 'PartnerState' ) = connected
DB_PROPERTY ( 'MirrorState' )  = synchronized
DB_PROPERTY ( 'File' )         = C:\$ blogs and websites\blog SQLAnywhere\20131028 PENDING - High Availability Demo, Revised\server1\demo.db
CONNECTION_PROPERTY ( 'Number' )          = 87
CONNECTION_PROPERTY ( 'Name' )            = Updatable
CONNECTION_PROPERTY ( 'CommLink' )        = local
CONNECTION_PROPERTY ( 'CommNetworkLink' ) = TCPIP
Execution time: 0.031 seconds

Step 5: Create the database file in server2.

The dbbackup utility can be used to create a copy of the first database and store the files in the server2 subfolder:
"%SQLANY12%\bin32\dbbackup.exe"^
  -c "SERVER=partner1_demo; DBN=demo; UID=dba; PWD=sql; HOST=localhost:55501;"^
  -o "server2\dbbackup_partner1_demo_log.txt"^
  server2

Step 6: Start the partner2_demo server.

"%SQLANY12%\bin32\dbspawn.exe"^
  -f "%SQLANY12%\bin32\dbsrv12.exe"^
  -n partner2_demo^
  -o "server2\dbsrv12_partner2_demo_log.txt"^
  -su sql^
  -x tcpip(port=55502;dobroadcast=no)^
  "server2\demo.db"^
  -xp on
Except for the server name, subfolder and port number, these dbsrv12 options are the same here as in Step 2:
-n partner2_demo^                             the server name for the second physical server
-o "server2\dbsrv12_partner2_demo_log.txt"^   where to write the diagnostic console log text file
-su sql^                                      the DBA password for connecting via DBN=utility_db
-x tcpip(port=55502;                          the port for direct connections to the second physical server
   dobroadcast=no)^                           to speed up connections between HA servers
"server2\demo.db"^                            the second physical database file   
-xp on                                        enables mirroring and read-only scale-out
The simplicity of the new -xp on option is important to note again: All the other objects and options required by the HA setup were defined once, in the script shown in Step 4.

Step 7: Start the arbiter server.

Because there is no physical database file associated with the arbiter server, the objects and options defined by the script in Step 4 are no use when starting the arbiter. That's why the following dbsrv12 command doesn't just specify different server name, subfolder and port number values, it also includes -xf and -xa options to fill in the blanks:
"%SQLANY12%\bin32\dbspawn.exe"^
  -f "%SQLANY12%\bin32\dbsrv12.exe"^
  -n arbiter_demo^
  -o "arbiter\dbsrv12_arbiter_demo_log.txt"^
  -su sql^
  -x tcpip(port=55500;dobroadcast=no)^
  -xf "arbiter\arbiter_demo.state"^
  -xa "AUTH=abc;DBN=demo"
-n arbiter_demo^                              the server name for the physical arbiter server
-o "arbiter\dbsrv12_arbiter_demo_log.txt"^    where to write the diagnostic console log text file
-su sql^                                      the DBA password for connecting via DBN=utility_db
-x tcpip(port=55500;                          the port for direct connections to the arbiter server
   dobroadcast=no)^                           to speed up connections between HA servers
-xf "arbiter\arbiter_demo.state"^             where to store the arbiter server state file
-xa "AUTH=abc;                                the authorization string to use for this HA setup
   DBN=demo"                                  the database name to use for this HA setup
At this point, there are five servers running: three physical servers partner1_demo, partner2_demo and arbiter_demo started by the dbsrv12 commands in Steps 2, 6 and 7, and the two logical primary and secondary (mirror) servers defined by the script in Step 4: primary_demo and secondary_demo.

Step 8: Connect to the primary and secondary databases.

The following script uses the logical server names to connect to the primary and secondary (mirror) databases; the connection names are "Updatable" and "Read-Only" to indicate that changes can be made to database data only via the primary server:
PAUSE Wait until the servers are up and running, then

"%SQLANY12%\bin32\dbisql.com"^
  -c "SERVER=primary_demo; UID=dba; PWD=sql; HOST=localhost:55501,localhost:55502; CON=Updatable" 

"%SQLANY12%\bin32\dbisql.com"^
  -c "SERVER=secondary_demo; UID=dba; PWD=sql; HOST=localhost:55501,localhost:55502; CON=Read-Only" 
The connection strings don't need to specify a DBN database name value because there's only one database running on each server. Single SQL Anywhere servers can (and often do) run multiple databases, but in the world of High Availability that . . . is . . . just . . . not . . . done. Nothing in the documentation says "you can't do it", but none of the examples show how it might be done, and all of the documentation about High Availability refers to "database" in the singular.

Here's a screenshot show two dbisql sessions where a table that has been freshly created and loaded in "Updatable" dbisql session
CREATE TABLE t ( c INTEGER );
INSERT t VALUES ( 1 );
COMMIT;
is available almost immediately to be selected in the "Read-Only" session
SELECT * FROM t;
even though both sessions are connected to entirely different databases (the primary and the secondary):


What Failover Looks Like

Here are a pair of screenshots showing the "Updatable" dbisql session before and after
  • the original primary server partner1_demo was abruptly stopped,

  • the arbiter and secondary servers got together to make partner2_demo the new primary server,

  • and the "Updatable" dbisql session automatically reconnected to the new primary server partner2_demo (as shown by the "Reconnected to database" message):

"Read-Only" Can Become Updatable

After the failover described above, the "Read-Only" dbisql session remained connected to what became updatable primary server; consider these interesting facts:
  • PROPERTY ( 'ServerName' ) returns "partner2_demo" which is the physical server the "Read-Only" session remains connected to,

  • PROPERTY ( 'Name' ) still returns "secondary_demo" even though the physical server "partner2_demo" has now become the logical "primary_demo" server, and

  • DB_PROPERTY ( 'ReadOnly' ) is now set "Off" for this connection, which means the "Read-Only" session is now updatable.


In other words, nothing changes for the "Read-Only" session as long as the physical partner2_demo server (the original secondary, and now the new primary) remains running. Even if the partner1_demo server is restarted, it will assume the role of secondary server, and the "Read-Only" session will remain updatable.

It's a matter of opinion whether this behavior obeys the rule "Watcom Does Things The Way They Should Be Done", but the Help is clear on the question "Bug or Feature?"... it's a feature:

Configuring read-only access to a database running on the mirror server

Connections to the mirror database are maintained if failover occurs and the mirror server becomes the primary server. After failover, a connection can make changes to the database. You can query the value of the ReadOnly database property to determine whether the database you are connected to is updatable:
SELECT DB_PROPERTY( 'ReadOnly' );

Divine Right Of Update

There is nothing in the way of locks or blocks that a read-only connection to the secondary (mirror) server can do to prevent updates made to the primary database from being applied to the secondary... in other words, the primary database has divine right of update.

For example, consider the earlier scenario where a table is created and loaded in an "Updatable" dbisql session on the primary database
CREATE TABLE t ( c INTEGER );
INSERT t VALUES ( 1 );
COMMIT;
followed by a query in a "Read-Only" session on the secondary database, only this time with the isolation level set to 3:
SET TEMPORARY OPTION ISOLATION_LEVEL = '3';
SELECT * FROM t;

c
1
If an update is then made to the same row on the primary database
UPDATE t SET c = 2;
COMMIT;
it isn't blocked by the transaction started at isolation level 3 on the "Read-Only" connection. Far from being blocked, the update is not only applied to the primary database, it is also applied to the secondary database, and the next statement executed on the "Read-Only" connection fails horribly:
Could not execute statement.
Rollback occurred due to deadlock during prefetch
SQLCODE=-684, ODBC 3 State="40001"
Line 1, column 1
SELECT * FROM dummy

Several points are worth noting here:
  • The only true part of the statement "Rollback occurred due to deadlock during prefetch" is the part about the rollback.

  • There's no "deadlock" involved, it's a straightforward bludgeoning of the secondary database by the update coming from the primary database, and

  • there's no "prefetch" (it doesn't help to SET TEMPORARY OPTION PREFETCH = 'OFF').

  • It doesn't matter what the next statement is on the "Read-Only" session; it's the transaction that's getting bludgeoned, and in this case it was a "SELECT * FROM dummy" that got the bad news.

  • The bludgeoning doesn't happen until the COMMIT is executed on the primary database; until then, the secondary database doesn't see the update.

  • If you try to catch the SQLCODE -684 in an EXCEPTION handler, you will be unsuccessful; the EXCEPTION handler will be ignored.

  • If you try to catch the deadlock in a CREATE EVENT TYPE DEADLOCK handler, you will also be unsuccessful; it isn't a real deadlock, at least not a deadlock that will fire an EVENT.
Divine Right Of Update is also a feature rather than a bug, as explained in this Help topic: Mirror database queries.

Tip: If you want your read-only queries to behave in a robust manner on the secondary database, run them at isolation level 0, and issue a ROLLBACK after every SELECT to release schema locks as soon as possible. That way, updates and schema changes on the primary database won't cause (as much) grief for your read-only queries on the secondary. Why ROLLBACK? Well, you could do a COMMIT, it doesn't matter, they're read-only queries :)


Friday, October 18, 2013

AUTOINCREMENT without the DEFAULT

Question: How do I use DEFAULT AUTOINCREMENT for a legacy table I can't change?

It's common to encounter a certain [cough] reluctance to modify the schema of tables that have been around forever and ever. Sometimes, it's almost impossible... you can modify the application code to your heart's content, even add new tables, but not modify any of the old ones... even if you're suffering from a performance problem.

For example, let's say there are concurrency problems caused by a flawed primary key generation process, and you want to use DEFAULT AUTOINCREMENT to fix those problems, but you can't.

Answer: It is possible to obtain the concurrency benefits of DEFAULT AUTOINCREMENT without modifying the schema; you use empty shadow tables instead, and call GET_IDENTITY().

First, here are a couple of legacy tables t1 and t2, followed by corresponding shadow tables:

CREATE TABLE t1
   ( pkey INTEGER NOT NULL PRIMARY KEY,
     data INTEGER NOT NULL );

CREATE TABLE t2
   ( pkey INTEGER NOT NULL PRIMARY KEY,
     data INTEGER NOT NULL );

CREATE TABLE empty_shadow_t1
   ( pkey INTEGER NOT NULL PRIMARY KEY DEFAULT AUTOINCREMENT );

CREATE TABLE empty_shadow_t2
   ( pkey INTEGER NOT NULL PRIMARY KEY DEFAULT AUTOINCREMENT );
Here's how the application code can be modified to call GET_IDENTITY() before each INSERT:
BEGIN
DECLARE @pkey1 INTEGER;
DECLARE @pkey2 INTEGER;

SET @pkey1 = GET_IDENTITY ( 'empty_shadow_t1', 1 );
INSERT t1 VALUES ( @pkey1, 0 );
COMMIT;
SET @pkey2 = GET_IDENTITY ( 'empty_shadow_t2', 1 );
INSERT t2 VALUES ( @pkey2, 0 );
COMMIT;
SET @pkey1 = GET_IDENTITY ( 'empty_shadow_t1', 1 );
INSERT t1 VALUES ( @pkey1, 0 );
COMMIT;
SET @pkey2 = GET_IDENTITY ( 'empty_shadow_t2', 1 );
INSERT t2 VALUES ( @pkey2, 0 );
COMMIT;
SET @pkey1 = GET_IDENTITY ( 'empty_shadow_t1', 1 );
INSERT t1 VALUES ( @pkey1, 0 );
COMMIT;
SET @pkey2 = GET_IDENTITY ( 'empty_shadow_t2', 1 );
INSERT t2 VALUES ( @pkey2, 0 );
COMMIT;

SELECT * FROM t1 ORDER BY pkey;
SELECT * FROM t2 ORDER BY pkey;
END;
If that code is executed twice, by two different connections, the tables look like this:
pkey        data 
----------- ----------- 
          1           0 
          2           0 
          3           0 
          4           0 
          5           0 
          6           0 


       pkey        data 
----------- ----------- 
          1           0 
          2           0 
          3           0 
          4           0 
          5           0 
          6           0 
Here's how SET @pkey1 = GET_IDENTITY ( 'empty_shadow_t1', 1 ); works:
xxx
  • It uses the DEFAULT AUTOINCREMENT specification on the column empty_shadow_t1.pkey to generated the next auto-increment value.

  • It modifies the corresponding SYSTABCOL.max_identity column value to reflect the fact that generated value has been reserved.
    SELECT SYSTAB.table_name,
           SYSTABCOL.column_name,
           SYSTABCOL.max_identity
      FROM SYSTAB INNER JOIN SYSTABCOL
              ON SYSTAB.table_id = SYSTABCOL.table_id
     WHERE SYSTAB.table_name LIKE 'empty%'
     ORDER BY SYSTAB.table_name;
    
    table_name        column_name            max_identity 
    ----------------- ----------------- ----------------- 
    empty_shadow_t1   pkey                              6 
    empty_shadow_t2   pkey                              6 
    

  • It returns the generated value as the GET_IDENTITY() result.
After that's done, @pkey1 contains the value for the INSERT, and empty_shadow_t1 is still empty.

Which is a good thing, because most DBAs don't mind it if you ask for an empty table :)

Dilbert.com 2007-11-16

Wednesday, October 16, 2013

Proving On-Demand

Question: What are the steps required to set up a proof-of-concept to implement 5 servers and 30 databases using the SQL Anywhere 16 On-Demand Edition? The databases will be created as numbered copies of a template: tenant1.db, tenant2.db, tenant3.db. It's OK to use a single computer as a host for everything for the time being.


Tip: Choosing a naming convention for databases is a big deal when you're dealing with hundreds or thousands of them. There's a lot to be said for a simple numbering system, something administrators of large MobiLink synchronization setups have discovered over the years: A store number makes a great MobiLink database identifier, better than a "store name" ...and anything's better than a GUID.

Consider this: The On-Demand software itself forces a simple 1-2-3 numbering system on you for SQL Anywhere server names, so think twice before insisting on some kind of "meaningful" or "corporate standard" naming convention for the databases.

Another tip: If you want to hide the fact that you're starting out small, don't use 1 for your first tenant database; for example, if your street address is 129 Main Street then use 129 as your first database number :)

Step 1: Create The ONDEMAND1 Environment Variable.

When writing command files to run On-Demand executables, it's easier to code the path as "%ONDEMAND1%" than "C:\Program Files\SQL Anywhere OnDemand 1.0\sa-win64-x64-16.0.0.1535-1.0.0.4613".

Here's how to set that up:

Control Panel 
   - System  
   - Advanced System Settings  
   - Environment Variables... 
   - System variables  
   - New... 
      Variable name: ONDEMAND1
      Variable value: C:\Program Files\SQL Anywhere OnDemand 1.0\sa-win64-x64-16.0.0.1535-1.0.0.4613




Step 2: Stop The Cloud If Necessary.

This article assumes you're starting from scratch, and that means if you've got the On-Demand software already running you have to shut it down. The quickest, most thorough way to do that is to use the Cloud Console itself: Overview - Stop the cloud.

Step 3: (Re)Initialize The Cloud.

The command files in this article are numbered to match the steps, and they're shown in boxes like this:
03_dbcloudinit.bat
"%ONDEMAND1%\Bin64\dbcloudinit.exe" 

PAUSE
The dbcloudinit.exe utility will prompt you for permission to re-create everything from scratch, then it will prompt you to fill in values like this:

Cloud name: MyCloud
Full name:  Breck
User ID:    admin
Password:   sql

TCP/IP: 2638
HTTP:   12345
HTTPS:  443

Encryption key:       6mFu3Cfi9ej
Secured feature key:  j6ogbIrueOgi9
Certificate password: yj487Gjr4uE

Part of the cloud initialization process is to contact the SAP Usage Server, but that part might not work. If it doesn't, and you see these error messages, try the workaround in the next step:

Proxy Settings
Unable to contact Usage Server. If there are Internet Proxy settings, enter the host
and port below:
Proxy Host
Proxy Port
OK

Error
Unable to contact the SAP Sybase SQL Anywhere, on-demand
Usage Server: https://saode.sybase.com
Verify that you have internet connectivity and that your firewall is
configured and working properly
OK


Step 3b: (Re)Initialize The Cloud, Alternative Method

The following version of the dbcloudinit command doesn't bother contacting the SAP Usage Server; at some point you'll have to fix the problem but this is a proof-of-concept, not a roll-out:
03b_dbcloudinit-no-usage-server-check.bat
"%ONDEMAND1%\Bin64\dbcloudinit.exe" -no-usage-server-check

PAUSE
Same as before, you will be prompted to fill in values like this:

Cloud name: MyCloud
Full name:  Breck
User ID:    admin
Password:   sql

TCP/IP: 2638
HTTP:   12345
HTTPS:  443

Encryption key:       6mFu3Cfi9ej
Secured feature key:  j6ogbIrueOgi9
Certificate password: yj487Gjr4uE

Step 4: Create The Additional 4 Servers.

The first On-Demand server is created as part the cloud initialization in the previous step. On-Demand servers are all named after the hosts they're on; in the case of this article the host name is ENVY so the first server is Envy#1.

Here's a command file to create 4 additional servers:
04_dbcloudcmd_CreateServer_4_servers.bat
"%ONDEMAND1%\Bin64\dbcloudcmd.exe" -cc "HOST=ENVY; UID=admin; PWD=sql"^
  run CreateServer host=Envy

"%ONDEMAND1%\Bin64\dbcloudcmd.exe" -cc "HOST=ENVY; UID=admin; PWD=sql"^
  run CreateServer host=Envy

"%ONDEMAND1%\Bin64\dbcloudcmd.exe" -cc "HOST=ENVY; UID=admin; PWD=sql"^
  run CreateServer host=Envy

"%ONDEMAND1%\Bin64\dbcloudcmd.exe" -cc "HOST=ENVY; UID=admin; PWD=sql"^
  run CreateServer host=Envy

PAUSE
All four of the above commands are identical; each one creates "one more server" on host=Envy with the server names being generated automatically Envy#2 through Envy#5. It's probably a good thing you don't get to pick the server names; with hundreds and perhaps thousands of database names to pick you don't need the extra work.

The dbcloudcmd.exe utility is a general-purpose command processor, a kind of "ISQL-for-On-Demand":
  • The -cc option specifies the connection string for the cloud itself, which is separate and different from any particular database connection string.

  • The run keyword is one of several cloud command verbs; others include describe, download, poll, queue and wait.

  • The CreateServer task is one of many cloud tasks that can be executed by the run verb. There are a veritable sackload of tasks you can run; think of them as SQL-for-On-Demand.

  • The host=Envy is one of the parameters for the CreateServer task. Each task has its own set, so expect to spend some time in the Help reading about task syntax.

Step 5: Create and initialize a template tenant database.

In some On-Demand setups each tenant database will be a hand-crafted affair, constructed and loaded by separate custom processes. In other setups each new tenant database will be initialized from a common template and will assume an independent "data personality" after it goes live.

This article assumes the latter: each new tenant database starts life being the same; the files are separate and the database names are different, but the data's identical.

Here is a skeleton script for creating a template for new tenant databases; it's a skeleton because it doesn't contain any application-specific SQL statements, it just creates an empty SQL Anywhere 16 database:
05_create_template_database.bat
"%SQLANY16%\Bin64\dbinit.exe"^
  tenant.db

"%SQLANY16%\Bin64\dbspawn.exe"^
  -f "%SQLANY16%\Bin64\dbsrv16.exe"^
  -o dbsrv16_log_tenant.txt^
  tenant.db

"%SQLANY16%\Bin64\dbstop.exe"^
  -c "HOST=Envy; DBN=tenant; UID=dba; PWD=sql"^
  -y^
  tenant

PAUSE
The dbinit utility creates the database file, the dbsrv16 command starts the database to force a transaction log to be created, and the dbstop utility does a clean stop of the database to make tenant.db and tenant.log available for copying.

Note: The %SQLANY16% copy of SQL Anywhere 16 must be used for tasks outside the context of the On-Demand software. An attempt to use the %ONDEMAND1% copy (say, in running dbsrv16 command above) will result in the error "No cloud administration database is running":



Step 6: Create 30 tenant databases and add them to the cloud.

A new tenant database must be created outside the On-Demand environment and then "added" to the cloud using the dbcloudadd.exe utility.

The following Windows command file performs those tasks; it accepts a single parameter (1, 2, 3, ...) to identify the database to be created (tenant1, tenant2, tenant3, ...):
06b_dbcloudadd_one_empty_tenant_db.bat
COPY tenant.db  tenant%1.db
COPY tenant.log tenant%1.log

"%SQLANY16%\Bin64\dblog.exe"^
  -t tenant%1.log^
  tenant%1.db 

"%ONDEMAND1%\Bin64\dbcloudadd.exe" -cc "HOST=ENVY; UID=admin; PWD=sql"^
  -c "UID=dba; PWD=sql; DBN=tenant%1"^
  tenant%1.db

ERASE /F tenant%1.db
ERASE /F tenant%1.log
Here's what a "CALL 06b_dbcloudadd_one_empty_tenant_db.bat 3" command does:
  • The COPY commands create a local copy of the tenant.db and .log files as tenant3.db and tenant3.log.

  • The dblog.exe utility modifies the tenant3.db file to refer to tenant3.log instead of tenant.log.

  • The dbcloudadd.exe utility connects to the On-Demand software using the -cc connection string,

  • then uses the -c connection string to connect to the tenant3 database

  • and specifies database file as tenant3.db.

  • The ERASE commands delete the local files tenant3.db and tenant3.log because they're no longer needed.
The Windows FOR command makes it possible to automate 30 (or 100, or 1000) calls to 06b_dbcloudadd_one_empty_tenant_db.bat with a single command:
06_dbcloudadd_30_empty_tenant_dbs.bat
REM Repeat %%a = 1 step 1 to 30 DO ...

FOR /L %%a IN (1,1,30) DO CALL 06b_dbcloudadd_one_empty_tenant_db.bat %%a 

PAUSE
When that FOR loop is finished, there are 30 tenant databases up and running in the On-Demand cloud... being able to use the FOR command in this manner is a beneficial result of the decision to number the tenant databases 1, 2, 3.

Step 7: Restart the Cloud Agent and Cloud Console.

In theory, it shouldn't be necessary to restart the On-Demand setup after a reboot, it should happen automatically. In practice (and "practice" is what a proof-of-concept is all about) manual intervention may be required. Here's how to restart the Cloud Agent and the first On-Demand server Envy#1 and then launch the Cloud Console in a browser window:
07_start Cloud Agent and Console.bat
"%ONDEMAND1%\Bin64\dbsvc.exe" -x dbcloudagent1.0.0.4613

"%ONDEMAND1%\Bin64\dbsvc.exe" -u dbcloudagent1.0.0.4613

PAUSE Launch the Cloud Console (it may not respond right away)...

START "" "https://localhost:443" 

PAUSE

Step 8: Restart the 4 additional servers.

Here's a script to restart the On-Demand servers Envy#2 through Envy#5 using the Windows FOR command to automate the process:
08_dbcloudcmd_StartServer_4_servers.bat
REM Repeat %%a = 2 step 1 to 5 DO ...

FOR /L %%a IN (2,1,5) DO "%ONDEMAND1%\Bin64\dbcloudcmd.exe"^
  -cc "HOST=ENVY; UID=admin; PWD=sql"^
  run StartServer Envy#%%a

PAUSE

Step 9: Restart the 30 tenant databases.

If the 30 tenant database don't start along with the servers, here's a FOR command to get them all going:
09_dbcloudcmd_StartDatabase_30_databases.bat
REM Repeat %%a = 1 step 1 to 30 DO ...

FOR /L %%a IN (1,1,30) DO "%ONDEMAND1%\Bin64\dbcloudcmd.exe"^
  -cc "HOST=ENVY; UID=admin; PWD=sql"^
  run StartDatabase tenant%%a 

PAUSE

Step 10: Connect to the 30 tenant databases.

When it comes time for client applications to connect to the tenant databases, the trick with On-Demand is to specify the host, database and user id but not the server name.

The next version of the Foxhound Database Monitor is one such client application; you can start 30 separate monitor sessions by providing a text file containing 30 session names each separated by a tab from the corresponding connection string:

tenant1 HOST=Envy; DBN=tenant1; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant2 HOST=Envy; DBN=tenant2; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant3 HOST=Envy; DBN=tenant3; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant4 HOST=Envy; DBN=tenant4; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant5 HOST=Envy; DBN=tenant5; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant6 HOST=Envy; DBN=tenant6; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant7 HOST=Envy; DBN=tenant7; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant8 HOST=Envy; DBN=tenant8; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant9 HOST=Envy; DBN=tenant9; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant10 HOST=Envy; DBN=tenant10; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant11 HOST=Envy; DBN=tenant11; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant12 HOST=Envy; DBN=tenant12; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant13 HOST=Envy; DBN=tenant13; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant14 HOST=Envy; DBN=tenant14; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant15 HOST=Envy; DBN=tenant15; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant16 HOST=Envy; DBN=tenant16; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant17 HOST=Envy; DBN=tenant17; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant18 HOST=Envy; DBN=tenant18; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant19 HOST=Envy; DBN=tenant19; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant20 HOST=Envy; DBN=tenant20; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant21 HOST=Envy; DBN=tenant21; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant22 HOST=Envy; DBN=tenant22; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant23 HOST=Envy; DBN=tenant23; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant24 HOST=Envy; DBN=tenant24; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant25 HOST=Envy; DBN=tenant25; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant26 HOST=Envy; DBN=tenant26; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant27 HOST=Envy; DBN=tenant27; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant28 HOST=Envy; DBN=tenant28; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant29 HOST=Envy; DBN=tenant29; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 
tenant30 HOST=Envy; DBN=tenant30; UID=dba; PWD=sql; DRIVER=SQL Anywhere 16; 



Monday, October 14, 2013

Learning On-Demand

The previous article about the On-Demand Edition of SQL Anywhere contained a link to Tutorial material that is [cough] unstable... the link is unstable, not the Tutorial material... well, more on that later.

That's not exactly news; everything in the sybase.com domain is subject to change without notice ( I should be happy, it gives me something to write about :)

Here are direct links to the actual Tutorial documents, but first, a warning...


Caution: Look before you leap... The tutorials contain links that are out of date, pointing to SQL Anywhere 12 material rather than SQL Anywhere 16; for example, "To learn more about the features of SQL Anywhere, refer to the documentation at http://dcx.sybase.com/index.html#1201/en/sqlanywhere_en12/help_top_index.htm"

Here are the links you need:
SQL Anywhere 16

SQL Anywhere On-Demand Edition

Module 1 – SAP Sybase SQL Anywhere, on-demand edition installation and setup
In this module, you will walk through the installation of the software, as well as the addition of hosts and servers to the on-demand edition environment.

Module 2 – Adding Databases in the SAP Sybase SQL Anywhere, on-demand edition Cloud
In this module, you will walk through how to add, start, and stop databases in the SAP Sybase SQL Anywhere, on-demand edition cloud.

Module 3 – Making Client Connections
In this module, you will walk through how to establish client-side connections using dbping with databases that are running in the Sap Sybase SQL Anywhere, on-demand edition Cloud.

Module 4 – Moving a Database
In this module, you will walk through how to move databases within the SAP Sybase SQL Anywhere, on-demand edition cloud. This includes moving running databases to other cloud servers on the same host and to cloud servers running on a different host.

Module 5 – Database Backup and Restore
When managing many databases, it is important to be able to clearly view the maintenance activities related to them, including backup, recovery, and validation tasks. In this module, you will walk through backing up a database and viewing the list of database backups. You will also learn about the plans for recovery and validation activities.

Module 6 – Tagging and Tasks
Now that you have created your SAP Sybase SQL Anywhere, on-demand edition cloud and added hosts, servers and databases, you need to manage those objects within the cloud environment. One way to manage cloud objects is by using tags. A tag is a non-hierarchical term or keyword that is assigned to a number of cloud objects. Tags provide an intuitive and flexible way to group cloud objects together using attributes that are common among them. These tags can then be used as targets for cloud administration activities and task deployment. For example, users can assign a geographical tag in order to schedule a task that applies only to tenant databases in a specific region, or to ensure that an object only interacts with other objects that use the same tag.

Module 7 – Tenant Database Monitoring
Once a SAP Sybase SQL Anywhere, on-demand edition Cloud is configured and is managing tenant databases, you will need a way to monitor and proactively detect problems in those tenant databases. The SQL Anywhere Monitor is a browser-based administration tool that provides you with information about the health and availability of your tenant databases.

Module 8 – Managing Users, User Privileges, and Cloud Rules
In this module, you will walk through how to create and edit cloud users for the cloud and assign certain privileges to them. You will also learn about cloud rules and how they allow enforcement of business rules and the management of resources in the cloud.

Module 9 – Customizing Cloud Settings
In this module, you will walk through how to customize settings for the SAP Sybase SQL Anywhere, on-demand edition cloud. The cloud’s description can be updated to reflect its purpose, and options can be changed including the email server, TCP/IP port ranges, and history retention period.

Module 10 – Billing
In this module, you will learn how to retrieve and read billing metrics for your SAP Sybase SQL Anywhere, on-demand edition cloud. The billing metrics contain usage information that is updated every hour. The usage information includes metrics such as consumption of processing resources and online time during a given period.

Module 11 – Tenant Mirroring
In this module, you will learn about configuring tenant read-only scale-out systems and high availability systems in the SAP Sybase SQL Anywhere, on-demand edition cloud. Read-only scale-out distributes the read-only load on a database over multiple servers to improve performance, while high availability ensures your database is still available even if one server fails for any reason.

Module 12 – Running SQL Statements in the Cloud
In this module, you will learn how to execute SQL on databases in the cloud. SQL statements can be executed on either single databases or groups of databases. Databases where SQL statements will be executed can be chosen individually or by their tags.

Module 13 – Using SQL Anywhere with the cloud
In this module, you will learn how to use SQL Anywhere and its administrative tools to work with the databases in the cloud. SQL Anywhere provides design and management tools for data management and data exchange. You will learn how to connect to your databases in the on-demand edition cloud using the administration tools, how to execute SQL using Interactive SQL, and how to compare database schemas with Sybase Central.

Module 14 – Connecting to Databases via HTTP or HTTPS Web Services
In this module, you will learn how to connect to your databases in the on-demand edition cloud via an HTTP or HTTPS web service.



Friday, October 11, 2013

Evaluating On-Demand

The On-Demand Edition of SQL Anywhere is an immensely powerful administration tool for creating, manipulating, moving and managing thousands of SQL Anywhere tenant databases installed across many hundreds servers and computers running on-site or in the cloud.

Question: How do I get started evaluating the SQL Anywhere On-Demand Edition? I've installed the software but I can't figure out what to do next.

Answer: The On-Demand setup process is designed for deployment rather than evaluation, experimentation, design, development or training. As a result, the out-of-box experience is somewhat different from other editions of SQL Anywhere:

  • The setup is immediately followed by a configuration process that asks questions you may not know how to answer if you have never worked with the product before.

  • The setup does not install any shortcuts, or documentation, or shortcuts to the documentation.

  • If the configuration process is not completely successful, nothing is left running and there is no apparent answer to the question "What do I do next?"
In other words, there's no On-Demand Developers Edition, it's really the . . .

On-Demand Deployment Edition

. . . and this article tries to answer the question "What do I do next?" after installing On-Demand for the first time.

First of all, here's the missing link to the Help:

SAP Sybase SQL Anywhere, on-demand edition 1.0 Support Package 3

And here's a link to the tutorials:

Modules 1 to 14: Tutorials on SQL Anywhere On-Demand Edition

...no, wait, here it is:

Modules 1 to 14: Tutorials on SQL Anywhere On-Demand Edition

...if that doesn't work, try Google. The Tutorials are out there!

Maybe that's all you need, all the "how-to" material you will ever need and then some.

Here's where all the executables are installed, which is handy to know when coding Windows command files to automate point-and-click tasks:

C:\Program Files\SQL Anywhere OnDemand 1.0\sa-win64-x64-16.0.0.1535-1.0.0.4613\Bin64

A copy of SQL Anywhere 16.0.0.1535 is included in that folder. That's the build which is used by On-Demand, and it's OK to have an earlier build (say, 16.0.0.1512) installed on the same computer... the two different builds won't interfere with each other.

Tip: If you like writing Windows command files that refer to the SQLANY16 environment variable installed by the regular SQL Anywhere 16 setup, you should create a similar environment variable for use in On-Demand command files:
Control Panel 
   - System  
   - Advanced System Settings  
   - Environment Variables... 
   - System variables  
   - New... 
      Variable name: ONDEMAND1
      Variable value: C:\Program Files\SQL Anywhere OnDemand 1.0\sa-win64-x64-16.0.0.1535-1.0.0.4613



If you had trouble with the initial configuration, or you just want to start over from scratch without running the setup again, here's how to (re)initialize the configuration:
"%ONDEMAND1%\Bin64\dbcloudinit.exe"

You will be presented with a series of question-and-answer browser pages that start with this . . .


and end with the Cloud Console page . . .


Along the way, you'll be asked to provide input like this . . .
Cloud name: MyCloud
Full name:  Breck
User ID:    admin
Password:   sql

TCP/IP: 2638
HTTP:   12345
HTTPS:  443

Encryption key:       6mFu3Cfi9ej
Secured feature key:  j6ogbIrueOgi9
Certificate password: yj487Gjr4uE

At this point, you're all set to play around and practice with the many features of On-Demand.

Here's where all your On-Demand databases and other files will be installed; if you create a database outside the On-Demand product and then import it, the files will be copied to this location:

C:\Users\Public\Documents\SQL Anywhere OnDemand 1.0

When something goes wrong (say, during training or experimentation, certainly not deployment :), here's where you'll go looking for answers:

C:\Users\Public\Documents\SQL Anywhere OnDemand 1.0\logs\

Some of the files in the logs folder contain readable text, like the SQL Anywhere server console logs. Other files will be in the Event Trace Data (ETD) format that needs translating to be understandable:
"%ONDEMAND1%\Bin64\dbmanageetd.exe"^
  -o dbmanageetd.txt^
  "C:\Users\Public\Documents\SQL Anywhere OnDemand 1.0\logs\agent_log_4613.etd"

[2013-10-03T17:10:34.688-04:00] dbcloudagent_main_info  message=[dbcloudagent 1.0.0.4613]
[2013-10-03T17:10:34.688-04:00] dbcloudagent_main_info  message=[Primary server addresses: 
   Envy:443,192.168.1.5:443]
[2013-10-03T17:10:35.702-04:00] dbcloudagent_main_info  message=[Cloud agent running; the  
   host ID is name='Envy']
[2013-10-03T17:10:35.702-04:00] dbcloudagent_monitor_info  message=[Monitoring  
   status of actions]
[2013-10-03T17:10:35.702-04:00] dbcloudagent_initaction_debug  message=[Initial action 1:  
   executable[dbcloudagentaction.exe] arguments[-a 1 -ii -dp "C:\Users\Public\Documents 
   \SQL Anywhere OnDemand 1.0" -swroot "C:\Program Files\SQL Anywhere OnDemand 1.0"  
   -op StartServerInit -swdir "C:\Program Files\SQL Anywhere OnDemand 1.0 
   \sa-win64-x64-16.0.0.1535-1.0.0.4613\Bin64" -servercommandlinetxt  
   "C:\Users\Public\Documents\SQL Anywhere OnDemand 1.0\server-1\servercommandline.txt"  
   -snum 1 -smajorver 16] maximum running time[-1]]
[2013-10-03T17:10:35.718-04:00] dbcloudagent_initaction_debug  message=[Initial  
   action 1 started]
[2013-10-03T17:10:36.342-04:00] dbcloudagent_poller_info  message=[Polling server]
...

If you're running the On-Demand software on a single computer (which is what new students tend to do), and you reboot that computer (which never happens In The Cloud but certainly happens on the desktop), the Cloud Console may or may not start successfully.

It turns out the Cloud Console is only the visible tip of a very large iceberg. The bulk of that iceberg consists not only of SQL Anywhere servers but of a "cloud agent" which runs as a Windows service.

If that service doesn't start automatically after a reboot (it should), here's a Windows command file to fix the problem; it stops-and-starts the cloud agent service, then fires up the Cloud Console page in your favorite browser:
"%ONDEMAND1%\Bin64\dbsvc.exe" -x dbcloudagent1.0.0.4613

"%ONDEMAND1%\Bin64\dbsvc.exe" -u dbcloudagent1.0.0.4613

PAUSE Launch the Cloud Console (it may not respond right away)...

START "" "http://localhost:12345 

PAUSE


Monday, October 7, 2013

Product Suggestion: Local Docs

For the first time in the history of SQL Anywhere, a major software release does not include a local copy of the documentation:


The SAP Sybase SQL Anywhere, On-Demand Edition is accompanied by documentation that exists only on the DCX website.

Relying entirely on the internet is a bold decision for the company that created MobiLink, a synchronization solution that allows customers keep operating during internet outages by maintaining local databases at each remote site.

A bold decision that should be revisited; yesterday's extended DCX outage meant the entire On-Demand customer base was without access to product documentation...



The argument might be made that because On-Demand software is run "in the cloud" it depends entirely on the internet being operational, and therefore it's OK to provide the docs on internet as well. However, the On-Demand software is not operated as a service by SAP, it is installed by the customer, and the customer is responsible for their own internet service levels. DCX, on the other hand, is a service operated by SAP, and as such is beyond the customer's control.

Here's a suggestion: Always ship documentation "in the box" with products that are installed by the customer as opposed to being run as a service by the vendor.


Wednesday, October 2, 2013

Latest SQL Anywhere Updates: 12.0.1.3967 for Linux and Windows

Current builds for the active platforms...

HP-UX     16.0 GA Dev Edition download       (date n/a)      Dev Edition registration
 Itanium  12.0.1.3894 (EBF 21788 SP60)       16 May 2013
          11.0.1.2958 (EBF 21793 SP96)       08 Apr 2013     End of Life 31 May 2014

IBM AIX   16.0 GA Dev Edition download       (date n/a)      Dev Edition registration
          12.0.1.3894 (EBF 21787 SP60)       16 May 2013
          11.0.1.2958 (EBF 21792 SP96)       08 Apr 2013     End of Life 31 May 2014

Linux     16.0.0.1642 (EBF 21801 SP4)        13 Sep 2013
          On Demand 1.0.4613 (SP3)           13 Sep 2013
          12.0.1.3967 (EBF 21835 SP65)   *** 30 Sep 2013 ***
          12.0.1 Chinese,                    16 Apr 2013
                 Japanese Docs (Eclipse)     16 Apr 2013
          11.0.1.3027 (EBF 21786 SP98)       13 Sep 2013     End of Life 31 May 2014

Mac OS    16.0.0.1565 (EBF 21800 SP3)        13 Sep 2013
          12.0.1.3958 (EBF 21796 SP64)       19 Sep 2013
          11.0.1.2449 Update                 29 Jun 2010     End of Life 31 May 2014

Solaris   16.0 GA Dev Edition download       (date n/a)      Dev Edition registration
 SPARC    12.0.1.3894 (EBF 21789 SP60)       16 May 2013
          11.0.1.2958 (EBF 21794 SP96)       08 Apr 2013     End of Life 31 May 2014

Solaris   16.0 GA Dev Edition download       (date n/a)      Dev Edition registration
 x64      12.0.1.3894 (EBF 21790 SP60)       16 May 2013
          11.0.1.2958 (EBF 21750 SP96)       08 Apr 2013     End of Life 31 May 2014

Windows   16.0.0.1644 (EBF 21802 SP5)        13 Sep 2013
          On Demand 1.0.4613 (SP3)           13 Sep 2013
          12.0.1.3967 (EBF 21834 SP65)   *** 30 Sep 2013 ***
          12.0.1 French,                     25 Sep 2012
                 English,                    25 Sep 2012
                 German,                     25 Sep 2012
                 Chinese,                    28 Mar 2013
                 Japanese Docs (HTML/PDF)    28 Mar 2013
          11.0.1.2960 (EBF 21751 SP97)       16 Apr 2013     End of Life 31 May 2014 

Other Stuff...

 Older Updates

 Free support! Q&A forum
   ...or, call Tech Support

 SQL Anywhere...
   ...Sybase home page 
   ...SAP home page 
   ...SAP Developer Center 

 Buy SQL Anywhere 

 Developer Edition... 
   [16.0] [12.0.1] [11.0.1]

 Download the...
   Educational Edition 
   Web Edition 

 Supported Platforms...
   SQL Anywhere 
   Linux 
   OnDemand

 ODBC Drivers for MobiLink

The asterisks "***" show which items have appeared on the Sybase website since the previous version of this page.
  • Only the latest fully-supported versions of SQL Anywhere (11.0.1, 12.0.1, 16.0 and On Demand) are shown here.

  • The "EBF 21788 SP60" numbers are the new SAP-specific codes associated with the build numbers "12.0.1.3894".

  • Just because an older version or different platform isn't "fully supported" any more doesn't mean you can't download files (or ask questions, or get help), it just means there won't be any more new Updates released.