I'm trying to do a query like this:
CREATE TABLE Connection_Properties (
COL VARCHAR(30) NULL
)
CONNECTION = 'mysql://localhost:3306/DOCKER2'
PASSWORD = '1234';
Although the schema called docker2 entered in connection does not exist, it is shown that the above query has been performed.
What is the role of that keyword, and if that is done, how to retrieve connection information and password information from that table (Connection_Properties)?
An example of creating and accessing the table with FEDERATED engine.
Enabling FEDERATED Engine.
Stop the server.
Open my.ini and add federated line to [mysqld] section.
Start server and ensure that it is started normally.
Execute show engines; and ensure that FEDERATED storage engine support is enabled.
Creating and accessing FEDERATED table.
Create a table and insert some data in it. The table will be created using default engine (InnoDB in my case).
USE test
CREATE TABLE local_test (id INT, val INT);
INSERT INTO local_test VALUES (1,11), (2,22);
Create FEDERATED table connected to the above table.
CREATE TABLE federated_test (id INT, val INT)
ENGINE=FEDERATED
CONNECTION='mysql://username:password#localhost:3306/test/local_test';
Pay attention - only table structure with specified connection properties is created, the connection is not established and is not even checked!
Work with FEDERATED table.
SELECT * FROM federated_test; -- 2 rows are selected
INSERT INTO federated_test VALUES (3,33); -- insert 3rd row
SELECT * FROM local_test; -- and check that it was inserted successfully
Drop FEDERATED table.
DROP TABLE federated_test; -- drop FEDERATED table definition
SELECT * FROM local_test; -- ensure that this is not effected the local table
local_test is accessed directly.
federated_test is accessed remotely. When the query which needs to access this table is executed then local server establishes a connection to remote server according the connection options (protocol, address and port of the remote server, username and password for to authenticate), accesses specified remote table in specified remote database, receives the answer and uses it in the query. In the query text there is no difference does the table is local or remote.
Related
I would like to have a new table with FEDERATED engine, created (cloned) from another existing InnoDB table. Something like this:
CREATE TABLE balance_live
AS SELECT * FROM balance
ENGINE=FEDERATED
CONNECTION='mysql://user:pass#8.8.8.8:3306/db/balance'
But this doesn't work for some reason.
You need an actual table definition, specified explicitly. It's not a view, it's a table. See here for the correct syntax:
https://dev.mysql.com/doc/refman/8.0/en/federated-create-connection.html
Do SHOW CREATE TABLE balance; on the remote host and use that as the definition, just change ENGINE=FEDERATED and add the CONNECTION clause.
As mysql manual on creating federated tables says:
Create the table on the local server with an identical table definition, but adding the connection information that links the local table to the remote table.
You cannot use the as select ... , since in the from clause you can only specify a local table. It is the federated table that creates the link to the remote table.
Just copy the table definition over from the remote table.
I have a two DB server say Server-1 & Server-2, I have installed MySql yog into it, and the servers are able to connect with each other as I have already provided Grant privileges for the servers.
But, I need to build a query which can extract data from more than one servers like -
Select * from Server1.db.Table1, Server2.db.Table2
Is this possible in mysql, if yes, can you please help me to achieve the same.
Thanks
federated storage engine should help to full fill your requirement.
Follow link to enable Federated storage engine in your server from where you are accessing remote table.
--In Server1:
CREATE DATABASE fed_remote_db
CREATE USER 'fed_remote_user'#'%' IDENTIFIED BY 'fed_remote_password';
GRANT ALL ON fed_remote_db.* TO 'fed_remote_user'#'%';
CREATE TABLE fed_remote_db.fed_table(id INT,NAME VARCHAR(50));
--In Server2:
CREATE TABLE fed_remote_db.Server1_fed_table (
id INT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=FEDERATED CONNECTION='mysql://fed_remote_user:fed_remote_password#Server1_IP:3306/fed_remote_db/fed_table';
SELECT *
FROM
fed_remote_db.Server1_fed_table a /* Remember Server1_fed_table table referring to remote server /,
fed_remote_db.server2_fed_table b / server2_fed_table table referring to local server */
WHERE a.id=b.id;
I believe you can convert above example for your requirements.
In my prior job, I was able to copy data from our production environment in a breeze by using the following statements:
from tablename#UNIXPROD2
INSERT INTO tablename#UNIXTEST2
My current job's databases aren't setup in this fashion.
So, I did some research on MySQL 5.0+ because that's what we are using for one of our customers. And I came across FEDERATED tables, so as I was reading, I found this (here):
As of MySQL 5.0.46, FEDERATED performs bulk-insert handling such that multiple rows are sent to the remote table in a batch. This provides a performance improvement. Also, if the remote table is transactional, it enables the remote storage engine to perform statement rollback properly should an error occur. This capability has the following limitations:
To me, this indicates that (A) I can copy the data from our prod database to our test database; (B) any actions performed on the federated table will also be processed on the source table, which is not what I want to do. I have some scripts that I need to run and I want to run it against actual prod data to make sure it works before I use it in the prod environment.
My question: Is my interpretation correct?
Assuming it is, I've tried:
select * from database.tablename#ipaddress, but received an error message that told me to check the MySQL manual for the version I'm running, which is what I'm going to do after I hit "Post Your Question."
I would appreciate any help in this matter.
EDIT: After further research, I think might be able to do what I need using OUTFILE and INFILE whereby I would use OUTFILE on the prod table(s) and then INFILE those rows on the test table(s). Thoughts?
My answer:
A - correct
B - correct.
You could set the user permission to read-only, but in your situation I would not use federated tables, instead dump the whole db into file and then restore it on the other server. Easiest way - use MySql Workbench.
and some info about federated tables:
You need federated enabled just on server B
You can access a view on A by making a federated table on B
You can do INSERT UPDATE DELETE on federated table
If you need read-only access you can limit the user privileges
BUT! You can't do any aggregate func. on a view which will be federated (ex. COUNT(), MAX(), UNION...) (you can, however it will lag)
Remember to set the KEY's on the federated table you are creating. (or it will lag horr.)
Remember to use ALGORITHM=MERGE on views
Remember to grant acces to USERNAME(from connection string) on server A
example of a federated table on server B:
delimiter $$
CREATE TABLE `schemaName`.`tableName`(
`keyName` VARCHAR(10) NOT NULL,
`key2Name` DATE DEFAULT '2012-01-01',
KEY `keyName` (`keyName`)
)
ENGINE=FEDERATED
DEFAULT CHARSET=utf8
CONNECTION='mysql://USERNAME:PASSWORD#IPADDRESS:PORTNUMBER/baseSchema/baseTable'
$$
And the view on server A:
CREATE
ALGORITHM = MERGE
DEFINER = `ANOTHERUSERNAME`#`%`
SQL SECURITY DEFINER
VIEW `baseSchema`.`baseTable` AS
SELECT
... AS `keyName`,
... AS `key2Name`
FROM
...
My project has its own database. Also, I use table of users, which is on other database. Two offices have their data on the same server, but third one has its own user table on other server.
So, in lots of queries I need to join either table some_db.users or other_server.some_db.users
What solution would you advise for this scenario?
I use MySQL.
There is Federated tables in MySQL:
The FEDERATED storage engine lets you access data from a remote MySQL
database without using replication or cluster technology. Querying a
local FEDERATED table automatically pulls the data from the remote
(federated) tables. No data is stored on the local tables.
First, you must have a table on the remote server that you want to access by using a FEDERATED table. Suppose that the remote table is in the sakila database and is defined like this:
CREATE TABLE test_table (
id INT(20) NOT NULL AUTO_INCREMENT,
name VARCHAR(32) NOT NULL
PRIMARY KEY (id)
)
ENGINE=MyISAM
DEFAULT CHARSET=latin1;
Next, create a FEDERATED table on the local server for accessing the remote table:
CREATE TABLE federated_table (
id INT(20) NOT NULL AUTO_INCREMENT,
name VARCHAR(32) NOT NULL
PRIMARY KEY (id)
)
ENGINE=FEDERATED
DEFAULT CHARSET=latin1
CONNECTION='mysql://fed_user:fed_user#197.186.1.199:3306/sakila/test_table';
Sample connection strings:
CONNECTION='mysql://username:password#hostname:port/database/tablename'
CONNECTION='mysql://username#hostname/database/tablename'
CONNECTION='mysql://username:password#hostname/database/tablename'
The basic structure of this table should match that of the remote table, except that the ENGINE table option should be FEDERATED.
Execute:
show variables like '%federated%';
to check if FEDERATED storage engine is available on your local server.
The table federated_table in localhost becomes virtual table of test_table in remote server.
Now you can use the JOIN between the tables in a DB in the localhost server. If there is a table called test in your localhost server, and you want to JOIN with the former sakila.test_table which is in the remote server, write a query like the one shown below:
SELECT * FROM `federated_table` JOIN `test`;
The federated_table in the query will actually refer to test_table in remote server.
On enabling FEDERATED Storage Engine
The FEDERATED storage engine is not enabled by default in the running server; to enable FEDERATED, you must start the MySQL server binary using the --federated option.
NOTE:
Optional storage engines require privileges and will fail to load when --skip-grant-tables is specified.
The result the entire db will fail to load and the following error will appear in the logs:
110318 21:37:23 [ERROR] /usr/local/libexec/mysqld: unknown option '--federated'
This in turn means that an upgrade from 5.x needs to be done in two steps if you have federated tables. Once with --skip-grant-tables and without --federated, the once without --skip-grant-tables and with --federated.
Source: The FEDERATED Storage Engine
Please mention the databse also.
In SQLServer you can use Linked sever. http://msdn.microsoft.com/en-us/library/ms188279.aspx
In MySQL, you can join tables from different databases using fully qualified names like
`database_name1`. `table_name1` JOIN `database_name2`.`table_name2`
But i fear, you cant join tables from different servers because for that you need to have two different connections and as per my knowledge there are no fully qualified connection names to be used in the query.
Alternatively, you can create local temporary table(s) on one of the servers and run the query there on. But in this case you will need to transfer data from one server to another. You can use MySQL GUI tool like SQLyog or MySQL admin, to transfer data from one server to another and to synchronize databases on two servers.
Hope it helps....
Federated tables are your solution for tables on other servers. They are very slow though if you perform joins on them.
If you just want to read data from another database on the same server you can use a view. This way you have all tables virtually in one database and you have to open only one connection in your application.
CREATE
VIEW `my_db`.`table_name`
AS
(SELECT * FROM `other_db`.`table_name`);
I have a DB on which I enabled symmetric encryption, to encrypt some columns.
I created a SP to enable encryption after I create the DB from script, as below
CREATE PROCEDURE [dbo].[sys_EnableSymmetricEncryption]
AS
BEGIN
--If there is no master key, create one now.
IF NOT EXISTS
(SELECT * FROM sys.symmetric_keys WHERE symmetric_key_id = 101)
CREATE MASTER KEY ENCRYPTION BY
PASSWORD = '9809u0ij989oih9o8yyo98yyo89uyp9p9'
CREATE CERTIFICATE My_Certificate
WITH SUBJECT = 'My Database';
CREATE SYMMETRIC KEY My_Key_01
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE My_Certificate;
END
So after I create db from script, I run this and then I can store data in encrypted columns
with
INSERT INTO [dbo].[Cards]
([CardNumber]
,[CardSecurityCode]
,[CardExpirationDate]
,[NameOnCard])
VALUES
(EncryptByKey(Key_GUID('My_Key_01'), #CardNumber) ,
EncryptByKey(Key_GUID('My_Key_01'), #CardSecurityCode) ,
EncryptByKey(Key_GUID('My_Key_01'), #CardExpirationDate) ,
EncryptByKey(Key_GUID('My_Key_01'), #NameOnCard))
and retrieve data with
OPEN SYMMETRIC KEY My_Key_01
DECRYPTION BY CERTIFICATE My_Certificate;
SELECT [CardID]
,CONVERT(nvarchar, DecryptByKey([CardNumber])) as 'CardNumber'
,CONVERT(nvarchar, DecryptByKey([CardSecurityCode])) as 'CardSecurityCode'
,CONVERT(nvarchar, DecryptByKey([CardExpirationDate])) as 'CardExpirationDate'
,CONVERT(nvarchar, DecryptByKey([NameOnCard])) as 'NameOnCard'
FROM [Cards]
All works well till I backup db and try to restore the backup on a different server
After I restore, when I try to run Select (as above) I get this error
Please create a master key in the database or open the master key in the session before performing this operation.
So I was trying to recreate the key with
IF NOT EXISTS
(SELECT * FROM sys.symmetric_keys WHERE symmetric_key_id = 101)
CREATE MASTER KEY ENCRYPTION BY
PASSWORD = '9809u0ij989oih9o8yyo98yyo89uyp9p9'
But then on select In still get the same error.
If I try to run the first Sp shown above, to create master key, cert and symmetric key, I get error
Msg 15581, Level 16, State 3, Procedure sys_EnableSymmetricEncryption, Line 11
Please create a master key in the database or open the master key in the session before performing this operation.
Msg 15282, Level 16, State 1, Procedure sys_EnableSymmetricEncryption, Line 14
A key with name 'OneTest_Key_01' or user defined unique identifier already exists or you do not have permissions to create
Maybe I should try to delete the certificate and symmetric key before trying to create them, but I don't know where are they located.
Any idea how to handle this?
Thanks
PS if I restore in same server, even as different database, all works fine
Try to run:
ALTER MASTER KEY REGENERATE WITH ENCRYPTION BY PASSWORD = '9809u0ij989oih9o8yyo98yyo89uyp9p9';