User-specific mysql timeout - mysql

Is there a way to set a SELECT timeout for a specific mysql user? The following question address this for any user on a database -- How to set a maximum execution time for a mysql query? -- but I want to set it only for a specific mysql user, the user given below.
Id User Host db Command Time State Info
97 tvs0XXX ec2...com:47703 ax Query 55 Creating sort index SELECT...

You can define this using max_execution_time session variable (in milliseconds), something like:
SET SESSION max_execution_time=2000;
It should be done from a client for each session, so there is no way (currently) to assign this for a specific database user.

Related

How can I force limit the number of rows returned from a query for all users?

We are looking to limit the number of rows returned when any user makes a SELECT query from our database. Of course you can manually limit the number of rows on a returned query, but we want to force-append something like limit 10 on all SELECT commands. Users will only be able to access this database from a bastion host using the MySQL CLI.
For example:
SELECT * FROM customer
would return all rows. Without a user specifying, we want to automatically turn the command into something like this so they can only get 10 rows back at the absolute maximum:
SELECT * FROM customer limit 10
Any way of achieving this desired functionality would be fine (whether it's an appended command or not). Is this possible?
If you do not trust your users to be able to use the database responsibly, you probably should not allow them to have direct access to the database via mysql cli. Develop a reporting layer where you can enforce such limitations.
If you insist on using mysql cli, then turn on --safe-updates option and configure --select-limit option.
Alternatively, set the sql_select_limit setting via config or batch file for these users.

How to fix mysql select command giving wrong result after the update in another db connection?

I have taken two mysql db connections using python MySQLdb module namely db and db1. The first connection is used to read a table and the second connection is for updating the table.
The following are the sequence of code that I have used.
1 : Read id from user table using db conncetion; current value 'Y'
2 : Update id in user table to 'N' using db1 connection.
3 : Reading id from user table using db connection. But at this time it gives value 'Y'.
import MySQLdb
db = MySQLdb.connect("localhost","root","test007","db",charset='')
apikey="123"
cursor=db.cursor() ## fetching no. of data received in valid time range
cursor.execute("select id from USER where apikey=%s",(apikey,))
data=cursor.fetchone()
cursor.close()
print data #current value 'Y'
db1 = MySQLdb.connect("localhost","root","test007","db",charset='')
cursor=db1.cursor() ## fetching no. of data received in valid time range
cursor.execute("update USER set id='N' where apikey=%s",(apikey,))
db1.commit()
cursor.close()
db1.close()
cursor=db.cursor() ## fetching no. of data received in valid time range
cursor.execute("select id from USER where apikey=%s",(apikey,))
data=cursor.fetchone()
cursor.close()
print data
db.close()
In step 3 it doesn't show the updated value. Why does this happen? How can i solve this issue without closing the connection db and take another connection to read the table after update?
This is not the actual code implementation. db1 is actually running from some other file. For simplicity, I just showed this.
It's doing what it is supposed to. REPEATABLE-READ means that you see the same data, regardless of what is going on in other transactions. This, of course, lasts only until your transaction terminates.
Think of it as taking a snapshot of the entire dataset when you start the transaction. Then, everything you do or see (SELECT) is frozen in time.
Either change to READ-UNCOMMITTED or break up the SELECTs into separate transactions.
As explained above, this is apparently as it ought to behave because of this illustion below (see https://dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html)
So simply commiting transaction before reading from the session resolves this error.

mysql: logging specific user logins

I'm looking for a stored procedure or something to log user-logins to mysql.
Users will have to be in a positive list.
I need to log user, login time, ip/hostname and query ( query not essential, but a nice-to-have).
My major problem is that I cannot do it via general query log, as is generates +23Gb of log per instance/day (i have 18 instances) and I don't have capacity for it.
I was thinking somewhat in lines of stored procedures, but cannot get my head around it, but not sure if it is the right way to go about it.
Capacity expansion is not an option.
Platform is:
CentOS Linux release 7.3.1611
mysql-community-server-5.6.36-2
Any thoughts on how to solve my issue are welcome.
You may be looking for the mysql init_connect system variable :
A string to be executed by the server for each client that connects. The string consists of one or more SQL statements, separated by semicolon characters.
So basically you want to create a table where logins will be logged, and set the init_connect system variable to something like :
INSERT INTO my_logging_audit
SELECT USER(), NOW()
WHERE USER() IN ('foo', 'bar');

Get user info with trigger in MySQL

As the title said, I'd like to get some information of the user who is executing the SQL statement in MySQL. For example, if some SQL statement is executed by a user called 'work', how could I got the user name and host with trigger before it is actually executed in MySQL.
Actually, I just want to monitor some actions, like DELETE, in MySQL. And I'm not sure the binlog can record the username and host who executed the SQL statement.
SELECT * FROM information_schema.PROCESSLIST WHERE USER="someuser";
Now it is up to you what you use. Write a cron job (linux) to store it into a file or write a MySQL event to enter it into a MySQL table.
The user#host that you appear to be looking for is available from the USER() information function.
https://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_user

MySQL: automatic mapping of UTC to Local Timezone

I have a forum where users can post comments. When a comment is created its corresponding datetime value is stored in UTC format.
I intend to present the data in local time, say 'ASIA/SINGAPORE';
2 options:
use convert_tz each time querying the database. I dont like the
approach, cause it makes me rewrite the select_expr each time querying.
use SET time_zone = 'ASIA/SINGAPORE';
As for the second option, I want to know what is the validity scope of the command (no super privilege here). more specifically, say if i'm using a php application, does the config gets invalid as i close db connection? should i issue the command each time querying the db?
Tnx.
MySQL variables are scoped in the connection (lowest level, between libmysql <-> mysqld). It means, that if PHP itself or some application library uses any kind of mysql connection pooling, then you could observe this variable disappearing (because of invisible connection switching), and the variable definitely will disappear after disconnecting.
If you are not happy rewriting your query, you probably could select apropriate tz name on the fly -- say, form a users table, as long as you have the id of the logged user, like this:
SELECT convert_tz( ..., ..., (select user_tz from users where user_id = ...))