Connecting Jmeter to an Oracle database with two hosts and service name - database

I am trying to connect Jmeter to a geo redundant database with two hosts and I am struggling with finding the right Database Url format.
This is how my connection string looks like:
jdbc:oracle:thin:#(DESCRIPTION=(ENABLE=BROKEN)(FAILOVER=on)(CONNECT_TIMEOUT=5sec)(TRANSPORT_CONNECT_TIMEOUT=3sec)(RETRY_COUNT=3)(LOAD_BALANCE=on)(ADDRESS_LIST=(LOAD_BALANCE=on)(ADDRESS=(PROTOCOL=TCP)(HOST=HostName)(PORT=port)))(ADDRESS_LIST=(LOAD_BALANCE=on)(ADDRESS=(PROTOCOL=TCP)(HOST=HostName2)(PORT=port)))(CONNECT_DATA=(SERVICE_NAME=ServiceName)))
Database Connection Configuration is as following:
JDBC Driver Class: oracle.jdbc.OracleDriver Username: username
Password: password
For the Database URL I tried different formats and I keep getting the error:
Cannot load JDBC driver class 'oracle.jdbc.OracleDriver'
Note that the ojdbc.jar file is in the /lib folder as per the Jmeter documentation. Also, the ports are the same for both hosts.
Any suggestion is welcome. :)

I don't think you will be able to establish the connection to Oracle RAC using JMeter's JDBC Connection Configuration as it doesn't allow full flexibility therefore you will not be able to properly instantiate the PoolDataSourceFactory
So I would recommend switching to JSR223 Test Elements and Groovy language where you will have the full freedom when it comes to setting up the connection, executing queries, accessing results, etc. The relevant code would be something like:
def prop = new Properties()
prop.put('oracle.jdbc.thinForceDNSLoadBalancing','true')
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource()
pds.setConnectionProperties(prop)
pds.setConnectionFactoryClassName('oracle.jdbc.pool.OracleDataSource'); pds.setUser('johndoe')
pds.setPassword('secret')
String dbURL =
'jdbc:oracle:thin:#(DESCRIPTION=(ENABLE=BROKEN)(FAILOVER=on)(CONNECT_TIMEOUT=5sec)' +
'(TRANSPORT_CONNECT_TIMEOUT=3sec)(RETRY_COUNT=3)(LOAD_BALANCE=on)(ADDRESS_LIST=(LOAD_BALANCE=on)' +
'(ADDRESS=(PROTOCOL=TCP)(HOST=HostName)(PORT=port)))(ADDRESS_LIST=(LOAD_BALANCE=on)' +
'(ADDRESS=(PROTOCOL=TCP)(HOST=HostName2)(PORT=port)))(CONNECT_DATA=(SERVICE_NAME=ServiceName)))'
pds.setURL(dbURL)
More information: Configuring Fast Connection Failover for JDBC Clients

It appears to be working with a connection string containing only host 1.
The Database URL is in the form:
jdbc:oracle:thin:#<hostname>:<port>/<serviceName>
Additionally, I got the error because the .jar file's path was not added to the classpath (click on Test Plan, in the bottom select browse next to Add directory or jar to classpath and select your odbc jar).
Another thing that was wrong was the Validation query, it should be "select 1 from dual" and also the query should not contain any semicolon at the end.
I hope this help people with the same issue.

Related

Debezium SQL Server Connector - "Couldn't obtain database name"

I'm trying to set up a Debezium SQL Server Connector against a SQL Server instance that is controlled by DBAs at my workplace. I've been able to start up Zookeeper and Kafka Server without issue, and Kafka Connect itself works with sample Connectors, but when attempting to start a Debezium SQL Server Connector instance I've been getting the error "Couldn't obtain database name".
[2022-07-12 16:36:04,269] ERROR Stopping after connector error (org.apache.kafka.connect.cli.ConnectStandalone:117)
java.util.concurrent.ExecutionException: org.apache.kafka.connect.runtime.rest.errors.BadRequestException: Connector configuration is invalid and contains the following 1 error(s):
Unable to connect. Check this and other connection properties. Error: Couldn't obtain database name
Here is my debezium config:
name=Dbz-SqlServer-connector
connector.class=io.debezium.connector.sqlserver.SqlServerConnector
database.hostname=MyDbHost
database.port=1433
database.user=MyUsername
database.password=MyPassword
database.dbname=MyDatabase
database.server.name=MyDbHost
table.include.list=dbo.CdcTest
database.history.kafka.bootstrap.servers=localhost:9092
database.history.kafka.topic=dbhistory.CdcTest
I've tried this in a .properties file passed to a standalone Connect instance, and as a JSON POST to a distributed Connect instance. I have tried all of the same steps on both my local Windows machine as well as on a linux VM, with the same results.
Confluent and Docker are not options for me in this situation.
for SQL Server login credentials, I am using a local account on the SQL Server instance that does have access to the database in question. I found the source code for debezium's connectors on their github and was able to find that specific error message within the code:
private static final String GET_DATABASE_NAME = "SELECT name FROM sys.databases WHERE name = ?";
...
public String retrieveRealDatabaseName(String databaseName) {
try {
return prepareQueryAndMap(GET_DATABASE_NAME,
ps -> ps.setString(1, databaseName),
singleResultMapper(rs -> rs.getString(1), "Could not retrieve exactly one database name"));
}
catch (SQLException e) {
throw new RuntimeException("Couldn't obtain database name", e);
}
}
I'm not completely familiar with Java but it appears that basically something is going wrong when the connector is trying to run "SELECT name FROM sys.databases WHERE name = 'MyDatabase'". When I run this against the database myself, logged in with the same account I'm using, it seems to work just fine, so I'm really not sure where to go from here. It is fair to say that since I'm not in full control of the SQL Server environment that I'm using, there may be some permissions issues that I'm not aware of, but from what I'm able to test it seems like it should be working.
I would greatly appreciate any help at all, whether just suggestions on settings/configs to check or a full-blown solution.
Thank you!
Update: I've built a simple console app to run that sys.databases query against MyDbHost, master database, as the relevant account, and it's working just fine so I feel like that confirms that my connection info is correct and account permissions are also correct. Seems like this is an issue within the Debezium connector.
It turned out that my problem was a mistake in the connector's config setting. I misunderstood which specific pieces of data to put into database.hostname and database.server.name, and one I corrected those fields the connector works.

Problem in JDBC Connection Configuration/JDBC Request - JMETER

I'm a problem in JDBC Connection Configuration.
When i execute my test (only JDBC Request - insert), doesn't appear any results in report (View Results Tree).
The connection is SQL Server.
See below the configuration:
database URL: jdbc:sqlserver://${myURL}
JDBC driver Class: com.microsoft.sqlserver.jdbc.SQLServerDriver
Username: ${user}
Password: ${password}
Could someone help me?
Thanks!!!
Make sure to add Microsoft JDBC Driver for SQL Server to JMeter Classpath and restart JMeter to pick up the .jar
Check jmeter.log file for any suspicious entries
Be informed that JDBC Connection Configuration is a Configuration Element hence it's being executed before anything else so your variables like ${myURL}, ${user} and ${password} might not have their respective values yet
Check that your query returns results in mssql-cli
Set the validation query to select 1 if it's different:
You can check out The Real Secret to Building a Database Test Plan With JMeter article for more comprehensive steps if needed.

Microsoft SQL JDBC Spring boot configuration does not work when database name is not in the url

I have a spring boot JDBC Cofiguration A as below which works well,
Configuration A
spring.datasource.sqlserver.url=jdbc:sqlserver://localhost:1433;database=my-testdb
spring.datasource.sqlserver.user=user_101#server-product1
spring.datasource.sqlserver.password=password_101
spring.datasource.sqlserver.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
Configuration B below does not. Note that the url string does not have the database name in it. The database name is specified in a separate line, as one would expect to configure.
spring.datasource.sqlserver.url=jdbc:sqlserver://localhost:1433
spring.datasource.sqlserver.user=user_101#server-product1
spring.datasource.sqlserver.password=password_101
spring.datasource.sqlserver.database=my-testdb
spring.datasource.sqlserver.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
Cannot figure out why the database name cannot be specified in a separate line and has to be in the URL. Can anyone mention why this does not work?
Other configuration : Spring Boot, sqljdbc41.jar
Well that's how the Microsoft's SQL Server / Azure JDBC driver works, database name is a mandatory part of the URL, and not given in a "database" attribute.
Technically, it may be related to the fact that databases in SQL Server behave rather autonomously, they each have their own set of catalog views, you cannot switch between databases freely etc.

Response message: java.sql.SQLException: No pool found named: in jMeter

I am trying to do the Load testing on a new Database XpressMP. So I started using jMeter for that. I configured jMeter to make a Select call to our database. Below is configuration-
And below is the Snapshot for XMP Select DB
And if I start my test in the jMeter, I always get this exception-
Response message: java.sql.SQLException: No pool found named: 'ucirrus', ensure Variable Name matches Variable Name of JDBC Connection Configuration
What does this exception mean?
I am pretty much sure, this is the problem with my JDBC Request configuration in my previous image. As I am doing this for the first time.
Can anyone tell me how to fix this problem?
You problem is that you don't use the right variable name.
In JDBC Connection Configuration (within Variable Name bound to pool) set:
Variable Name : ucirrus

h2 in-memory tables, remote connection

I am having problems with creating an in memory table, using H2 database, and accessing it outside of the JVM it is created and running in.
The documentation structures the url as jdbc:h2:tcp://<host>/mem:<databasename>
I've tried many combinations, but simply cannot get the remote connection to work. Is this feature working, can anyone give me the details of how they used this.
None of the solutions mentioned so far worked for me. Remote part just couldn't connect.
According to H2's official documentation:
To access an in-memory database from another process or from another computer, you need to start a TCP server in the same process as the in-memory database was created. The other processes then need to access the database over TCP/IP or TLS, using a database URL such as: jdbc:h2:tcp://localhost/mem:db1.
I marked the crucial part of the text in bold.
And I found a working solution at this guy's blog:
The first process is going to create the DB, with the following URL:
jdbc:h2:mem:db1
and it’s going to need to start a tcp Server:
org.h2.tools.Server server = org.h2.tools.Server.createTcpServer().start();
The other processes can then access your DB by using the following URL:
"jdbc:h2:tcp://localhost/mem:db1"
And that is it! Worked like a charm!
You might look at In-Memory Databases. For a network connection, you need a host and database name. It looks like you want one of these:
jdbc:h2:tcp://localhost/mem:db1
jdbc:h2:tcp://127.0.0.1/mem:db1
Complete examples may be found here, here and here; related examples are examined here.
Having just faced this problem I found I needed to append DB_CLOSE_DELAY=-1 to the JDBC URL for the tcp connection. So my URLs were:
In Memory : jdbc:h2:mem:dbname
TCP Connection : jdbc:h2:tcp://localhost:9092/dbname;DB_CLOSE_DELAY=-1
From the h2 docs:
By default, closing the last connection to a database closes the
database. For an in-memory database, this means the content is lost.
To keep the database open, add ;DB_CLOSE_DELAY=-1 to the database
URL.
Not including DB_CLOSE_DELAY=-1 means that I cannot connect to the correct database via TCP. The connection is made, but it uses a different version to the one created in-memory (validated by using the IFEXISTS=true parameter)
In SpringBoot: https://www.baeldung.com/spring-boot-access-h2-database-multiple-apps
#Bean(initMethod = "start", destroyMethod = "stop")
public Server inMemoryH2DatabaseaServer() throws SQLException {
return Server.createTcpServer(
"-tcp", "-tcpAllowOthers", "-tcpPort", "9090");
}

Resources