Wednesday, March 25, 2009

Mysql: Client Tips 2: Running Shell Commands from the Commandline

Ok, As you know I am trying to explore more of the mysql command line and exploring its features. I have already written about how to change default mysql prompt using the command "prompt" in one of my previous articles.

Continuing this series. I am focusing today on the "system" command or "/!".

Well, I always have some of the sql source files and I execute it from the mysql command line. But I just keep forgetting their names. And most of the times I either close the mysql session and do 'ls' at the command line or move the mysql session in background and do a 'ls'.

Mysql cli has this very useful command called "system" using which you can execute shell commands from mysql client itself.

just type
  system ls -l
or
  \! ls -l
Some of us, who are familiar with Vim, will like this "\!" version a lot, because we are already using ! to run system commands there.

You can run almost all system commands using either of system or '\!'

Some examples:
mysql:root@test [14:26:19 pm]$ \! pwd
/home/owner

mysql:root@test [14:29:33 pm]$ \! date
Thu Mar 26 14:29:46 SGT 2009

mysql:root@test [14:29:46 pm]$ \! bash
owner@rocky-desktop:~$ exit
mysql:root@test [14:30:12 pm]$

You see the last one is quiet interesting. You can actually open a shell using this command perform some tasks. Just exit from the shell and you are back in the mysql world.

Liked it ! Start playing with mysql client system command.

Tuesday, March 24, 2009

Mysql: Comments Trick

Nice article by Eli White. Now you can understand easily all those comments that you see in the mysqldump output.


MySQL Trick with Comments
MySQL has a custom extension (if you want to call it that) to it’s commenting system, which actually allows you to make conditional commands. The mysqldump program that many people use to back up their databases uses this concept heavily, which is where I first ran into it.

In it’s simplest form, this allows you to place commands in a SQL file that only MySQL will run:

/*! MySQL specific code */

This allows you to make a single SQL file, that not only will execute correctly (and in detail) on MySQL, but it will also work on any ANSI compatible database, since you’ve hidden any of the non-ANSI parts in MySQL conditional comments. So for example, MySQL allows you to set a variable declaring that all names will be a certain character set, such as UTF-8, and therefore you can do:

/*! SET NAMES utf8 */;


Thursday, March 19, 2009

MySQL: Query to List Down All Schema Objects


Below is a simple query to ease your day to day work. It simply lists down all the objects of a MySQL Schema. The things that you are mostly interested in e.g. Tables, Views, Routines, Indexes, Triggers and so on.

Just replace "[your-schema-name-here]" in the following query with your schema name. Hope it comes handy to some of you out there.

Update:05/27/2015 - Adding Github Gist for the script


SELECT OBJECT_TYPE
,OBJECT_SCHEMA
,OBJECT_NAME
FROM (
SELECT 'TABLE' AS OBJECT_TYPE
,TABLE_NAME AS OBJECT_NAME
,TABLE_SCHEMA AS OBJECT_SCHEMA
FROM information_schema.TABLES

UNION

SELECT 'VIEW' AS OBJECT_TYPE
,TABLE_NAME AS OBJECT_NAME
,TABLE_SCHEMA AS OBJECT_SCHEMA
FROM information_schema.VIEWS

UNION

SELECT 'INDEX[Type:Name:Table]' AS OBJECT_TYPE
,CONCAT (
CONSTRAINT_TYPE
,' : '
,CONSTRAINT_NAME
,' : '
,TABLE_NAME
) AS OBJECT_NAME
,TABLE_SCHEMA AS OBJECT_SCHEMA
FROM information_schema.TABLE_CONSTRAINTS

UNION

SELECT ROUTINE_TYPE AS OBJECT_TYPE
,ROUTINE_NAME AS OBJECT_NAME
,ROUTINE_SCHEMA AS OBJECT_SCHEMA
FROM information_schema.ROUTINES

UNION

SELECT 'TRIGGER[Schema:Object]' AS OBJECT_TYPE
,CONCAT (
TRIGGER_NAME
,' : '
,EVENT_OBJECT_SCHEMA
,' : '
,EVENT_OBJECT_TABLE
) AS OBJECT_NAME
,TRIGGER_SCHEMA AS OBJECT_SCHEMA
FROM information_schema.triggers
) R
WHERE R.OBJECT_SCHEMA = [your-schema-name-here];

Mysql: InnoDB: Transaction Models and Isolation Levels.

Inconsistency can play havoc while executing concurrent connection.
To make our life easy MySQL's InnoDB supports the following isolation levels.

  • Isolation level 1 (read uncommitted):- Can read the *dirty* update done by client 1. It can cause Inconsistent behaviour in case client 1 roll-backs. This isolation level also allow non-repeatable, phantom reads.
  • Isolation level 2 (read committed):- Can't read the *dirty* update done by client 1. Hence at this isolation level changes propagate only after the transaction is committed. However this isolation level allows non-repeatable and phantom reads.
  • Isolation level 3 (repeatable read):- Can't read the *dirty* update done by client 1. Also at this isolation level read locks are acquired on data. Thus reads are repeatable at this isolation level. Phantom reads however cause problem because range locks are not acquired at that level
  • Isolation level 4 (serializable):- Transaction is serialized, all three cases are handled, however slow in performance as at every level locks are acquired.

Default Isolation level for Mysql is Repeatable Read

How to check Isolation level for Mysql:

To know isolation level for current session :-

mysql> select @@tx_isolation;

To check isolation level globally:-

     mysql> select @@global.tx_isolation;

How to change Isolation level for Mysql:

Here is the command to do so:-

mysql> set [session|global] transaction isolation level [read uncommitted| read committed | read repeatable | serializable] ;
Note:
1. Use global if you want to set isolation level for all the new connections made from that point onwards. However it won't change isolation level of existing connections.

How to change Isolation level at service startup:

    Use --transaction-isolation=level, example
$ mysqld --transaction-isolation={ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE } start


Some examples to clear the air:-

Basic Setup

    * Client one reads device model information and can update device model information.
    * Client two can also read and update device model information.

Test Cases:-

Example 1:- ( Dirty Read ) Client One:

> start transactions;

> select dev_model from client;

| dev_model|
|   1      |
|   2      |
|   3      |

> update dev_model set dev_model=4 where dev_model=1;

Client Two:-

> start transactions;

> select dev_model from client;  
  ( At Isolation level 1 (read uncommitted) )
    |dev_model|
    |   4     |
    |   2     |
    |   3     |

   ( At Isolation level 2 (read committed) )
    |dev_model|
    |   1     |
    |   2     |
    |   3     |
  ( Same as above for level 3, 4)
 

Example 2 (Non-Repeatable Read):-

client 1:-

> start transaction;

> select dev_model from client

|dev_model|
|   1     |
|   2     |


client 2:
> start transaction
> update client set dev_model=4 where dev_model=1
> commit||

client 1:
> select dev_model from client
 
At isolation 1,2:-
|dev_model|
|  1      |
|  4      |
          
As we can see for client 1, reads are non-repeatable.

At isolation 3,4:-
|dev_model|
|  1      |
|  2      |

Thus at isolation level 3 and above reads are repeatable.


As read locks are acquired by client 1, the data does not change even when client 2 commits. Client 2 transaction needs to wait for client one to commit first thus making transaction 1, 2 as serialized. Thus at isolation level 3, the reads are repeatable.

* Isolation level 4 (serializable): At isolation level 3, . for example:-

Client 1:-
> start transaction;

> select dev_model from client where client_id > 5 and client_id < 10
| dev_model |
|   1       |
|   2       |

client 2:-

> start transaction;

> insert into client (client_id, dev_model) values (7, 10);

> commit

client 1:-

>  select dev_model from client where client_id > 5 and client_id < 10 ;

(Isolation level 1,2,3)
|dev_model|
|  1      |
|  2      |
|  10     |

( Isolation level 4)
|dev_model|
|   1     |
|   2     |

Thus transaction 1 take place as if transaction 2 hasn't occurred YET


Thus a phantom read can occur at isolation level 3, however at isolation level 4 i.e serializable the transactions are serialized and all the three cases, i.e. phantom read, non-repeatable reads and dirty read are prevented by acquiring locks for range, data and transaction.