Can I CREATE TRIGGER in an rds DB? - triggers

I'm trying to create a trigger on a table in my Amazon RDS database, and I can't seem to make it happen.
I tried to create a trigger on a table in the mysql client I use (Navicat), and got the error that I needed the SUPER privilege to do so. After some searching, I found that you could SET GLOBAL log_bin_trust_function_creators = 1 to get around this. I tried that using these instructions: http://getasysadmin.com/2011/06/amazon-rds-super-privileges/ (and then restarting the DB server for good measure), but no luck.
I also tried creating the trigger and setting the variable via the mysql commmand line to make sure Navicat wasn't adding anything unwanted to my sql commands, but that failed, too. It also seems from searching that there's no way to grant yourself the SUPER privilege.
So ... is creating a trigger possible in RDS?

Its easy!
Open the RDS web console.
Open the “Parameter Groups” tab.
Create a new Parameter Group. On the dialog, select the MySQL family compatible to your MySQL database version, give it a name and confirm.
Select the just created Parameter Group and issue “Edit Parameters”.
Look for the parameter ‘log_bin_trust_function_creators’ and set its value to ’1′.
Save the changes.
Open the “Instances” tab. Expand your MySQL instance and issue the “Instance Action” named “Modify”.
Select the just created Parameter Group and enable “Apply Immediately”.
Click on “Continue” and confirm the changes.
Again, open the “Instances” tab. Expand your MySQL instance and issue the “Instance Action” named “Modify”.
Dont forget: Open the “Instances” tab. Expand your MySQL instance and issue the “Instance Action” named “Reboot”.
Via - http://techtavern.wordpress.com/2013/06/17/mysql-triggers-and-amazon-rds/

No it is actually not impossible it just takes far too much extra work.
First off it seems to be impossible to apply Super Privileges to a default parameter group.
So what I had to do was to create a new DB Parameter group either through the Console, or the CLI.
What I found was, the key is that the default region was not the region I was trying to use so I had to use a --region parameter to apply it to the group in the correct region where I was deploying my DB Instance
rds-create-db-parameter-group --db-parameter-group-name allow-triggers --description 'parameter group to allow triggers' --region your-region
Next I had to create a DB Instance which used that parameter group. (Again through the console or CLI)
rds-create-db-instance
Then I had to modify the Parameter group to allow log_bin_trust_function_creators only accomplishable through the CLI
rds-modify-db-parameter-group --db-parameter-group-name yourgroupname --region yourRegion --parameters 'name=log_bin_trust_function_creators,value=true,method=immediate'
Lastly I had to modify the created DB Instance to allow triggers, also CLI only.
rds-modify-db-instance --db-instance-identifier your-db-instance-id --db-parameter-group-name allow-triggers --apply-immediately

In addition to the parameter group modification that others have already mentioned, there is a further challenge that arises when using a MySQL database dump (via mysqldump) to create triggers in an AWS RDS instance. You may get a message like this:
ERROR 1227 (42000) at line 875: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
This happens because the dump contains "definer" entries with a username that's different than your RDS master username. One solution is to replace the definer username with your RDS master username. Another solution is not to use mysqldump to create your database.
See this blog post for more information:
http://www.percona.com/blog/2014/07/02/using-mysql-triggers-and-views-in-amazon-rds/

EDIT: It turns out Multi-AZ for MySQL uses "physical replication" and not logical replication, so this may not be correct. At least that's what their documentation says: https://aws.amazon.com/rds/details/multi-az/ - I have asked on their forums what this means, but did not get a reply. What's weird is that my RDS Multi-AZ instance claims it's a "master in a replication setup", even though I have no read replicas.
As the question has already been addressed, this is a comment more than an answer:
I'm surprised nobody takes into account why this feature is not available as a default. Amazon wouldn't disable it just to make people's lives harder.
In a master/slave replication it can be dangerous to use stored procedures and triggers that modify data (as in perform queries other than SELECT).
Please have a read below before disabling this restriction in a master/slave setup, which Amazon RDS is when you use Multi-AZ (and you should, for production at least).
http://dev.mysql.com/doc/refman/5.6/en/stored-programs-logging.html

I followed the above but it did not work for me. I spent almost a day to figure out why it is not working and now I know why. I am listing down steps that I followed to make it work.
Created mysql parameters group using aws web console (make sure that it should have same family as the default parameter group. Earlier, I had created a parameter group but it had different family and so it did not work. This is critical step.
Using aws web console change value of log_bin_trust_function_creators to 1
Apply new parameter group. This is another critical step
rds-modify-db-instance –I $AWS_ACCESS_KEY –S $AWS_SECRET_KEY –region $EC2_REGION \ –db-instance-identifier $DB_INSTANCE \
–db-parameter-group-name $DB_GROUPNAME \
–apply-immediately
You need RDSCli from - http://s3.amazonaws.com/rds-downloads/RDSCli.zip
Then verify if parameter group is associated with your db instance
rds-describe-db-instances \
–I $AWS_ACCESS_KEY \
–S $AWS_SECRET_KEY \
–region $EC2_REGION
And then reboot before you try creating trigger
rds-reboot-db-instance \
–I $AWS_ACCESS_KEY \
–S $AWS_SECRET_KEY \
–region $EC2_REGION \
–db-instance-identifier $DB_INSTANCE
Remember to set below environment variable before you try above commands.
export AWS_ACCESS_KEY=’*****’
export AWS_SECRET_KEY=’*****’
export EC2_REGION=’region’
export AWS_RDS_BIN=”$AWS_RDS_HOME/bin”
export PATH=$PATH:$AWS_RDS_BIN
export JAVA_HOME=c:/jdk1.6_25 (in most cases this is already set)
Thanks to http://blog.iprofs.nl/2013/03/20/rds-database-triggers-for-mysql/ for full details.

AWS lays out how to enable functions and triggers in this post
Create a DB parameter group for your MySQL instance:
Sign in to the AWS Management Console and open the Amazon RDS console.
In the navigation pane, choose Parameter Groups.
Choose Create Parameter Group. The Create Parameter Group window appears.
For Parameter Group Family, choose the parameter group family.
For Group Name, type the name of the new DB parameter group.
For Description, type a description for the new DB parameter group.
Choose Create.
Important
After you create a DB parameter group, you should wait at least 5 minutes before creating your first DB instance that uses that DB parameter group.
For more information about creating a DB parameter group, see Working with DB Parameter Groups - Creating a DB Parameter Group.
Modify the newly created parameter group and set the following parameter:
In the navigation pane, choose Parameter Groups. The available DB parameter groups appear in a list.
In the list, select the parameter group you want to modify.
Choose Edit Parameters and set the following parameter to the specified value:
log_bin_trust_function_creators = 1
Choose Save Changes.
Important
After you modify a DB parameter group, you should wait at least 5 minutes before creating your first DB instance that uses that DB parameter group.
For information about modifiying a DB parameter group, see Working with DB Parameter Groups - Modifying Parameters in a DB Parameter Group.
Associate your RDS DB instance with the new or modified DB parameter group:
In the navigation pane, choose Instances.
Select the DB instance you want to associate with a DB parameter group.
On the Instance Actions menu, choose Modify.
In the Modify DB Instance dialog box, under Database Options, choose the parameter group you want to associate with the DB instance. Changing this setting does not result in an outage. The parameter group name changes immediately, but the actual parameter changes are not applied until you reboot the instance without failover.
Apply changes by rebooting the instance.

For me, it worked as the #foxybagga's answer suggest, but I needed to update the generated sql's dump (from mysqlworkbench) to have CURRENT_USER as the DEFINER
ie:
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=CURRENT_USER*/ /*!50003 TRIGGER `sod_db`.`date`
BEFORE INSERT ON `sod_db`.`CashOut`
FOR EACH ROW
BEGIN
SET NEW.created = NOW();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = #saved_sql_mode */ ;
/*!50003 SET character_set_client = #saved_cs_client */ ;
/*!50003 SET character_set_results = #saved_cs_results */ ;
/*!50003 SET collation_connection = #saved_col_connection */ ;
I hope this helps someone is having the same problem.

Related

Keycloak Admin CLI - Updating a realm with JSON file

Objective:
Our objective is to update the entire realm provided a json file.
Problem:
The issue at hand is we cannot seem to update the realm entirely to include the client changes as well.
Actions taken:
Option 1:
Based on the Keycloak Admin CLI documentation, a Keycloak realm can be updated from a JSON file using the following command:
kcadm.sh update realms/demorealm -f demorealm.json
However, when making an update to a property within the clients section of the JSON file (i.e. a client's description), the change is not reflected within the Keycloak realm.
We also tried to take a look at the kcadm.sh help update . We tried to utilize the merge flag (Merge new values with existing configuration on the server. Merge is automatically enabled unless --file is specified) . We do have a file specified and therefore tried to enable it using the flag - but to no success. The clients did not change as expected.
Option 2:
We have tried the partial import command found in Keycloak documentation
$ kcadm.sh create partialImport -r demorealm -s ifResourceExists=OVERWRITE-o -f demorealm.json
With the ifResourceExists set to OVERWRITE, it accurately changes clients. However, it alters other Realm configurations such as assigned users roles. Ex: After manually creating a new user via the Keycloak UI and setting roles for the user, the roles are lost after running the command with the OVERWRITE flag set. Setting the ifResourceExists to SKIP does not properly update values for a client as it is skipped altogether.
Question:
Is it possible, either with a different command or different flags, to update a Keycloak realm in its entirety with a single Keycloak admin command? Neither Option 1 or Option 2 listed above worked for us. We want to avoid making individual update client calls when updating the Realm.
Notes:
We have properly authenticated and confirmed that changes made at the realm level are reflected in Keycloak.
After further research, the approach we decided to go with is to update realm level settings with:
kcadm.sh update realms/demorealm -f demorealm.json
We then iterate over the clients and add/update them with:
kcadm.sh update clients/{clients-uuid} -f clientfile.json
Since the previous command does not update client roles, we must then use the following command to add the roles:
kcadm.sh update clients/{clients-uuid}/roles/{role-name} -f rolefile.json
Finally, to add in composite roles, we use this command:
kcadm.sh add-roles --cclientid {clientID} --rid {id of client role} --rolename {name of role to add}

Is it possibe to have multiple kerberos tickets on same machine?

I have a use case where I need to connect to 2 different DBS using 2 different accounts. And I am using Kerberos for authentication.
Is it possible to create multiple Kerberos tickets on same machine?
kinit account1#DOMAIN.COM (first ticket)
kinit account2#DOMAIN.COM (second ticket)
Whenever I do klist, I only see most recent ticket created. It doesn't show all the tickets.
Next, I have a job that needs to first use ticket for account1 (for connection to DB1) and then use ticket for account2 (for DB2).
Is that possible? How do I tell in DB connection what ticket to use?
I'm assuming MIT Kerberos and linking to those docs.
Try klist -A to show all tickets in the ticket cache. If there is only one try switching your ccache type to DIR as described here:
DIR points to the storage location of the collection of the credential caches in FILE: format. It is most useful when dealing with multiple Kerberos realms and KDCs. For release 1.10 the directory must already exist. In post-1.10 releases the requirement is for parent directory to exist and the current process must have permissions to create the directory if it does not exist. See Collections of caches for details. New in release 1.10. The following residual forms are supported:
DIR:dirname
DIR::dirpath/filename - a single cache within the directory
Switching to a ccache of the latter type causes it to become the primary for the directory.
You do this by specifying the default ccache name as DIR:/path/to/cache on one of the ways described here.
The default credential cache name is determined by the following, in descending order of priority:
The KRB5CCNAME environment variable. For example, KRB5CCNAME=DIR:/mydir/.
The default_ccache_name profile variable in [libdefaults].
The hardcoded default, DEFCCNAME.

Google Cloud SQL for PostgreSQL `work_mem`

there. I want to tune Google Cloud SQL for PostgreSQL instance. Currently, I'm trying to eliminate sorting speed degradation:
Sort Method: external merge Disk: 39592kB
Right now work_mem is set to 4MB, and it seems that is too small. After reading docs, I didn't find the way how to change this setting. It's impossible via Web GUI and via command line:
$ gcloud sql instances patch reporting-dev --database-flags work_mem=128MB
The following message will be used for the patch API method.
{"project": "xxx-153410", "name": "reporting-dev", "settings": {"databaseFlags": [{"name": "work_mem", "value": "128MB"}]}}
WARNING: This patch modifies a value that requires your instance to be
restarted. Submitting this patch will immediately restart your
instance if it's running.
Do you want to continue (Y/n)? Y
ERROR: (gcloud.sql.instances.patch) HTTPError 404: Flag requested cannot be set.
Any thoughts on that?
You can change it by user or by database.
alter database db1 set work_mem='64MB';
alter user stan set work_mem='32MB';
User overides db, db overrides postgresql.conf / cluster settings. Both override alter system set ... which you might not be able to use due to security settings.

What are the privileges and the configuration required for SQL Producer

From the documentation I couldn't find anything related to privilege settings and configurations required for SQLServer Producer.
What should be the grants and privileges given to SQL user in order to have CodeFluent Entities to generate all the objets (table, procedures and so on)?
Thanks for your answer.
To generate the model, the SQL user needs to have the serveradmin server role (or above: sysadmin). This server role is needed to run the project_runtime.sql script (sp_addmessage).
The rest of the scripts are DELETE, ALTER, UPDATE, INSERT, SELECT. You can view the SQL roles here:
http://msdn.microsoft.com/en-us/library/ms189121.aspx
http://msdn.microsoft.com/en-us/library/ms189612.aspx
If you need to setup specific restrictions, you could run the project_runtime.sql manually (with a high server role), and let the user do the rest.
Also, you can configure the SQL Producer to not generate the sp_addmessage, because it's not mandatory to run the application. Set Add Runtime Messages=False
Regards,

How to set a timezone for MySql Google Cloud SQL

Tried to create new costume flag from the developer console - doesn't work.
Tied from the command line: gcloud sql instances patch --database-flags time_zone
Doesn't work, get error: "invalidFlagName"
There is a database flag "default_time_zone" in developer console that you can use to specify timezone offset when you create a new instance or edit an existing instance.
See https://cloud.google.com/sql/docs/mysql-flags for detailed info.
The MySQL timezone tables are not populated so that flag is not supported via the --database-flags or web UI. If you are happy maintaining the tables yourself then ping us at cloud-sql#google.com with the setting you want and we'll manually set it.