Amazon RDS switch server between Reader instance and Writer instance - mysql

I am using Amazon Aurora and I have 2 database server by default:
The Reader instance and the Writer instance.
My application is connecting to the primary connection endpoint
sample.cluster-sample.us-west-2.rds.amazonaws.com
However, my application can't write data into the database suddenly and I found the replica (sample-instance-r1) has become Writer instance.
My application is programmed using Node.js with mysql plugin and using connection pool. How can I avoid amazon RDS switch the Writer instance and thus not able to write data?

The cluster endpoint address does not change due to failover:
To use a connection string that stays the same even when a failover promotes a new primary instance, you connect to the cluster endpoint. The cluster endpoint always represents the current primary instance in the cluster.
So what you are describing does not normally happen when you are using cluster endpoint (not counting the time required for the failover to compete). Thus please make sure that you application is actually using that endpoint as Aurora has multiple endpoints.

Related

MYSQL InnoDB Cluster Connect String parameters

I have setup MySQL InnoDB Cluster latest release (8.0.27) with three nodes with single primary. And I have a VB script and connection string for it.
Current connection string is like :
jdbc:mysql://node1,node2,node3;db=test?multi_host=true
Assume my primary node1 goes down, R/W access will be passed onto either node2 or node3 becoming primary. During this my connection string won't work as it tries to connect to first node and fails.
Is there any other parameter which can be passed in connect string to handle such issues?
How does connect string gets to know which node is primary and connect to it.
Thanks.
An InnoDB Cluster usually runs in a single-primary mode, with one primary instance (read-write) and multiple secondary instances (read-only).
In order for client applications to handle failover, they need to be aware of the InnoDB cluster topology. They also need to know which instance is the PRIMARY. While it is possible for applications to implement that logic, MySQL Router can provide this functionality for you.
shell> mysqlrouter --bootstrap root#localhost:3310
MySQL Router connects to the InnoDB cluster, fetches its metadata and configures itself for use. The generated configuration creates 2 TCP ports: one for read-write sessions (which redirect connections to the PRIMARY) and one for read-only sessions (which redirect connections to one of the SECONDARY instances).
Once bootstrapped and configured, start MySQL Router (or set up a service for it to start automatically when the system boots):
shell> mysqlrouter &
You can now connect a MySQL client, such as MySQL Shell to one of the incoming MySQL Router ports and see how the client gets transparently connected to one of the InnoDB cluster instances.
shell> mysqlsh --uri root#localhost:6442
However, when primary node fails, you can just read data and write cannot work. If you want write to work, see High Availability and Multi-Primary cluster for MySql.
See this for more detail.

AWS RDS Aurora MySQL Cluster, Reader Replica shows no connections

I added a reader replica to my RDS Aurora MySQL cluster. The instance is running with minor cpu usage but it does not show connections on the monitoring page. I have enabled detailed monitoring. Access groups are the same as the writer instance.
How to I ensure that traffic is going to my reader instance?
AWS RDS Aurora does not support splitting of read/write transactions,
In order to forward read only queries to read replica endpoint and read/write queries to your master endpoint you need to add function or a proxy to your application to inspect the query then forward it to read replica or to the master, in other word the application logic should manage this process.

MariaDB configuration in Spring Boot for AWS Aurora - write query routing to reader instance

I have an application running MariaDB using Aurora RDS MySQL as datasource.
In my application.properties, I have:
spring.datasource.url=jdbc:mariadb:aurora://****.cluster***.rds.amazonaws.com:3306,****.cluster-ro***.rds.amazonaws.com:3306/db
Intermittently, I see this error:
Caused by: java.sql.SQLException: (conn=150057) The MySQL server is running with the --read-only option so it cannot execute this statement
I have read answers to other questions on SO and they talk about this happens due to DNS caching used by AWS among other reasons.
I also talked to AWS support team, and they advised to only use write endpoints if the application does both read/write operations. However, the reader endpoint is responsible for load-balancing, so that functionality will be lost and all the queries will hit the writer instance.
I also read this article in MariaDB docs: Aurora configuration in MariaDB
[...] recommended url string has to use only cluster endpoint.
Driver will automatically discover master and slaves of this cluster from current cluster end-point during connection time. This permits adding new replicas to the cluster instance which will be discovered without changing driver configuration.
Do I need to provide only the writer cluster endpoint and MariaDB will take care of load balancing between writer and reader endpoints? Or do I need to provide both with additional configuration?

Should I use MySQL Database Pool or a Single Persistant Connection in Tornado

If I am using async mysql library like Tornado-MySQL(by PyMySQL) or TorMySQL or Asynctorndb which are async libraries to do MySQL database calls so to not block the IOLoop.
What I want to know is in what way should I use them in my given scenario?
Scenario : Suppose I am running my Tornado Web Application behind Nginx as Load Balancer. The whole setup is in AWS EC2 instance. Now Nginx, Tornado, MySQL all running in the same host. The Tornado Instances are run with Supervisord as the process management program.
If the no. of VCPUs of my EC2 instance are x, and no. of Nginx worker processes are y and no. of Tornado Instances are z, then given this condition, how should I use my async MySQL library?
Should I create a single persistant connection in my Application initialization which will be passed to all the handlers? Or should I use a connection pool?
Considering the fact that what will be the effect of each method with the no. of Tornado Instances running.
What are the advantages and disadvantages for each of the method?
The "single persistent connection" strategy is for using synchronous database drivers with Tornado (in which case the IOLoop guarantees that only one request can use the connection at a time). With an asynchronous driver, multiple requests can be using the database at a time, which means you must use a connection pool.

persistently replicating RDS MySQL database to external slave

AWS now allows you to replicate data from an RDS instance to an external MySQL database.
However, according to the docs:
Replication to an instance of MySQL running external to Amazon RDS is only supported during the time it takes to export a database from a MySQL DB instance. The replication should be terminated when the data has been exported and applications can start accessing the external instance.
Is there a reason for this? Can I choose to ignore this if I want the replication to be persistent and permanent? Or does AWS enforce this somehow? If so, are there any work-arounds?
It doesn't look like Amazon explicitly states why they don't support ongoing replication other than the statement you quoted. In my experience, if AWS doesn't explicitly document a reason for why they do something then you're not likely to find out unless they decide to document it at a later time.
My guess would be that it has to do with the dynamic nature of Amazon instances and how they operate within RDS. RDS instances can have their IP address change suddenly without warning. We've encountered that on more than one occasion with the RDS instances that we run. According to the RDS Best Practices guide :
If your client application is caching the DNS data of your DB instances, set a TTL of less than 30 seconds. Because the underlying IP address of a DB instance can change after a failover, caching the DNS data for an extended time can lead to connection failures if your application tries to connect to an IP address that no longer is in service.
Given that RDS instances can and do change their IP address from time to time my guess is that they simply want to avoid the possibility of having to support people who set up external replication only to have it suddenly break if/when an RDS instance gets assigned a new IP address. Unless you set the replication user and any firewalls protecting your external mysql server to be pretty wide open then replication could suddenly stop if the RDS master reboots for any reason (maintenance, hardware failure, etc). From a security point of view, opening up your replication user and firewall port like that are not a good idea.