I've started to check mysql connector j's replication paradigm and see that we can seperate read and write operations on master and slave databases.
I've checked below page and get some clues on the operation but still need to know how does mysql-jdbc understands which server is master and which servers are slaves ? ( might be a silly one, sorry for this )
http://www.dragishak.com/?p=307
The ReplicationDriver or NonRegisteringReplicationDriver decides the first url as master and the rest considered as slaves
The point you should of take into consideration is : If you are using ReplicationDriver or NonRegisteringReplicationDriver you need to give at least two hosts contains the same db instance. Otherwise you will get an SQLException telling : "Must specify at least one slave host to connect to for master/slave replication load-balancing functionality".
One more point : You don't actually need to create an instance of NonRegisteringReplicationDriver. Because ReplicationDriver is also using it. You can check it by let your application throw and Exception. What you will see is; the DB connection was tried by NonRegisteringReplicationDriver.connect(..) method.
Edit(!) : You actually don't need to create non of spesific driver for your system. What you need to know is what are you doing and the correct connection url. Because the Driver class itself checks the url against replication pattern and loadbalance pattern. Then it triggers the required driver instance.
Related
Right now I am connecting to a cluster endpoint that I have set up for an Aurora DB-MySQL compatible cluster, and after I do a "failover" from the AWS console, my web application is unable to properly connect to the DB that should be writable.
My setup is like this:
Java Web App (tomcat8) with HikariCP as the connection pool, with ConnecterJ as the driver for MySQL. I am evaluating Aurora-MySQL to see if it will satisfy some of the needs the application has. The web app sits in an EC2 instance that is in the same VPC and SG as the Aurora-MySQL cluster. I am connecting through the cluster endpoint to get to the database.
After a failover, I would expect HikariCP to break connections (it does), and then attempt to reconnect (it does), however, the application must be connecting to the wrong server, because anytime a write is hit to the database, a SQL Exception is thrown that says:
The MySQL server is running with the --read-only option so it cannot execute this statement
What is the solution here? Should I rework my code to flush DNS after all connections go down, or after I start receiving this error, and then try to re-initiate connections after that? That doesn't seem right...
I don't know why I keep asking questions if I just answer them (I should really be more patient), but here's an answer in case anyone stumbles upon this in a Google search:
RDS uses DNS changes when working with the cluster endpoint to make it looks "seamless". Since the IP behind the hostname can change, if there is any sort of caching going on, then you can see pretty quickly how a change won't be reflected. Here's a page from AWS' docs that go into it a bit more: https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-jvm-ttl.html
To resolve my issue, I went into the jvm's security file and then changed it to be 0 just to verify if what was happening was correct. Seems correct. Now I just need to figure out how to do it properly...
I want my Drupal8 installation to be more reliable in case of database failure, so I want to enable Master / Slave replication in MySQL, and make it work with Drupal 8.
I setted up two MySQL servers (one master, one slave), and replication is working.
Now, I want to setup Drupal to balance SELECT query to the slave, and INSERT/UPDATE/DELETE queries to the master. It will balance the load between the two servers, and I will have a (litle) HA concept with it.
To test this architecture, I installed a brand new Drupal 8 instance, no custom module at all. Only pure vanilla Drupal 8 if possible.
I change the settings.php file as follow :
$databases['default']['default'] = array (
'database'=>'drupaldb',
'username'=>'masteruser',
'host'=>'database-master.com'
...
);
$databases['default']['slave'] = array (
'database'=>'drupaldb',
'username'=>'slaveuser',
'host'=>'database-slave.com'
...
);
"slaveuser" is a MySQL user with only READ access ; "masteruser" have RW access on database.
With this settings, the application is working fine, but when I look at the Slave metrics, there is no connection. Even when I'm reloading page of the front-end.
If I switch off the master, or if I change the master settings (bad password, wrong database) in config php file, I expected the application, for the front-end pages, to use the Slave settings. But front pages are in error : "The website encountered an unexpected error. Please try again later". Error log indicate a SQL connection failure.
What I see here, is that there is no way to balance queries onto master (for writes) and slave (for reads).
I expected Drupal8 to manage this without any extra plugin.
Do I have to use the mysql_nd_ms PHP extension to do M/S balancing ?
The syntax for the replica database configuration can be found in settings.php
https://api.drupal.org/api/drupal/sites%21default%21default.settings.php/8.7.x
The syntax for the default db replica is:
// $info_array is the db connection details
$databases['default']['replica'][] = $info_array;
Note: D8 uses replica not slave for the terminology.
Note: so far as I can tell, adding 'replica' servers does nothing unless you are using the db_* functional calls (which are deprecated), or if you manually instantiate the database.replica connection in any of your custom queries
e.g.
/** #var \Drupal\Core\Database\Connection $database_replica */
$database_replica = \Drupal::service('database.replica');
$query = $database_replica->select('node', 'n');....
$database_replica = \Drupal::service('database.replica');
or
$database_replica = Database::getConnection('replica', 'default');
I am getting this error when executing a GRANT statement on my Aurora DB instance in AWS:
The MySQL server is running with the --read-only option so it cannot execute this statement
My user is not read-only though, so why is this happening?
It turned out to be a silly mistake, but posting it anyway in case anyone else has the problem:
I was accessing the replica instance by mistake - I had copied the endpoint for the replica, and it is read-only apparently. So if you have this problem, verify that you are connecting to the Primary Instance or best of all the DB Cluster endpoint.
Edit: According to #Justin's answer we definitely should use DB Cluster:
You need to connect to the cluster, rather than an instance. This is because instances seem to take a turn to be the readers and writers.
You need to connect to the cluster, rather than an instance. This is because instances seem to take a turn to be the readers and writers.
In my case, I was receiving this error after performing a Blue/Green failover in a Test environment. I was trying to access the Blue database, in order to confirm the process for reverting back to Blue database should that be required later.
Accessing Blue via the cluster address yielded this error, as did attempting to use the direct links to the Blue "reader" and "writer" instances. In the end, I performed a failover of the Blue "reader" and "writer" instances, after which the cluster address was in a working state again.
tl;dr
Try a failover of the "writer".
I have RestComm Connect configured to use an external MySQL DB (according to 'How to get started with Restcomm-Connect and Mysql'). The setup works fine (able to make Alice<->Bob calls via Olympus).
Now I would like to try out a new RestComm Connect release and configure it to use the same MySQL DB instance - i.e. to use the same 'restcomm' database (I want to share existing clients' accounts between the two RestComm instances).
So the target setup would be e.g.:
Restcomm-JBoss-AS7-8.2.0.1221 ---
\
--> MySQL DB ['restcomm' database]
/
Restcomm-JBoss-AS7-8.2.0.1304 ---
In this case both RestComm instances share the same 'restcomm' database.
Is the above setup feasible, or are there instance specific data stored in the DB which can't be shared (i.e. besides tables such as restcomm_accounts or restcomm_clients)?
Of course only one of the RestComm instances would be running at given time.
Any tips, ideas or suggestions would be appreciated.
Thanks,
Dominik
Yes it's designed to share the same DB, even with both or more instances active.
I've got a trio of Windows servers (data1, data2 and datawitness) that aren't part of any domain and don't use AD. I'm trying to set up mirroring based on the instructions at http://alan328.com/SQL2005_Database_Mirroring_Tutorial.aspx. I've had success right up until the final set of instructions where I tell data1 to use datawitness as the witness server. That step fails with the following message:
alter database MyDatabase set witness = 'TCP://datawitness.somedomain.com:7024'
The ALTER DATABASE command could not be sent to the remote server instance 'TCP://datawitness.somedomain.com:7024'. The database mirroring configuration was not changed. Verify that the server is connected, and try again.
I've tested both port 7024 as well as 1433 using telnet and both servers can indeed connect with each other. I'm also able to add a connection to the witness server from SQL Server Manager on the primary server. I've used the Configuration Manager on both servers to enabled Named Pipes and verify that IP traffic is enabled and using port 1433 by default.
What else could it be? Do I need any additional ports open for this to work? (The firewall rules are very restrictive, but I know traffic on the previously mentioned ports is explicitly allowed)
Caveats that are worth mentioning here:
Each server is in a different network segment
The servers don't use AD and aren't part of a domain
There is no DNS server configured for these servers, so I'm using the HOSTS file to map domain names to IP addresses (verified using telnet, ping, etc).
The firewall rules are very restrictive and I don't have direct access to tweak them, though I can call in a change if needed
Data1 and Data2 are using SQL Server 2008, Datawitness is using SQL Express 2005. All of them use the default instance (i.e. none of them are named instances)
After combing through blogs and KB articles and forum posts and reinstalling and reconfiguring and rebooting and profiling, etc, etc, etc, I finally found the key to the puzzle - an entry in the event log on the witness server reported this error:
Database mirroring connection error 2 'DNS lookup failed with error: '11001(No such host is known.)'.' for 'TCP://ABC-WEB01:7024'.
I had used a hosts file to map mock domain names for all three servers in the form of datax.mydomain.com. However, it is now apparent that the witness was trying to comunicate back using the name of the primary server, which I did not have a hosts entry for. Simply adding another entry for ABC-WEB01 pointing to the primary web server did the trick. No errors and the mirroring is finally complete.
Hope this saves someone else a billion hours.
I'd like to add one more sub answer to this specific question, as my comment on Chris' answer shows, my mirror was showing up as disconnected (to the witness) Apperently you need to reboot (or in my case i just restarded the service) the witness server.
As soon as i did this the mirror showed the Witness connection as Connected!
See: http://www.bigresource.com/Tracker/Track-ms_sql-cBsxsUSH/