MySQL - How to grant access to only one of n slaves? - mysql

I have one master and two slaves.
Is it possible to restrict a particular read-only user to query only against the second slave (disallowing him from running any queries on the master and the first slave)?
I see that one can do the following to make un-replicated changes to the master, but what I think I need is to make changes to one slave and not the other.
SET sql_log_bin = {OFF|ON}
And the GRANT syntax allows one to limit what host users come from, but -- as far as I understand -- not which DB server(s) the person can use.
I didn't find much in a web search -- perhaps that's a hint that there's a better way to solve this problem. Basically I'm asking if this can be enforced by the database since the restriction I want applies to just this one user.

For context: a slave is basically just a server that copies every action that happened on the master. Depending on your configuration, the slaves will either just run the same queries that have been executed on the master, or apply a list of changes to individual rows to the slave.
To add a user just for a specific slave, you can do this directly on the slave. Anything you do here will only affect this slave. If your user currently exists on the master (and slaves), you would first have to drop him/remove his permissions, wait until this change has been replicated to all the slaves (which might also depend on your configuration), then add/modify this user directly on the slave.
You may need to temporarily disable a read_only or super_read_only setting (on the slave), which exists to prevent accidently executing something on the slave - but that is what you want to do.
Since your slave now deviates (slightly) from the master, if you would now run a query that alters that user on your master (e.g. drop it again), it might have a different effect on the master and the slave. This will depend on your configuration, but keep it in mind.

Related

How to re-replicate ignored tables

I'm currently thinking about the following problem:
A customer has set up a simple master/slave replication between two mariaDB systems. For unknown reasons they have set the flag "Replicate_Wild_Ignore_Table" to skip "logdb.%". Obviously, they decided to skip the skipping of that database and want the logdb to be included in the replication again.
I'm curious now, is it possible to somehow remove that flag and have the database in question be replicated as the rest or is there no way to circumvent the "stop slave, dump master, import dump, recreate replication based on current logpos, start slave" procedure?
You can't assume that the master still has all relevant binlogs that once contained updates to the logdb.% tables. That is, even if you could re-apply those updates, do you have enough history to account for all changes to the tables?
Another risk is if you use statement-based replication, if there were ever statements that referenced both a table in logdb.% and a table in another database, the replication filter has skipped that statement. So for example:
INSERT INTO mydb.mytable SELECT * FROM logdb.othertable;
Therefore even the tables that are not in logdb.% might be compromised. The point is you don't know for sure.
The bottom line is that you should definitely reinitialize the replica now by taking a current backup of the master, and avoid using replication filters in the future.
If you use InnoDB tables, you might consider using Percona XtraBackup to make the process easier. See https://www.percona.com/doc/percona-xtrabackup/2.3/howtos/setting_up_replication.html

AES Encryption of Data during MySQL Master - Slave Replication

I need to encrypt some data on MySQL slave and using AES_Encrypt for the same. Is it possible to encrypt it while replicating it from the Master database?
Using MySQL 5.6
In MySQL replication, when using binlog_format=STATEMENT, triggers fire on the master and again on the slave, but there is no specific requirement that the triggers be defined identically on the master and slave, or that triggers be provisioned on both.
I say there is no specific requirement, because it is not enforced. If you want the data to be identical on master and slave -- as is almost always the case in a replicated environment -- then yes, the triggers have to be defined identically on both servers... but it is possible to customise the slave triggers -- and one way of doing it would be to define BEFORE INSERT and BEFORE UPDATE triggers on the slave that encrypted the columns before inserts and updates.
This does require STATEMENT replication, which I don't use because it is more delicate and some statements cannot be deterministically replicated in STATEMENT mode.
This would require extra care to ensure that master and slave are always consistent, and would require custom tools since standard table comparison tools would consider master and slave tables to be different.
With binlog_format=ROW, any triggers defined on the slave are ignored for replicated events, because they would be redundant -- the changes done by the triggers on the master will already be replicated to the slave as row events, and executing the triggers on the slave would not have the correct result. Row-based replication uses raw row images, so is always deterministic, unlike statement based replication.
The MariaDB team recognizes that there may be cases where identical data sets are not the objective, such as where you might want to build denormalized query tables on the slave, so in MariaDB 10.1, they introduced a feature to allow slaves to fire triggers for row-based events. This might also be a viable solution, if your master is not using statement-based replication. It does not appear to require the master to run MariaDB, only the slave.
https://mariadb.com/kb/en/mariadb/running-triggers-on-the-slave-for-row-based-events/
It is also possible to create accounts that cannot access all columns, since the MySQL permissions model allows grants to be made at the server, database, table, and column level. Without permission to access a column, you won't see it, in spite of it being there.
Arguably, though, if the data is sensitive, the most correct solution would be to encrypt it on the master.

MySql phpMyAdmin: Replicating/Synchronizng two Database automatically

I have two same database on two different server, and I want to synchronize both database.
For example, If I do any process like Insert, Update, Delete, Alter, Drop, etc it also reflect on other database automatically.
I had tried it on my local server, but every time I have to do it manually.
Is there any way to do it automatically, suppose I Insert a record and it automatically inserted into other database.
The "synchronisation" feature you are looking for is called Replication.
A replication can be set up between a master and a slave machine.
It does not rely on a constant connection, but stores all changes on the master and replays all those changes on the slave once a connection is established.
Tuturial for you
What you're talking about is called 'Replication'.
If you are going to be making changes to both databases and expect it to show up in the other, you need a Master/Master pair.
Have a read about it here: https://dba.stackexchange.com/questions/9424/best-way-to-setup-master-to-multi-master-replication

filter mysql replication (ignore-db)

mysql ignore-db works according to server my.cnf AFAIK,
i.e.
binlog-ignore-db = mysql
replicate-ignore-db = mysql
I am not sure, if this works from client side too, can anyone explain the mechanism, how can i be able to send from master but not accept in client side.
Why i want to do this? I have multiple slave "2 slave" must replicate MySQL table where as in other 2 should not be overwriten. Where as every other table will be replicated.
Reading this: http://dev.mysql.com/doc/refman/5.6/en/replication-rules-db-options.html didnt make me clear enough.
binlog-ignore-db is a master-side setting, it tells the Master not to log changes taking place on the listed DB.
replicate-ignore-db is a slave-side setting, it tells the Slave to ignore incoming log information related to the listed DB
The typical use case is when you want to replicate different databases from one single Master to different Slaves. The Master must log all changes occurring in all databases (minus those possibly excluded by binlog-ignore-db, i.e. database that will not be replicated anywhere).
Each Slave will receive the full binary log, but will only replicate changes related to the selected databases (i.e. databases not excluded by replicate-ignore-db -- this list would be different on each Slave).
(mysql database being a system database, it should be ignored from both ends, unless you really, really really know what you are doing).

MySQL Replication: Preventing master server from replicating table inserts

I have a logging table on the master server that is inserted into very often. I don't need this table replicated to the slave servers, and in fact I already have replicate-ignore-table set on the slaves to ignore it.
However, that only happens after all of those inserts are fetched from the master. I'd like to prevent those inserts from getting sent to the slaves entirely for 2 reasons:
Cut down on network traffic between the servers
I've had cases of the relay log entries being corrupted (and having to skip corrupted entries). Given the quantity of inserts into the logging table, it's always on those inserts (which aren't necessary anyway).
Is it possible to somehow prevent the master from sending back the logs for a specific table? Or, prevent the inserts from showing up in the master's bin-log files? I'm only aware of ignoring databases in the master's bin-log files.
Thanks.
In your code, send "SET SESSION sql_log_bin=0" to MySQL before inserting a logging row. Then set it back to 1 afterward.
This approach gives you fine-grained control over when and when not to binary-log. Only possible drawback is that the database user will need the SUPER privilege.