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';
Related
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.
In the stand-alone mode of SequoiaDB, when I want to connect MySQL to create table, it reported the following error:
mysql> use cs;
Database changed
mysql> create table cl(a int, b int, c text, primary key(a, b) ) engine = SequoiaDB ;
ERROR 1030 (HY000): Got error 49841 from storage engine
SDB_RTN_COORD_ONLY can only be used for coordination node
By default, when you create a table on MySQL, it will synchronize to create the corresponding partition table (hash partition, including all partition groups) on SequoiaDB. The partition key takes precedence over the primary key field. If the primary key is not created when creating table, please use the unique key. If the unique key is not created, please use the first field. Users can disable the creation of the default partition table by setting the configuration parameter sequoiadb_use_partition to OFF. This configuration parameter can also be modified in the shell command line and configuration file.
View configuration parameters and shell command:
mysql> show variables like sequoiadb%;
Turn the sequoiadb_use_partition to ON
Using command:
mysql> SET GLOBAL sequoiadb_use_partition=OFF;
And set it to OFF.
For more information, you can refer to this article
I am trying to use the Mysql service from Compose.io
This service has, by default, replication (3 nodes)
When I try to install Drupal through either Drush or WebUI, I get some errors:
Failed to INSERT a value into a test table on your database server. We tried inserting a value with the command INSERT INTO {drupal_install_test} (id) VALUES (1) and the server reported the following error: SQLSTATE[HY000]: General error: 3098 The table does not comply with the requirements by an external plugin.: INSERT INTO {drupal_install_test} (id) VALUES (1); Array ( ) .
Failed to UPDATE a value in a test table on your database server. We tried updating a value with the command UPDATE {drupal_install_test} SET id = 2 and the server reported the following error: SQLSTATE[HY000]: General error: 3098 The table does not comply with the requirements by an external plugin.: UPDATE {drupal_install_test} SET id = 2; Array ( ) .
Failed to DELETE a value from a test table on your database server. We tried deleting a value with the command DELETE FROM {drupal_install_test} and the server reported the following error: SQLSTATE[HY000]: General error: 3098 The table does not comply with the requirements by an external plugin.: DELETE FROM {drupal_install_test}; Array ( ) .
When replication is on, every table needs to have a Primary Key, and apparently Drupal don't add those by default.
Is there any workaround on configuring Drupal to use a Mysql db with Replication on?
Note that Compose.io doesn't expose the replicas, only the master, to the user.
This is apparently an error message returned by the new Group Replication feature.
Yes, Group Replication requires that all tables have a primary key.
https://dev.mysql.com/doc/refman/5.7/en/group-replication-requirements.html says:
Every table that is to be replicated by the group must have a defined primary key, or primary key equivalent where the equivalent is a non-null unique key.
Unfortunately, the test table Drupal uses to test installation does not have a primary key (or equivalent).
This has been reported as an issue to Drupal: https://www.drupal.org/project/drupal/issues/2856362
There might be a fix coming in Drupal 8.5 or later, but in the meantime, there could be useful patches proposed by commenters in that issue. Basically, you just need to change the creation of the drupal_install_test table in a few files to:
CREATE TABLE {drupal_install_test} (id INT NOT NULL PRIMARY KEY)
EASY FIX (Drupal 7)
In your install.inc file line #307 must be changed to
CREATE TABLE {drupal_install_test} (id int NOT NULL PRIMARY KEY)
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.
I am doing master/slave replication on MySQL5.1 and r/w split with mysql proxy 0.8.x
It works fine except with temporary tables. MySQL throws an error, that the temporary table is not existent.
This is the query log for the master server:
CREATE TEMPORARY TABLE IF NOT EXISTS sh ( ad_id MEDIUMINT( 8 ) UNSIGNED NOT NULL, score float , INDEX ( `ad_id` ), INDEX ( `score` )) ENGINE = MEMORY
INSERT INTO sh
SELECT cl.ID, 1
FROM classifieds cl
WHERE cl.advertiser_id = '40179'
This is the query log for the slave:
CREATE TEMPORARY TABLE IF NOT EXISTS sh ( ad_id MEDIUMINT( 8 ) UNSIGNED NOT NULL, score float , INDEX ( `ad_id` ), INDEX ( `score` )) ENGINE = MEMORY
This is the mysql errror message:
Occured during executing INSERT INTO sh SELECT cl.ID, 1 FROM classifieds cl WHERE cl.advertiser_id = '40179' statement
Error: 1146 Table 'dbname.sh' doesn't exist
If I query the master directly (change php db connection to master instead to mysql-proxy), it works without problems.
I am using this mysql proxy config:
[mysql-proxy]
daemon = true
pid-file = /home/mysqladm/mysql-proxy.pid
log-file = /home/mysqladm/mysql-proxy.log
log-level = debug
proxy-address = 192.168.0.109:3307
proxy-backend-addresses = 192.168.0.108:3306
proxy-read-only-backend-addresses = 192.168.0.109
proxy-lua-script = /usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
Has anybody an idea on how to fix that? Thank you for any help!
// edit next day
I believe I know why this isn't working:
MySQL Proxy sends the create tmp and insert select statements to the master which replicates the commands correctly to the slave, then in the next step the select is sent to the slave. Unfortunatelly in MySQL the tmp table is only valid for the connection which issued it, therefore the tmp table created by the replication is not valid for the second connection issued by mysql proxy on slave.
I am now trying to solve this by changing my application and issuing connects with tmp tables directly to the master.
Please let me know if you believe that there is a better solution.
Yes, that's exactly the problem. This is one of the pitfalls of splitting read queries with MySQL Proxy instead of having the application layer make that determination for itself.
It sounds like what you're doing is putting that determination back into the application layer, but for these tables only. That's a fine workaround. If you find yourself making more exceptions that require pointing a dbh directly at a database, consider abstracting that code and giving your application a way to request a dbh for a particular functionality. In this case, you'd like your code to ask a library "give me a dbh that I can perform TEMPORARY TABLE queries on."
Another way would be to give all TEMPORARY TABLEs recognizable names (maybe make them all start with "tmp_") which would give Proxy a fighting chance to send SELECTs on them to the right place.