on 2018 May 19 5:18 PM
I'm working on an IT project in which I need to access existing SQL Anywhere data via ODBC. In this case its Windows 2012 R2 environment.
There's only one server and naturally we want to use test data before messing with LIVE actual data. Rather than require duplication of the entire physical server (physically or virtual) the notion was use a different (test) DSN to access a test database that intentionally has the same definition as the live data.
The test database offered for me to work with is file copy of "mydatabase.db" file and its log, with old data contained in it, in its own folder such as "D:\\duplicate\\mydatabase.db" along with the userid and pwd for database owner.
Conceptually "all" I need to do is make a second DSN that runs an instance of SQL Anywhere against the test database file and I should be able to experiment without risk to the live db. That's where the fun begins.
I've dumped hours into this with errors and so far no success. Here's what I've tried to sort out:
I've gotten almost entirely "connection error" results when trying to configure this properly, except for one time when I managed to connect to the LIVE data quite unintentionally.
After failing repeatedly I made another attempt to resolve this: I decided on manually launching a "personal database" instance from a command prompt. I figured I could even setup the DSN to use an "already running" server if I could just launch from the command line for a while during the time I need to work with the test db.
So I renamed the physical db file, I specified a path to the renamed db file "d:\\duplicate\\mydatabase-test.db", I used -n mydatabase-test, I used -xd, and I used something like -xTCPIP(ServerPort=49158). I noticed that it was trying to start using shared memory (I thought it would not do so when I specified the TCPIP comms), and the launch of the dbeng16.exe failed because it "could not bind to 127.0.0.1:49158". I've tried several different ports in the dynamic port range and none of them could be bound.
(I've written entire full-scale applications that successfully use dynamic port numbers on a variety of Windows Server versions...)
Does someone have ideas about the dbeng16.exe port binding error that happens regardless of what port is specified?
Or --far better-- does anyone know a recipe I could follow to setup the DSN quickly and correctly for the intended purpose?
Request clarification before answering.
Quick answer: try running dbdsn -cm -g dsnname
, which will display the dbdsn command used to create that DSN. Modify that command to create a second DSN by changing the connection string in the -c
switch of that command to include DBF=full-path-to-test-database-file
. Remove any DBN connection parameter. Change the name of the DSN (-wu
switch) and execute the command to create a second DSN that can be used to connect to the test database.
This may not work (you may get a "permission denied" error) depending on whether you are running dbeng16
or dbsrv16
and the value of the -gd
switch. In that case, you can either start the test database in a second server or modify the live server to run both the live and test databases. See below.
Much longer answer:
Let me try to clarify the different names and parameters:
When starting the database server, you first give it the server name using -n, then specify a database filename and then (optionally) a database name, again using -n. For example:
dbsrv16 -n MyServerName path-to-live-database-file -n LiveDB path-to-test-database-file -n TestDB
You would then use the following connection string to connect to the live database:
UID=user;PWD=password;ENG=MyServerName;DBN=LiveDB
If you are on a different computer, you would add ";HOST=serverHostName". If you wanted to connect to the test database, you would change DBN=LiveDB
to DBN=TestDB
in your connection string.
If you prefer, you can start a second server for the test database. A single server running two databases can make more efficient use of system resources than two separate servers but either will work. In that case, you'd need a different server name both on the server command line and the connection string.
That's the naming stuff. Now onto the networking stuff.
When you start dbsrv16, the server attempts to listen for TCP connections on port 2638. You can change that port number if you want, but if you're only running one server on the machine, there's no need to. If you are trying to connect from a different machine, you need to add the HOST= parameter, as described above. Just add ;HOST=ServerHostName
to the connection string.
If you are running two servers on the same machine, they cannot both listen on the same port. If you want to specify a port to listen on, add the -x tcpip(port=n)
switch to the server command line (where n is the port number). Then you need to change the HOST
connection parameter to ;HOST=ServerHostName:n
. If you do not specify a port number on the second server, it will pick a random available port starting at 49152 and display the chosen port in the server console. You will need to check for the port number and specify that in your connection string. This is more difficult because if you shut the server down and start it again, it may pick a different port.
This is a very long-winded answer but hopefully it gives you enough information to solve your problem.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Graeme,
Thanks for your reply. I'll try to digest and apply this information as best as I'm able.
My scenario already has a database server running and responsive on port 2638, which is the production server I wish to avoid colliding with.
The folks who are responsible for the production server don't want me altering how it's currently set up, and I think this indicates that adding a test.db to the same server is pretty well off limits. This suggests to me I need to have another instance running for test at least until my effort can be switched over to the production server. (They actually use more than one for production purposes but I'm not situated to attempt changing any of that.)
I take it from your reply that there's nothing inherently built into the .db file itself that would "force" a particular database name, i.e. in a way that would override naming either by command line or DSN-supplied switches. SO if I understand correctly, working with an old snapshot of the .db file as a source of test data (& schema) would not inherently cause a collision with the production database.
It appears one of the major areas of confusion I've had is understanding how the Windows DSN configuration dialog parameters [which I presume go to the ODBC driver?] vs. command line switches placed on the "startup" line in the DSN configuration dialog [which presumably go to the dbeng or dbsrv executable?] are intended or not intended to interact with one another!
I haven't even reached the point of using a connection string (one that presumably specifies the DSN) because the "Test Connection" button on the configuration dialog has reported communication failure in every case except for the one time I inadvertently connected to the live server/db.
I'll continue to study your reply but hope these remarks would help clarify a little where I've been getting into trouble so far.
Sorry, I did not address your question about renaming the database file. The answer is yes and no. If you are making a copy of the live database file, you also need to make a copy of the live transaction log file and point the database at that file. You need to do this:
copy live.db test.db copy live.log test.log dblog -t test.log test.db
Once you've done that, you can start a new server with test.db and it will not conflict with live.db.
All connection parameters whether in a connection string or a DSN go to the ODBC driver. If no server can be found using those parameters, then we may attempt to "autostart" one, depending on which parameters were supplied. For example, if you give a HOST or LINKS parameter, we assume you're attempting to connect to a server on a remote host, so we don't autostart. We start with the START= parameter if it exists, otherwise we use a default of "dbeng16". We then add server switches based on the connection parameters:
You should use the connection parameters rather than including these switches in the START parameter.
You may want to look at this question for more information on connecting and connection parameters, though there's no information there on autostarting.
So your requirement is that the test database
Then I would suggest to just copy the production database to the test machine (i.e. without renaming the database file and transaction log file) and configure a Windows SQL Anywhere service to run there. The only necessary differences between both databases are
So you could use, say, connections strings like
HOST=ProdServerMachine;ENG=ProdEngine;DBN=YourDatabase;UID=...
to connect to the production database and likely
HOST=TestServerMachine;ENG=TestEngine;DBN=YourDatabase;UID=...
to connect to the test database. (I'm assuming each database server is the only one on the according machine so they use the default port 2638.) Of course, you could use the IP address of the machines instead of their host name.
I suppose you meant to write
dblog -t test.log test.db
The world is a big place, and it contains many strange things, like fake host names in the client computer's C:\\Windows\\System32\\drivers\\etc\\hosts file.
In other words, IP addresses are the real thing.
...on the OTHER hand, you can change the hosts file to redirect production host names to a development IP address, which I sometimes do when testing client deliverables 🙂
(like HA setups mimicing multiple computers on one laptop)
You wrote in your first comment:
The folks who are responsible for the production server don't want me altering how it's currently set up, and I think this indicates that adding a test.db to the same server is pretty well off limits.
And now:
Actually the test database must run on the same host as production.
Hm, now I don't really understand. If you are not allowed to add a test database to the running database server on the host but need to run it on the host itself, then apparently you need to run a second database server instance on the same host. I don't understand why that is "less dangerous" from "the folks's" view because a second server instance might also compete for the host's resources...
If you need to run a second server instance, then regard the second last paragraph of Graeme's answer, i.e. you need to specify a particular port then both when starting the database server and when connecting from clients. (Aside: It isn't the easiest thing to configure but I think it's far from "very complicated" - and by chance no unusual setup at all...)
User | Count |
---|---|
64 | |
8 | |
7 | |
7 | |
6 | |
5 | |
5 | |
4 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.